Installation
Install Flink Manager from the Docker image or the release bundle, connect it to PostgreSQL and your Flink cluster, and go to production.
Three supported paths
- A. Docker Compose — recommended; the template below is production-ready.
- B. Docker image — plain
docker runequivalent of the compose template. - C. Release bundle — a zip with the application jar, start scripts and a systemd unit, for hosts without Docker.
All paths run the same application: the web console is served by the application itself at /flink-manager/, so there is nothing else to deploy.
Prerequisites
- A PostgreSQL database (14+). Create the database before first start — Flink Manager creates and migrates the schema automatically.
- A reachable Apache Flink 2.x cluster (JobManager REST API), and optionally a Flink SQL Gateway.
- Secrets to set: a strong
JWT_SECRET, anAUTH_SECRET_KEYand a database password.
A. Docker Compose
Create a .env file next to your docker-compose.yml:
# .env — the compose file refuses to start without these
DB_PASSWORD=<db-password>
JWT_SECRET=<random-base64-secret>
AUTH_SECRET_KEY=<random-32-bytes-base64># docker-compose.yml
services:
flink-manager:
image: vinteroslabs/flink-manager:latest
pull_policy: always
ports:
- "${SERVER_PORT:-8080}:${SERVER_PORT:-8080}"
environment:
FLINK_SERVER_URL: "${FLINK_SERVER_URL:-http://jobmanager:8081}"
FLINK_SQL_GATEWAY_URL: "${FLINK_SQL_GATEWAY_URL:-http://jobmanager:8083}"
FLINK_SAVEPOINT_DIR: "${FLINK_SAVEPOINT_DIR:-/tmp/flink-savepoints}"
DB_URL: "${DB_URL:-jdbc:postgresql://db:5432/flink-manager}"
DB_USERNAME: "${DB_USERNAME:-flinkmgr}"
DB_PASSWORD: "${DB_PASSWORD:?Set DB_PASSWORD in .env}"
JWT_SECRET: "${JWT_SECRET:?Set JWT_SECRET in .env}"
JWT_EXPIRATION_MS: "${JWT_EXPIRATION_MS:-43200000}"
AUTH_SECRET_KEY: "${AUTH_SECRET_KEY:?Set AUTH_SECRET_KEY in .env}"
AUTH_UI_BASE_URL: "${AUTH_UI_BASE_URL:-http://localhost:8080/flink-manager}"
CORS_ALLOWED_ORIGINS: "${CORS_ALLOWED_ORIGINS:-}"
SERVER_PORT: "${SERVER_PORT:-8080}"
SPRING_PROFILES_ACTIVE: "${SPRING_PROFILES_ACTIVE:-in-memory-db}"For production, set in .env:
SPRING_PROFILES_ACTIVE=default
DB_URL=jdbc:postgresql://db-prod:5432/flink-manager
DB_USERNAME=flinkmgrThen:
docker compose up -d
curl http://localhost:8080/actuator/healthimage: latest with pull_policy: always. To stay on a fixed version, replace latest with the release tag (e.g. 0.0.1) — see the changelog for released versions.Upgrades
docker compose pull && docker compose up -dThe database schema is migrated automatically on startup; no manual migration steps.
B. Docker image (plain docker run)
The image is published on Docker Hub as vinteroslabs/flink-manager, tagged per release (0.0.1) plus a rolling latest.
docker run -d --name flink-manager \
--restart unless-stopped \
-p 8080:8080 \
-e SPRING_PROFILES_ACTIVE=default \
-e DB_URL="jdbc:postgresql://<db-host>:5432/flink-manager" \
-e DB_USERNAME="flinkmgr" \
-e DB_PASSWORD="<db-password>" \
-e FLINK_SERVER_URL="http://<flink-jobmanager>:8081" \
-e FLINK_SQL_GATEWAY_URL="http://<flink-sqlgateway>:8083" \
-e JWT_SECRET="<random-base64-secret>" \
-e AUTH_SECRET_KEY="<random-32-bytes-base64>" \
vinteroslabs/flink-manager:0.0.1- The container listens on port 8080 (override with
SERVER_PORT). - Memory defaults are
-Xms512m -Xmx1gwith G1 GC; tune withJVM_OPTS. - All settings are environment variables — see Configuration for the full list.
Verify
curl http://localhost:8080/actuator/healthThen open http://<host>:8080/flink-manager/ and log in (see Getting Started → Log in).
Upgrades
Pull the new tag, stop and recreate the container with the same environment. Schema migrations run automatically on startup.
C. Release bundle
Each release publishes a zip on GitHub Releases:
flink-manager-<version>.zip
├── flink-manager-api-<version>-protected.jar
└── scripts/
├── flink-manager.sh # Linux/macOS launcher (foreground | start | stop)
├── flink-manager.bat # Windows launcher
└── flink-manager.service # systemd unit1. Prerequisites
- Java 22+ (JDK) on the host
- A PostgreSQL database as above
2. Install
sudo mkdir -p /opt/flink-manager
sudo unzip flink-manager-0.0.1.zip -d /opt/flink-manager
sudo useradd --system --home /opt/flink-manager flinkmgr
sudo chown -R flinkmgr:flinkmgr /opt/flink-manager3. Configure
Every setting can be provided as an environment variable (see Configuration). With systemd, override without editing the unit:
sudo systemctl edit flink-manager[Service]
Environment=SPRING_PROFILES_ACTIVE=default
Environment=DB_URL=jdbc:postgresql://db-prod:5432/flink-manager
Environment=DB_USERNAME=flinkmgr
Environment=DB_PASSWORD=<secret>
Environment=FLINK_SERVER_URL=http://flink-prod:8081
Environment=JWT_SECRET=<base64-secret>
Environment=AUTH_SECRET_KEY=<base64-secret>
# Secrets can also live in a root-only file referenced with EnvironmentFile=.4. Run with systemd
sudo install -m 644 /opt/flink-manager/scripts/flink-manager.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now flink-manager
journalctl -u flink-manager -fThe unit runs the jar as the unprivileged flinkmgr user and restarts it on failure.
5. Run without systemd
cd /opt/flink-manager
./scripts/flink-manager.sh start # background (writes flink-manager.pid, logs in logs/)
./scripts/flink-manager.sh stop # stop
./scripts/flink-manager.sh # foregroundOn Windows, run scripts\flink-manager.bat (foreground).
Calling the launcher from your own script
Every setting in flink-manager.sh can be overridden via the environment before invoking it. The recommended pattern is a small wrapper script that sets the parameters your deployment needs, then calls the launcher:
#!/usr/bin/env bash
# start.sh — configure Flink Manager, then start it.
# Set strong, private secrets before running start.sh.
JWT_SECRET=<random-base64-secret>
AUTH_SECRET_KEY=<random-32-bytes-base64>
# The release launcher defaults to localhost for Flink endpoints.
FLINK_SERVER_URL=http://localhost:8081
FLINK_SQL_GATEWAY_URL=http://localhost:8083
FLINK_SAVEPOINT_DIR=/tmp/flink-savepoints
JWT_EXPIRATION_MS=43200000
AUTH_UI_BASE_URL=http://localhost:8080/flink-manager
# CORS_ALLOWED_ORIGINS is intentionally not set: the console is served by the
# application itself, so no cross-origin permission is needed.
SERVER_PORT=8080
SPRING_PROFILES_ACTIVE=in-memory-db
exec /opt/flink-manager/scripts/flink-manager.sh "$@"- Secrets are the only mandatory overrides.
JWT_SECRETandAUTH_SECRET_KEYship with dev-only defaults and must be replaced; everything else falls back to a sensible default (see Configuration). - The example uses
in-memory-dbfor a quick test with no database. For production, use the default profile with PostgreSQL. - Keep secrets out of the wrapper if the script lives in version control: source them from a root-only file instead, or rely on the systemd
EnvironmentFile=mechanism. - Passing
"$@"through meansstart/stopstill work.
6. Verify
curl http://localhost:8080/actuator/health7. Upgrades
Install the new jar and the matching flink-manager.sh from the new bundle (the script is stamped with the version), remove the old jar, then restart the service. Schema migrations run automatically on startup.
Reverse proxy & TLS
Flink Manager can terminate TLS itself (set SSL_ENABLED=true and point SSL_KEYSTORE_PATH at a PKCS12/JKS keystore — see Configuration), or you can put it behind a reverse proxy that forwards / to the application port.
The console is served by the application itself, so when the proxy routes everything to the same origin the browser makes same-origin API calls and no CORS configuration is needed. Set CORS_ALLOWED_ORIGINS only if the console is reachable under a different origin than the API (e.g. the proxy serves the console on https://flink.example.com but forwards API calls to a different host).
License activation
After installation, activate your license as described in the License guide.