Deploy
Run au1h in production with Docker images, on any host.
au1h is three stateless containers plus Postgres and Redis:
| Service | Image | Port | Public host (example) |
|---|---|---|---|
| server | ghcr.io/ad12-codes/au1h-server | 4444 | api.example.com |
| web | ghcr.io/ad12-codes/au1h-web | 80 | app.example.com |
| docs | ghcr.io/ad12-codes/au1h-docs | 80 | docs.example.com (optional) |
Images are built by .github/workflows/build-images.yml on every push to main and
tagged latest and sha-<commit>. Each app also has a Dockerfile if you prefer to
build your own.
Variables
The server reads these (full list in the configuration reference):
| Variable | Value |
|---|---|
DATABASE_URL | postgresql://user:pass@host:5432/au1h |
REDIS_URL | redis://host:6379 |
BETTER_AUTH_SECRET | openssl rand -base64 48. Changing it later signs everyone out and re-keys JWTs |
BETTER_AUTH_URL | https://api.example.com |
CORS_ORIGIN | https://app.example.com |
AU1H_ADMIN_EMAILS | Your email, so you can register additional admins later |
AU1H_TRUST_PROXY | true when a reverse proxy sets x-forwarded-for |
NODE_ENV | production |
EMAIL_PROVIDER | smtp or resend plus its credentials, see Email |
The admin portal needs one: AU1H_SERVER_URL=https://api.example.com, read when the
container starts. The docs image needs nothing.
docker compose
Bundled Postgres and Redis, prebuilt images:
git clone https://github.com/AD12-codes/au1h && cd au1h
cp deploy/.env.example .env # edit
docker compose -f deploy/docker-compose.ghcr.yml up -ddocker-compose.yml at the repository root is the same stack built from source. Put a
reverse proxy (Caddy, Traefik, nginx) in front, terminating TLS and forwarding each host
to its service. Set AU1H_IMAGE_TAG to a sha-<commit> tag to pin a release.
Any container platform
On a platform that runs Docker images (Coolify, Dokploy, Railway, Fly, Render, Kubernetes), create three services from the images above, attach a Postgres and a Redis, and set the variables. The server applies migrations on start, so there is no separate migration step. Only the server needs the database; the portal and docs are static files behind nginx.
The GHCR packages are public. If you publish your own, either make them public or give
your platform a registry credential with read:packages.
First run
Open https://app.example.com/register. The first account becomes an admin; after that,
sign-up requires AU1H_ADMIN_EMAILS or a workspace invitation. Then register your first
application and copy its slug.
Updating
Pull the new image and restart. Migrations run on start and are additive. Back up Postgres before major upgrades.
Scaling and backups
One server container is plenty for most deployments. Several can run behind the same Postgres and Redis; caches and rate limits are shared through Redis. Postgres holds all state, so back it up; Redis can be rebuilt (sessions are re-read from Postgres).