Skip to content

Deploy on Coolify

View markdown

The repository ships docker-compose.coolify.yml for Coolify's Docker Compose resource type. It contains the app and PostgreSQL 16, with data in named volumes so redeploys never touch it.

  1. In Coolify: New Resource → Docker Compose, pick the repository https://github.com/kdigivn/kdigi-cms-open (or your fork), and set Docker Compose Location to /docker-compose.coolify.yml.
  2. Add the environment variable PAYLOAD_SECRET with a random string of at least 32 characters (openssl rand -hex 32). It is the only required variable. Coolify generates the domain, TLS certificate and database password.
  3. Attach a domain to the app service (port 3000). With a custom domain, also set PAYLOAD_PUBLIC_SERVER_URL=https://cms.example.com, otherwise the login page and media URLs use the Coolify-generated domain.
  4. Deploy. The first start applies all migrations. Open https://cms.example.com/admin and create the first account; it becomes the super admin.

Create the first account right after deploying. While the database is empty, anyone who can reach /admin can submit the first-user form and become a super admin.

To use an external PostgreSQL instead of the bundled one, set DATABASE_URI and remove the db service together with the depends_on entry of app.

The compose file forwards R2_OFF, ENABLE_JOBS_AUTORUN, FRONTEND_BASE_URL, DEEPSEEK_API_KEY, DEEPSEEK_MODEL, RECAPTCHA_SECRET, MODERATION_WEBHOOK_URL, OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_ENDPOINT, SEED_DEMO and SKIP_MIGRATIONS. A variable missing from the compose environment: block does not reach the container, so add it there if you use another one. Do not set SEED_DEMO=true on a real install: it creates a demo site and sample content.

  • Images are stored in the media_data volume (/app/media) by default. To keep them off the server, configure Cloudflare R2 per site. See Media library.
  • Every content save queues a "revalidate frontend" job so your website refreshes its cache. Jobs only run when ENABLE_JOBS_AUTORUN=true, and that variable must be enabled on exactly one instance.

Back up both the database and the media, and keep the PAYLOAD_SECRET you use. Enable Coolify's scheduled database backups for the postgres_data volume and include media_data in your server backup.

The full guide to deployment, backups and troubleshooting is in Deploy.