Docker Compose Deployment
authlance/deployment docker-compose is a working reference environment that boots MySQL, Ory Kratos, Ory Hydra, the Auth Container, the License Operator, NATS, and an nginx edge proxy. The Loop/Scaffold dashboard remains on the host machine and talks to the containers through the same credentials rendered into .env.
Stack Contents
- MySQL (
mysqlservice) with initialization scripts undermysql-init/. - Ory Kratos + courier (
kratos,kratos-migrate,kratos-courier) and Ory Hydra (hydra,hydra-migrate) that use configs rendered fromtemplates/ory. - Auth Container (
authlance) and License Operator (licenseoperator) which mount config files produced fromtemplates/app/authandtemplates/app/license. - NATS (
nats) exposed onlocalhost:4222for events plus an admin endpoint onlocalhost:8222. - nginx (
nginx) terminating TLS on${NGINX_HTTPS_PORT:-8443}and proxying the dashboard routes (/and/authlance/loop) tohost.docker.internal:3000while forwarding/authlanceand/authlance/licenseto the backend containers.
Kratos and Hydra only expose cluster-internal ports. The host touches them through the Auth Container or License Operator.
Prerequisites
- Docker Desktop (Compose v2) on macOS or Linux.
- A
.envfile indeployment/docker-compose(generated from.env.template). - A license file placed at
deployment/docker-compose/licenses/authlance.lic(or updateAUTH_LICENSE_FILE). - TLS material under
deployment/docker-compose/nginx/certsif you do not want to rely on self-signed certs.
Bootstrapping the Stack
All commands run from deployment/docker-compose.
cp .env.template .env # first-time setup
./start.sh
start.sh copies .env.template into .env when missing, pulls the referenced images, and launches the services in the correct order. The script prints health URLs for Kratos, Hydra, and MySQL once everything is on its way up.
Bring the Loop/Scaffold dashboard up on your host machine using the same connection info that Compose exports (see Development Environment for the full workflow). nginx/nginx.conf proxies https://localhost:${NGINX_HTTPS_PORT:-8443} to that host process, so the containerized services automatically receive the right cookies and callback URLs.
Template Rendering and Shared Configs
The ory-templates one-shot service uses envsubst to turn every file in templates/ory and templates/app/** into named Docker volumes:
ory_kratos_config→/etc/kratos(includeskratos.yml, the identity schema, and Jsonnet mail templates).ory_hydra_config→/etc/hydra.app_auth_config→/app/configinside the Auth Container (config.yaml+authlance.lic).app_license_config→/app/configinside the License Operator (config.yaml+trialLicense).
Edit .env to any credentials or anything else referenced by the templates. Re-render after every change:
docker compose run --rm ory-templates
docker compose up -d authlance licenseoperator
Stopping the consuming services before re-rendering is recommended so that they remount the updated volumes:
docker compose stop authlance licenseoperator
docker compose run --rm ory-templates
docker compose up -d authlance licenseoperator
Customize the App Config Templates
The templates under deployment/docker-compose/templates/app/** ship with safe placeholders only. Before you render production-ready configs:
- License Operator (
templates/app/license/config.yaml.template) – Replace theexample-subscriptionandexample-one-offproducts (plus the matchingsecurityentries) with your own product keys, Stripe product/price IDs, and copy any commented examples if you need tiered or bundled SKUs. The checked-in template deliberately avoids real Authlance values. - Auth Container (
templates/app/auth/config.yaml.template) – ThepaymentTierblock is commented because it is optional. Uncomment it only if you enforce per-group member caps, and provide your values directly in the file (no.envvariables are rendered for those keys).
Call out these tweaks in your team docs so everyone knows to customize the templates whenever they clone the repo.
Reusing Rendered Files for Kubernetes Secrets
Each Helm chart consumes a secret referenced through duna.configSecret. Rather than rebuilding configuration by hand, you can export the rendered volumes produced by Compose and create Kubernetes secrets from them:
# 1. Render the latest configs
docker compose run --rm ory-templates
# 2. Copy the files out of the volumes (COMPOSE_PROJECT_NAME defaults to duna)
docker run --rm -v duna_app_auth_config:/src alpine cat /src/config.yaml > auth-config.yaml
docker run --rm -v duna_app_license_config:/src alpine cat /src/config.yaml > license-config.yaml
# 3. Turn them into secrets that match the value files used by Helm
kubectl create secret generic auth-config --from-file=config.yaml=auth-config.yaml
kubectl create secret generic license-config --from-file=config.yaml=license-config.yaml
Use the same technique for ory_kratos_config or ory_hydra_config when you need to hydrate ConfigMaps or Secrets that feed your Ory workloads. Because .env drives every template, you can keep one authoritative set of credentials, render them with Compose, and reuse the outputs elsewhere.
Loop/Scaffold Configuration
Compose does not render templates/app/loop-scaffold/config.json.template automatically. When you extend the dashboard locally (or build a dashboard image), generate loop-scaffold/app-config.json from the same .env file:
cd deployment/docker-compose
set -a && source .env && set +a
envsubst < templates/app/loop-scaffold/config.json.template > ../../loop-scaffold/app-config.json
That file is the exact artifact mounted by the dashboard Helm chart. Keeping it in sync with .env means the host dashboard talks to the same MySQL schema, NATS server, and Stripe/Postmark credentials as the containers.
TLS and Routing Notes
- Drop
server.crtandserver.keyintonginx/certs/to terminate HTTPS. Self-signed certs ormkcertoutputs work well for local development. nginxredirects plain HTTP (port${NGINX_LOCAL_PORT:-8080}) to HTTPS (${NGINX_HTTPS_PORT:-8443}) by default; editnginx/nginx.confif you want different behavior.- Requests for
/authlancego straight to the Auth Container,/authlance/licensehits the License Operator, and/authlance/loopplus/proxy the dashboard on the host. Update this map if you place a different host port or run multiple dashboards.
Lifecycle Commands
docker compose downtears everything down but keeps databases and rendered configs. Add-vif you want to remove the named volumes as well.docker compose logs -f authlance licenseoperatortails the backend logs../start.shis safe to rerun whenever you refresh.env; it re-pulls images and brings the services back up.- Health endpoints are exposed at:
- Kratos admin:
http://localhost:${KRATOS_ADMIN_PORT:-4434}/health/ready - Hydra admin:
http://localhost:${HYDRA_ADMIN_PORT:-4445}/health/ready - MySQL:
127.0.0.1:${MYSQL_LOCAL_PORT:-3307}
- Kratos admin:
Once you are comfortable with the Compose stack, move on to Helm deployments for production or GitOps-driven setups.