dpndncY

Deploying with Docker

Two ways to run the image: Docker Compose (recommended, includes HTTPS) or a plain docker run. Read Deploying dpndncY first if you have not.

#Docker Compose with HTTPS

The repository's docker-compose.yml runs the platform plus Caddy, which obtains and renews certificates automatically.

#What you need

  • Docker Engine with the Compose v2 plugin (docker compose version works).
  • Two DNS names pointing at the machine, for example dpndncy.example.com (console) and api.dpndncy.example.com (API).
  • Ports 80 and 443 reachable from the internet, so Let's Encrypt can validate the names. On a private network, see "Internal certificates" below.

#Steps

# 1. Get the deployment files (or use the dpndncy-deploy.tar.gz you were given)
mkdir dpndncy && cd dpndncy
curl -fsSL https://dpndncy.com/downloads/dpndncy-deploy.tar.gz | tar xz

# 2. Configure
cp .env.example .env
$EDITOR .env        # DOMAIN, API_DOMAIN, ACME_EMAIL, APP_SECRET, SUPERADMIN_EMAIL, SUPERADMIN_PASSWORD

# 3. Start
docker compose up -d
docker compose logs -f dpndncY        # wait for "dpndncY SCA Engine running"

Generate APP_SECRET with openssl rand -hex 32. Open https://<DOMAIN> and sign in with SUPERADMIN_EMAIL. Then follow "Setting up a new workplace" in Deploying dpndncY.

Compose reads .env for itself and passes it to the container. The environment section of the compose file derives CORS_ORIGIN, APP_URL, NEXT_PUBLIC_APP_ORIGIN and PUBLIC_API_URL from DOMAIN and API_DOMAIN, so you do not set those.

#Internal certificates

With no public DNS (for example dpndncy.corp.local), use Caddy's own certificate authority. In .env set:

CADDYFILE=./Caddyfile.internal

Browsers and CI runners must trust that authority once. Its root certificate is in the caddy-data volume at /data/caddy/pki/authorities/local/root.crt:

docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt ./dpndncy-root.crt

To use a certificate from your own CA instead, mount it into the caddy service and add tls /certs/tls.crt /certs/tls.key to both site blocks of the Caddyfile.

#Another reverse proxy

Any proxy works if it sends the console hostname to dpndncY:3000 and the API hostname to dpndncY:3001, keeps X-Forwarded-For and X-Forwarded-Proto, and allows long requests (scans and uploads run for minutes; use read and send timeouts of 600 seconds and a body limit of at least MAX_ZIP_UPLOAD_MB, default 200 MB). Keep TRUST_PROXY=true. deploy/nginx/dpndncy.conf is an nginx example.

#Updating

docker compose pull
docker compose up -d

Pin DPNDNCY_IMAGE to a version (for example ghcr.io/dpndncy-sca/platform:2.9.0) so an update happens when you choose. Take a backup first (Running dpndncY); a new version can migrate the database. docker compose --profile auto-update up -d adds Watchtower, which updates unattended. Most production installs do not want that.

#Everything that lives where

Thing Where
Database, secrets, licences, caches volume dpndncy-data, mounted at /app/data
Certificates volumes caddy-data, caddy-config
Logs docker compose logs, JSON lines, rotated at 10 MB x 5 files

#Plain docker run (evaluation)

For a quick look on one machine, without HTTPS. Pick a hostname or address you will browse to; the three origin variables must match it exactly:

docker run -d --name dpndncy --restart unless-stopped \
  -p 8080:3000 -p 8081:3001 \
  -v dpndncy-data:/app/data \
  -e APP_SECRET=$(openssl rand -hex 32) \
  -e ENABLE_BOOTSTRAP_SUPERADMIN=true \
  -e [email protected] \
  -e SUPERADMIN_PASSWORD='choose-a-long-password' \
  -e CORS_ORIGIN=http://localhost:8080 \
  -e NEXT_PUBLIC_APP_ORIGIN=http://localhost:8080 \
  -e APP_URL=http://localhost:8080 \
  -e PUBLIC_API_URL=http://localhost:8081 \
  -e COOKIE_SECURE=false \
  ghcr.io/dpndncy-sca/platform:stable

Console at http://localhost:8080, API at http://localhost:8081.

  • The volume must be mounted at /app/data. Anywhere else, and the database is lost when the container is removed.
  • COOKIE_SECURE=false is needed only because this runs over plain HTTP. With HTTPS leave it at its default, true.
  • Without CORS_ORIGIN the backend exits at start-up in production mode.

#Troubleshooting

Symptom Cause and fix
Container restarts at once, log says CORS_ORIGIN missing in production Set CORS_ORIGIN (Compose does this from DOMAIN)
Container restarts, log says APP_SECRET env var missing in production Set APP_SECRET
Sign-in page loads but sign-in says the request could not be verified The address in the browser does not match CORS_ORIGIN / NEXT_PUBLIC_APP_ORIGIN. Use the same scheme, host and port
Sign-in works but you are signed out on the next click COOKIE_SECURE=true over plain HTTP. Use HTTPS or set it to false for evaluation
Certificates are not issued DNS for both names does not point here yet, or ports 80/443 are blocked. docker compose logs caddy
CLI or pipeline gets 404 from the console address Use the API address, not the console. See Scanning from CI/CD pipelines
Everyone is signed out after a restart Expected. Browser sessions end whenever the server restarts. API tokens keep working. If they stop working too, the signing key was rotated with the emergency option, or the data volume was replaced