Docker
This repository includes a ready-to-use Dockerfile and docker-compose.yml for containerized development and production builds.
Quick start (recommended)
Use the provided npm scripts:
npm run docker:build
npm run docker:upUseful helpers:
npm run docker:logs— tail app logsnpm run docker:shell— open a shell in the app containernpm run docker:test— run tests inside the containernpm run docker:prune— reclaim disk space (removes unused images/cache/volumes)npm run docker:down/npm run docker:stop
Container Workers CLI (cw)
ZinTrust includes a unified CLI flow for the worker container stack.
Workers stack
zin init:cw
zin deploy cw
zin deploy:cwPublish workers/schedules images (maintainers / Docker Hub access required):
zin docker push --tag <version>Use the prebuilt images in Compose (skip local builds):
ZINTRUST_IMAGE=zintrust/zintrust:<version> docker compose -f docker-compose.workers.yml up -d
ZINTRUST_IMAGE=zintrust/zintrust:<version> docker compose -f docker-compose.schedules.yml up -dCompatibility aliases still work:
zin init:cwr
zin deploy cwr
zin deploy:cwrContainer Proxies CLI (cp)
ZinTrust includes a unified CLI flow for the proxy gateway + proxy services stack.
Initialize proxy stack files
zin init:proxyAliases:
zin init:cp
zin init:container-proxies
zin init:pyDeploy / up / down
zin deploy cp
zin deploy:cp
zin cp build
zin cp up -d
zin cp downPublish proxy images (maintainers / Docker Hub access required):
zin docker push --tag <version>Compose target file: docker-compose.proxy.yml.
Prebuilt images (Docker Hub)
If you prefer not to build proxy images locally, use the prebuilt Docker Hub images:
- See
docs/docker-hub-proxies.md
Cloudflare Containers Proxy Worker (ccp)
This is the Cloudflare-hosted equivalent of the proxy gateway pattern, implemented as a Worker plus container-backed Durable Objects.
Scaffold the dedicated Wrangler config + Worker entry:
zin init:containers-proxy
# short alias
zin init:ccpInstall the runtime package:
npm i @zintrust/cloudflare-containers-proxyRun locally (Wrangler dev + Docker-backed Containers):
zin docker -c wrangler.containers-proxy.jsonc -e staging
# short alias
zin dk -e stagingTip: Wrangler creates many cloudflare-dev/* image tags during local dev. To clean up unused old tags before starting the dev server:
npm run dev:cp:cleanThe gateway routes by path prefix (mirrors the Compose gateway paths):
MYSQL_PROXY_URL=http://127.0.0.1:8787/mysql
POSTGRES_PROXY_URL=http://127.0.0.1:8787/postgres
REDIS_PROXY_URL=http://127.0.0.1:8787/redis
MONGODB_PROXY_URL=http://127.0.0.1:8787/mongodb
SQLSERVER_PROXY_URL=http://127.0.0.1:8787/sqlserver
SMTP_PROXY_URL=http://127.0.0.1:8787/smtpIf you override the dev server port, update the URLs accordingly (or pass --port to zin docker).
Deploy:
zin deploy:ccp -e production
# short alias
zin d:ccpProxy gateway endpoint conventions
When using the unified gateway (default port 8800), point proxy URLs to gateway paths:
MYSQL_PROXY_URL=http://127.0.0.1:8800/mysql
POSTGRES_PROXY_URL=http://127.0.0.1:8800/postgres
REDIS_PROXY_URL=http://127.0.0.1:8800/redis
MONGODB_PROXY_URL=http://127.0.0.1:8800/mongodb
SQLSERVER_PROXY_URL=http://127.0.0.1:8800/sqlserver
SMTP_PROXY_URL=http://127.0.0.1:8800/smtpDirect per-service URLs (for example http://127.0.0.1:8789) still work, but they bypass the gateway.
Proxy stack env fallbacks (workers-compatible)
docker-compose.proxy.yml now follows worker-style host env fallbacks:
- DB host fallback:
DOCKER_DB_HOST→host.docker.internal - Redis host fallback:
DOCKER_REDIS_HOST→host.docker.internal
This avoids empty override variables falling back to 127.0.0.1 inside containers.
Health checks, cost, and disable switches
Docker health checks have a small runtime overhead (local CPU/network in Docker host). On most local/dev setups this is negligible, but on metered hosted Docker platforms frequent checks can contribute small additional cost.
You can disable proxy health checks via environment variables:
PROXY_HEALTHCHECK_DISABLE=true
PROXY_GATEWAY_HEALTHCHECK_DISABLE=truePROXY_HEALTHCHECK_DISABLEdisables health checks for proxy services.PROXY_GATEWAY_HEALTHCHECK_DISABLEdisables health checks for the nginx gateway.
Keep them enabled in production unless your platform constraints require disabling them.
What the Dockerfile does
The root Dockerfile is multi-stage:
- builder (
node:20-alpine)
- installs build tooling (
python3,make,g++) for native modules likebcrypt - runs
npm ci - runs
npm run build:dkto producedist/
- runtime (
node:20-alpine)
- installs only production dependencies (
npm ci --omit=dev) - copies
dist/from the builder stage - runs as a non-root user
- starts the compiled server via
node dist/src/boot/bootstrap.js
Production build target
To build the runtime stage explicitly:
npm run docker:build:prodThis corresponds to docker build --target runtime ....
Docker Compose (local dev)
The included docker-compose.yml is optimized for local development:
- mounts the repo into the container (
.:/app) for live iteration - runs
npm run devin the app container - starts PostgreSQL by default
- includes Redis under the
optionalprofile
Start dev services:
docker-compose up -dStart dev services including Redis:
docker-compose --profile optional up -dEnvironment variables
Compose passes common settings (examples):
NODE_ENV,HOST,PORTDB_CONNECTION,DB_HOST,DB_PORT,DB_DATABASE,DB_USERNAME,DB_PASSWORD
You can override these via your shell environment or a .env file that Docker Compose reads.
Ports and health checks
The Docker setup uses two different conventions:
- Compose maps
3000:3000by default and setsPORT=3000. - Health checks in both
Dockerfileanddocker-compose.ymlcallhttp://localhost:7777/health.
ZinTrust projects default to port 7777 unless configured otherwise. If your container is configured to listen on 3000, update the health check URL accordingly (or set your server port to 7777 and map ports as you prefer).
Persistent data
Compose uses named volumes for infrastructure:
postgres_datafor Postgresredis_datafor Redis
Application storage/logs are repo-mounted in dev mode; for production you typically mount only what you need (logs, uploads, backups) and keep your container filesystem immutable.