Docker
VectorStep and the Gateway publish multi-arch (linux/amd64 + linux/arm64)
images to GHCR on every tagged release, plus an edge tag tracking the
default branch. See Versions and releases
for what each tag means and the VectorStep/Gateway compatibility rule:
docker pull ghcr.io/bantex01/vectorstep:latestdocker pull ghcr.io/bantex01/vectorstep-gateway:latestEvery published image is signed and has an SBOM attached to its GitHub
release — see Verifying a release
for the cosign verify command. Pin production deployments to a released
semver tag (e.g. :0.1.0) rather than :latest or :edge — see Versions
and releases.
This page covers pulling and running the images directly — docker run or
your own docker compose file. If you just want VectorStep running with no
manual wiring, use the installer
instead; it manages the compose file, config, and volumes below for you.
Config and secrets
Section titled “Config and secrets”Images contain code and committed samples only — config is never baked in.
Mount a config file and point CONFIG_PATH (VectorStep) /
VECTORSTEP_GATEWAY_CONFIG (Gateway) at it; secrets arrive as environment
variables consumed by the config’s ${VAR} substitution. Everything writable
lives under a single /data volume, so the container variant of
config.yaml looks like this:
database: {url: "sqlite+aiosqlite:////data/db/runs.db"} # four slashes = absolute pathpipeline_config_dir: /data/pipelines # or a ConfigMap mount — see Kubernetesstep_library_dir: /data/stepsartifacts: {dir: /data/artifacts}logging: {dir: /data/logs}auth: tokens: - name: admin token: ${VECTORSTEP_ADMIN_TOKEN} role: admin - name: webhook token: ${VECTORSTEP_WEBHOOK_TOKEN} role: webhookauth.tokens isn’t optional — VectorStep refuses to start without it (or
auth.allow_unauthenticated: true, only for a trusted local machine): pipeline
write access is equivalent to shell access on the host it’s running on. See
Securing a deployment for what
each role can do.
Running it
Section titled “Running it”export VECTORSTEP_ADMIN_TOKEN=$(openssl rand -hex 24)export VECTORSTEP_WEBHOOK_TOKEN=$(openssl rand -hex 24)echo "Admin token (save this — it's what you log into the UI with): $VECTORSTEP_ADMIN_TOKEN"
docker run -d \ -p 8000:8000 \ -e VECTORSTEP_ADMIN_TOKEN \ -e VECTORSTEP_WEBHOOK_TOKEN \ -v ./config.yaml:/etc/vectorstep/config.yaml:ro \ -v vectorstep-data:/data \ ghcr.io/bantex01/vectorstep:latestThe Gateway’s container config additionally needs identity.path and
agents_dir pointed at /data — its default, /data/identity, already
assumes that layout; only override it if you’re mounting something other
than a single /data volume. See Configuration
for the full field reference.
Evaluating the pair locally (docker compose)
Section titled “Evaluating the pair locally (docker compose)”The installer manages a
docker-compose.yaml for you — fetched from the public
VectorStep-Dist repo into
~/.vectorstep/, refreshed on every re-run — bringing up both services from
the published images with docker compose up, no build: step and no
source checkout involved. It’s an evaluation/dev path, not a production
one — for a real deployment, see Kubernetes.
If you’d rather write your own compose file instead of using the installer’s,
VectorStep-Dist/docker-compose.yaml is worth reading first — it has the
config-mounting and named-volume conventions this page describes already
wired up correctly.
Network defaults (docker compose)
Section titled “Network defaults (docker compose)”The installer’s compose stack binds loopback by default:
ports: ["${VECTORSTEP_BIND:-127.0.0.1}:${VECTORSTEP_PORT:-8000}:8000"]So a fresh install never exposes an unauthenticated-by-default service to
the rest of the local network. Set VECTORSTEP_BIND=0.0.0.0 in
~/.vectorstep/.env only when this host needs to serve other machines, and
only once you’ve put TLS in front of it — either server.tls in
config/vectorstep.yaml (see Deployment → TLS)
or a terminating reverse proxy.
The Gateway publishes no host port at all — VectorStep reaches it on the
compose network at ws://gateway:18780, which is all the default stack
needs. If you’re pointing a Gateway MCP client, or anything else running on
the host rather than in a container, at localhost:18780, add a persistent
mapping to docker-compose.yaml’s gateway service:
gateway: ports: ["127.0.0.1:18780:18780"]then docker compose up -d to apply it — docker compose port only prints
a binding that already exists, so with no ports: entry there’s nothing for
it to report.
Keep it off a non-loopback interface unless it’s behind TLS and a firewall — the Gateway’s admin token can rewrite agent definitions.
Where next
Section titled “Where next”- Kubernetes — the production path once evaluation is done.
- Deployment — the full
config.yamlreference and database/migration mechanics, regardless of how you’re running the images.