Docker Compose Setup
unqueue is AGPL-3.0 licensed. The self-hosted version is identical to the cloud version — no features are gated.
This guide covers the two-stack Docker Compose layout used in this repository: an infrastructure stack (Postgres, PgBouncer, Redis) and an app stack (API server + platform UI).
Prerequisites
Section titled “Prerequisites”- Docker 20.10+
- Docker Compose v2 (
docker compose, notdocker-compose) - Node.js 24+ and pnpm 11+ (only needed to run database migrations from your machine)
1. Clone the repository
Section titled “1. Clone the repository”2. Start infrastructure
Section titled “2. Start infrastructure”Copy .env.infra.example values into your compose environment (or a local .env file) and start Postgres, PgBouncer, and Redis:
| Service | Default host port | Notes |
|---|---|---|
| PgBouncer | 6432 | App connects here — not Postgres directly |
| Redis | 6379 | Password required (REDIS_PASSWORD) |
See .env.infra.example for the full variable list.
3. Configure the app
Section titled “3. Configure the app”Copy .env.example to .env and set at minimum:
Generate ENCRYPTION_KEYS:
For production builds, also set VITE_API_URL to the public API origin (e.g. https://api.your-domain.com). The platform image inlines this at build time.
See Configuration for the full reference.
4. Run database migrations
Section titled “4. Run database migrations”Migrations do not run automatically on container startup. From the repo root:
Ensure DATABASE_URL in your environment points at the running PgBouncer instance before migrating.
5. Start the app stack
Section titled “5. Start the app stack”Or with Doppler-managed secrets (if configured):
| Service | Default host port | Notes |
|---|---|---|
| Platform (UI) | 5174 | nginx serving the built React app |
| API server | 3001 | Hono + oRPC + Socket.IO |
Open http://localhost:5174, create an account, then connect your BullMQ Redis.
Updating
Section titled “Updating”Pull the latest changes, rebuild, and re-run migrations if the schema changed:
Production deployment
Section titled “Production deployment”For production, deploy the infra and app stacks separately (e.g. two Dokploy compose projects on the same network):
- Infra stack:
docker-compose.infra.yml— set variables from.env.infra.example - App stack:
docker-compose.yml— set variables from.env.exampleor Doppler
When both stacks share a Docker network, use in-network hostnames:
Set COOKIE_DOMAIN to your parent domain (e.g. .your-domain.com) so auth cookies work across platform and API subdomains.
Reverse proxy
Section titled “Reverse proxy”The platform and API run on separate origins in production. Example Nginx config:
Caddy handles TLS automatically if you prefer:
Troubleshooting
Section titled “Troubleshooting”The platform can’t reach the API server
Make sure VITE_API_URL was set to the public API URL when the platform image was built, and that BETTER_AUTH_URL points to the same API origin — not localhost.
Jobs aren’t updating in real time
Check that your reverse proxy forwards WebSocket upgrades (Upgrade and Connection headers). Live updates use Socket.IO.
Database migrations failed
Verify DATABASE_URL points at PgBouncer and Postgres is healthy, then run migrations from the repo root:
Auth cookies don’t persist across subdomains
Set COOKIE_DOMAIN to the parent domain with a leading dot (e.g. .your-domain.com).