Docker Deployment
The workflow engine is distributed as a Docker image and can be deployed standalone or as part of the full neops stack.
Docker Image
The image also carries the Monitor App sources together with a generated engine API client (built in the Dockerfile’s client-gen stage), so the app can be served directly from the image — neops-lab runs it this way with npm install && npm run dev inside /app/rest/monitor-app.
Tags follow the branch/release naming:
| Tag | Source |
|---|---|
latest |
Latest stable release |
develop |
Latest development build |
main |
Latest main branch build |
x.y.z |
Specific release version |
Docker Compose
The repository includes a ready-to-use docker-compose.yml that starts the development dependency stack (PostgreSQL + Monitor App):
make gen-fetch-client # the Monitor App image builds from the generated API client
docker compose up -d
Run the engine locally with npm run start:dev (see Setup). The base compose file only starts supporting services — the engine is not included.
| Service | URL | Purpose |
|---|---|---|
| PostgreSQL | localhost:5434 |
Database (mapped from container port 5432) |
| Monitor App | http://localhost:5173 | Web UI for workflow management |
Configuration
All settings can be overridden via environment variables or a .env file:
| Variable | Default | Description |
|---|---|---|
POSTGRES_PASSWORD |
unsafe |
Database password |
POSTGRES_PORT |
5434 |
Host port for PostgreSQL |
MONITOR_PORT |
5173 |
Host port for the Monitor App |
CMS dependency
Workflows that use acquire clauses or operate on specific entities (devices, interfaces,
groups) require a running CMS. Set NEOPS_CMS_URL to point to an existing instance — as a
host environment variable when running the engine locally via npm, or as a service
environment variable when you run the engine as a container of your own.
Building the Image
The Makefile helper builds either flavor with the right build args:
make build-docker # enterprise -> neops-workflow-engine:latest
make build-docker flavor=preview # developer-preview -> neops-workflow-engine-preview:latest
NPM_TOKEN is expected to already be exported in your environment; the target aborts with a clear
message if it is not. It runs the run-ci stage first, then builds the image itself.
To build by hand instead:
export NPM_TOKEN=ghp_xxx
DOCKER_BUILDKIT=1 docker build \
--secret id=npm_token,env=NPM_TOKEN \
--build-arg LICENSE_FLAVOR=enterprise \
--build-arg NEOPS_VERSION=1.4.0 \
-t quay.io/zebbra/neops-workflow-engine:latest .
The build uses BuildKit secrets so the npm token is never written to image layers.
Build-time variables
These are properties of the image, fixed when it is built. They are not runtime settings – see Configuration for the variables you set when deploying.
| Build arg | Required | Purpose |
|---|---|---|
LICENSE_FLAVOR |
Yes | enterprise or developer-preview. Selects the license compiled into the image |
NEOPS_VERSION |
No (develop) |
Version string the image reports at GET /version/ |
LICENSE_FLAVOR has no default
Omitting it fails the build. This is deliberate: defaulting would risk shipping the enterprise flavor unintentionally.
The chosen flavor is both compiled in and stamped into the image’s NEOPS_LICENSE_FLAVOR
environment variable. On startup the engine compares the two and refuses to boot if they
disagree, treating the image as corrupt. Do not override NEOPS_LICENSE_FLAVOR when running a
container – it is an integrity check, not a switch.
Running from source
When you run the engine from source rather than from an image (npm run start:dev), there
is no compiled flavor. NEOPS_LICENSE=developer-preview selects that flavor for local
development and tests; anything else yields enterprise. This variable has no effect on a
built image.
Running Migrations
The engine runs pending migrations automatically on startup.
Networking
The engine needs to reach:
- PostgreSQL – for state persistence
- CMS – for entity data and locking (GraphQL over HTTP)
Workers need to reach the engine’s REST API (port 3030) for:
- Worker registration and heartbeat
- Function block registration
- Job polling and result pushing
The Monitor App runs client-side in the browser and connects to the engine API directly (default: http://localhost:3030, configurable in the Monitor App’s Settings page).
Health Check
The engine exposes a health endpoint:
For custom deployments that run the engine as a compose service, configure a health check like this:
services:
engine:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3030/health/"]
interval: 15s
timeout: 5s
retries: 5
start_period: 30s
See also: Configuration Reference for all environment variables, Setup for local development.

