Last active
February 11, 2026 15:24
-
-
Save flyingwebie/1dddf2768c51b61522d587d684fc45d7 to your computer and use it in GitHub Desktop.
Host Twenty CRM in your Coolify system
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # documentation: https://twenty.com/developers/section/self-hosting | |
| # slogan: Open-source CRM platform for modern teams with customizable workflows and integrations | |
| # tags: crm,productivity,sales,open-source,business | |
| # logo: svgs/twenty.svg | |
| # port: 3000 | |
| services: | |
| postgres: | |
| image: 'postgres:16-alpine' | |
| volumes: | |
| - '${COOLIFY_VOLUME_DB}:/var/lib/postgresql/data' | |
| environment: | |
| - 'POSTGRES_DB=${POSTGRES_DB:-twenty-db}' | |
| - 'POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}' | |
| - 'POSTGRES_USER=${SERVICE_USER_POSTGRES}' | |
| healthcheck: | |
| test: | |
| - CMD-SHELL | |
| - 'pg_isready -U ${POSTGRES_USER} -h localhost -d ${POSTGRES_DB}' | |
| interval: 10s | |
| timeout: 5s | |
| retries: 10 | |
| start_period: 20s | |
| restart: always | |
| twenty: | |
| image: 'twentycrm/twenty:${TAG:-latest}' | |
| volumes: | |
| - '${COOLIFY_VOLUME_SERVER}:/app/packages/twenty-server/.local-storage' | |
| environment: | |
| - SERVICE_FQDN_SERVER_3000 | |
| - NODE_PORT=3000 | |
| - 'PG_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB}' | |
| - 'SERVER_URL=${SERVICE_URL_SERVER}' | |
| - 'CACHE_STORAGE_TYPE=${CACHE_STORAGE_TYPE:-redis}' | |
| - 'REDIS_URL=redis://redis:6379' | |
| - 'API_RATE_LIMITING_TTL=${API_RATE_LIMITING_TTL:-100}' | |
| - 'API_RATE_LIMITING_LIMIT=${API_RATE_LIMITING_LIMIT:-100}' | |
| - 'DISABLE_DB_MIGRATIONS=${DISABLE_DB_MIGRATIONS:-false}' | |
| - 'DISABLE_CRON_JOBS_REGISTRATION=${DISABLE_CRON_JOBS_REGISTRATION:-false}' | |
| - 'STORAGE_TYPE=${STORAGE_TYPE:-local}' | |
| - 'STORAGE_S3_REGION=${STORAGE_S3_REGION:-}' | |
| - 'STORAGE_S3_NAME=${STORAGE_S3_NAME:-}' | |
| - 'STORAGE_S3_ENDPOINT=${STORAGE_S3_ENDPOINT:-}' | |
| - 'APP_SECRET=${SERVICE_PASSWORD_64}' | |
| - 'MESSAGING_PROVIDER_GMAIL_ENABLED=${MESSAGING_PROVIDER_GMAIL_ENABLED:-false}' | |
| - 'CALENDAR_PROVIDER_GOOGLE_ENABLED=${CALENDAR_PROVIDER_GOOGLE_ENABLED:-false}' | |
| - 'AUTH_GOOGLE_CLIENT_ID=${AUTH_GOOGLE_CLIENT_ID:-}' | |
| - 'AUTH_GOOGLE_CLIENT_SECRET=${AUTH_GOOGLE_CLIENT_SECRET:-}' | |
| - 'AUTH_GOOGLE_CALLBACK_URL=${AUTH_GOOGLE_CALLBACK_URL:-}' | |
| - 'AUTH_GOOGLE_APIS_CALLBACK_URL=${AUTH_GOOGLE_APIS_CALLBACK_URL:-}' | |
| - 'CALENDAR_PROVIDER_MICROSOFT_ENABLED=${CALENDAR_PROVIDER_MICROSOFT_ENABLED:-false}' | |
| - 'MESSAGING_PROVIDER_MICROSOFT_ENABLED=${MESSAGING_PROVIDER_MICROSOFT_ENABLED:-false}' | |
| - 'AUTH_MICROSOFT_ENABLED=${AUTH_MICROSOFT_ENABLED:-false}' | |
| - 'AUTH_MICROSOFT_CLIENT_ID=${AUTH_MICROSOFT_CLIENT_ID:-}' | |
| - 'AUTH_MICROSOFT_CLIENT_SECRET=${AUTH_MICROSOFT_CLIENT_SECRET:-}' | |
| - 'AUTH_MICROSOFT_CALLBACK_URL=${AUTH_MICROSOFT_CALLBACK_URL:-}' | |
| - 'AUTH_MICROSOFT_APIS_CALLBACK_URL=${AUTH_MICROSOFT_APIS_CALLBACK_URL:-}' | |
| - 'EMAIL_FROM_ADDRESS=${EMAIL_FROM_ADDRESS:-contact@yourdomain.com}' | |
| - 'EMAIL_FROM_NAME=${EMAIL_FROM_NAME:-Twenty CRM}' | |
| - 'EMAIL_SYSTEM_ADDRESS=${EMAIL_SYSTEM_ADDRESS:-system@yourdomain.com}' | |
| - 'EMAIL_DRIVER=${EMAIL_DRIVER:-smtp}' | |
| - 'EMAIL_SMTP_HOST=${EMAIL_SMTP_HOST:-}' | |
| - 'EMAIL_SMTP_PORT=${EMAIL_SMTP_PORT:-587}' | |
| - 'EMAIL_SMTP_USER=${EMAIL_SMTP_USER:-}' | |
| - 'EMAIL_SMTP_PASSWORD=${EMAIL_SMTP_PASSWORD:-}' | |
| - 'MESSAGE_QUEUE_TYPE=${MESSAGE_QUEUE_TYPE:-pg-boss}' | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| redis: | |
| condition: service_healthy | |
| healthcheck: | |
| test: | |
| - CMD | |
| - curl | |
| - '--fail' | |
| - 'http://localhost:3000/healthz' | |
| interval: 10s | |
| timeout: 5s | |
| retries: 20 | |
| start_period: 30s | |
| restart: always | |
| labels: | |
| - traefik.enable=true | |
| - 'traefik.http.routers.twenty-server-http.rule=Host(`${SERVICE_FQDN_SERVER}`)' | |
| - traefik.http.routers.twenty-server-http.entryPoints=http | |
| - traefik.http.routers.twenty-server-http.middlewares=redirect-to-https | |
| - 'traefik.http.routers.twenty-server-https.rule=Host(`${SERVICE_FQDN_SERVER}`)' | |
| - traefik.http.routers.twenty-server-https.entryPoints=https | |
| - traefik.http.routers.twenty-server-https.tls=true | |
| - traefik.http.routers.twenty-server-https.tls.certresolver=letsencrypt | |
| - traefik.http.services.twenty-server.loadbalancer.server.port=3000 | |
| worker: | |
| image: 'twentycrm/twenty:${TAG:-latest}' | |
| volumes: | |
| - '${COOLIFY_VOLUME_SERVER}:/app/packages/twenty-server/.local-storage' | |
| command: | |
| - yarn | |
| - 'worker:prod' | |
| environment: | |
| - 'PG_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB}' | |
| - 'SERVER_URL=${SERVICE_URL_SERVER}' | |
| - 'CACHE_STORAGE_TYPE=${CACHE_STORAGE_TYPE:-redis}' | |
| - 'REDIS_URL=redis://redis:6379' | |
| - 'API_RATE_LIMITING_TTL=${API_RATE_LIMITING_TTL:-100}' | |
| - 'API_RATE_LIMITING_LIMIT=${API_RATE_LIMITING_LIMIT:-100}' | |
| - DISABLE_DB_MIGRATIONS=true | |
| - DISABLE_CRON_JOBS_REGISTRATION=true | |
| - 'STORAGE_TYPE=${STORAGE_TYPE:-local}' | |
| - 'STORAGE_S3_REGION=${STORAGE_S3_REGION:-}' | |
| - 'STORAGE_S3_NAME=${STORAGE_S3_NAME:-}' | |
| - 'STORAGE_S3_ENDPOINT=${STORAGE_S3_ENDPOINT:-}' | |
| - 'APP_SECRET=${SERVICE_PASSWORD_64}' | |
| - 'MESSAGING_PROVIDER_GMAIL_ENABLED=${MESSAGING_PROVIDER_GMAIL_ENABLED:-false}' | |
| - 'CALENDAR_PROVIDER_GOOGLE_ENABLED=${CALENDAR_PROVIDER_GOOGLE_ENABLED:-false}' | |
| - 'AUTH_GOOGLE_CLIENT_ID=${AUTH_GOOGLE_CLIENT_ID:-}' | |
| - 'AUTH_GOOGLE_CLIENT_SECRET=${AUTH_GOOGLE_CLIENT_SECRET:-}' | |
| - 'AUTH_GOOGLE_CALLBACK_URL=${AUTH_GOOGLE_CALLBACK_URL:-}' | |
| - 'AUTH_GOOGLE_APIS_CALLBACK_URL=${AUTH_GOOGLE_APIS_CALLBACK_URL:-}' | |
| - 'CALENDAR_PROVIDER_MICROSOFT_ENABLED=${CALENDAR_PROVIDER_MICROSOFT_ENABLED:-false}' | |
| - 'MESSAGING_PROVIDER_MICROSOFT_ENABLED=${MESSAGING_PROVIDER_MICROSOFT_ENABLED:-false}' | |
| - 'AUTH_MICROSOFT_ENABLED=${AUTH_MICROSOFT_ENABLED:-false}' | |
| - 'AUTH_MICROSOFT_CLIENT_ID=${AUTH_MICROSOFT_CLIENT_ID:-}' | |
| - 'AUTH_MICROSOFT_CLIENT_SECRET=${AUTH_MICROSOFT_CLIENT_SECRET:-}' | |
| - 'AUTH_MICROSOFT_CALLBACK_URL=${AUTH_MICROSOFT_CALLBACK_URL:-}' | |
| - 'AUTH_MICROSOFT_APIS_CALLBACK_URL=${AUTH_MICROSOFT_APIS_CALLBACK_URL:-}' | |
| - 'EMAIL_FROM_ADDRESS=${EMAIL_FROM_ADDRESS:-contact@yourdomain.com}' | |
| - 'EMAIL_FROM_NAME=${EMAIL_FROM_NAME:-Twenty CRM}' | |
| - 'EMAIL_SYSTEM_ADDRESS=${EMAIL_SYSTEM_ADDRESS:-system@yourdomain.com}' | |
| - 'EMAIL_DRIVER=${EMAIL_DRIVER:-smtp}' | |
| - 'EMAIL_SMTP_HOST=${EMAIL_SMTP_HOST:-}' | |
| - 'EMAIL_SMTP_PORT=${EMAIL_SMTP_PORT:-587}' | |
| - 'EMAIL_SMTP_USER=${EMAIL_SMTP_USER:-}' | |
| - 'EMAIL_SMTP_PASSWORD=${EMAIL_SMTP_PASSWORD:-}' | |
| - 'MESSAGE_QUEUE_TYPE=${MESSAGE_QUEUE_TYPE:-pg-boss}' | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| twenty: | |
| condition: service_healthy | |
| restart: always | |
| redis: | |
| image: 'redis:7-alpine' | |
| restart: always | |
| command: | |
| - redis-server | |
| - '--maxmemory-policy' | |
| - noeviction | |
| - '--save' | |
| - '60' | |
| - '1' | |
| volumes: | |
| - '${COOLIFY_VOLUME_REDIS}:/data' | |
| healthcheck: | |
| test: | |
| - CMD | |
| - redis-cli | |
| - ping | |
| interval: 10s | |
| timeout: 5s | |
| retries: 10 | |
| start_period: 10s |
Author
Author
@ivanu-myrmz I compared the original docker-compose with yours but I don't see many differences expect that you removed networks and formatting the envs without '' - have you test it?
I updated and make it more secure generating random passwd for the db :D
Just dropping by to say thank you! That's perfect :)
Having the same problem with the Coolify template, the worker container is also unhealthy with this template.
Author
@sanny-io have you wait the db migration? that could be the issue - Check this video https://youtu.be/Ou7PVP0MkGc
@flyingwebie I think that was the problem, it's working now. Thank you for your help, template, and video.
It's very much appreciated 🙂
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ivanu-myrmz I compared the original docker-compose with yours but I don't see many differences expect that you removed networks and formatting the envs without '' - have you test it?