Docker Compose
Deploy deco Studio locally using Docker Compose for testing and development
This guide covers running deco Studio with Docker Compose for testing and self-hosted evaluation.
Source (compose files): decocms/studio → deploy/docker-compose
Overview
Studio uses PostgreSQL as its database. The repo ships three compose files under deploy/docker-compose/ — pick by use case:
docker-compose.postgres.yml— self-host, all-in-one: Studio (published image) plus a fully bundled stack (PostgreSQL + NATS + MinIO), all wired so the app provisions nothing itself. The recommended starting point. (selfhost/examples/docker-composewraps this with a documented.env.example.)docker-compose.yml— self-host, bring-your-own DB: Studio only (published image), expecting a PostgreSQL you provide.docker-compose.dev.yml— development: only the dependencies (PostgreSQL + a 3-node NATS cluster, prod-like topology); you run the API and web apps from source withbun run dev:servers. No sandbox here — that needs Kubernetes (see the dev-hybrid loop).
The self-host files use a Docker volume for persistence and an automatic /health check.
Prerequisites
- Docker 20.10+
- Docker Compose 2.0+
- A PostgreSQL database — bundled (via
docker-compose.postgres.yml) or your own
Quick Start (bundled PostgreSQL)
# 1. Clone the repo and enter the compose directory
git clone https://github.com/decocms/studio.git
cd studio/deploy/docker-compose
# 2. Create a .env with an auth secret and Postgres credentials
cat > .env << EOF
BETTER_AUTH_SECRET=$(openssl rand -base64 32)
POSTGRES_USER=studio_user
POSTGRES_PASSWORD=$(openssl rand -base64 24)
POSTGRES_DB=studio_db
EOF
# 3. Start Studio + PostgreSQL
docker compose -f docker-compose.postgres.yml up -d
# 4. Access
open http://localhost:3000
The docker-compose.postgres.yml file wires DATABASE_URL automatically from the POSTGRES_* variables, using the postgres service as the host.
BETTER_AUTH_SECRET falls back to an insecure dev-only default if unset — always set a real one. The POSTGRES_* variables also have defaults, but always set a real password.
Environment variables
Set these in .env alongside the compose file:
| Variable | Default | Description |
|---|---|---|
BETTER_AUTH_SECRET | local-dev-better-auth-secret-change-me (insecure) | Authentication secret — always set a real one. Generate with openssl rand -base64 32 |
IMAGE_REPOSITORY | ghcr.io/decocms/studio/studio | Image repository |
IMAGE_TAG | latest | Image tag |
PORT | 3000 | Port exposed on the host |
BASE_URL / BETTER_AUTH_URL | http://localhost:3000 | Public URLs for the app |
DATABASE_URL | see below | PostgreSQL connection string |
POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB | studio / studio / studio | Credentials for the bundled Postgres (postgres compose file only) |
The container runs as user 1001:1001 and persists data to the studio-data volume; the bundled Postgres persists to postgres-data .
Using your own PostgreSQL
To point Studio at an external database, use the base docker-compose.yml and set DATABASE_URL :
# .env
BETTER_AUTH_SECRET=your_generated_secret_here
DATABASE_URL=postgresql://user:password@host:5432/database_name
docker compose up -d
localhost inside the container refers to the container itself. To reach PostgreSQL running on your machine, use host.docker.internal (Docker Desktop) or your machine’s LAN IP. With the bundled docker-compose.postgres.yml , the host is the service name postgres .
Authentication options
By default the bundled stack uses email/password auth. To enable social login, uncomment and set the provider variables in the compose environment block (or your .env ):
AUTH_GOOGLE_CLIENT_ID=...
AUTH_GOOGLE_CLIENT_SECRET=...
AUTH_GITHUB_CLIENT_ID=...
AUTH_GITHUB_CLIENT_SECRET=...
For richer configuration (deployment-wide SSO, email providers, magic links), set the corresponding AUTH_* variables in the compose environment block — there’s no config file to mount. See Authentication for the full reference.
Operations
Logs and status
# Follow logs for the app
docker compose logs -f studio
# Container status
docker compose ps
# Resource usage (container name is "decocms")
docker stats decocms
Update the image
docker compose pull
docker compose up -d
Pin a version by setting IMAGE_TAG in .env before pulling.
Backup and restore (PostgreSQL)
# Backup (bundled Postgres service)
docker compose exec postgres pg_dump -U studio_user studio_db > backup-$(date +%Y%m%d).sql
# Restore
docker compose exec -T postgres psql -U studio_user studio_db < backup-20240101.sql
Reset all data
docker compose down -v # removes named volumes (studio-data, postgres-data)
docker compose -f docker-compose.postgres.yml up -d
docker compose down -v permanently deletes the volumes. Back up first if the data matters. Plain docker compose down (without -v ) keeps your volumes.
Security
- Always generate a strong
BETTER_AUTH_SECRET(openssl rand -base64 32) and a realPOSTGRES_PASSWORD. - Don’t commit
.env(echo ".env" >> .gitignore;chmod 600 .env). - Don’t commit secrets (client secrets, API keys) into
.envor the compose file.
Found an error or want to improve this page?
Edit this page