Skip to content

Instantly share code, notes, and snippets.

@flyingwebie
Last active February 5, 2026 01:18
Show Gist options
  • Select an option

  • Save flyingwebie/1dddf2768c51b61522d587d684fc45d7 to your computer and use it in GitHub Desktop.

Select an option

Save flyingwebie/1dddf2768c51b61522d587d684fc45d7 to your computer and use it in GitHub Desktop.
Host Twenty CRM in your Coolify system
# 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:[email protected]}'
- 'EMAIL_FROM_NAME=${EMAIL_FROM_NAME:-Twenty CRM}'
- 'EMAIL_SYSTEM_ADDRESS=${EMAIL_SYSTEM_ADDRESS:[email protected]}'
- '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:[email protected]}'
- 'EMAIL_FROM_NAME=${EMAIL_FROM_NAME:-Twenty CRM}'
- 'EMAIL_SYSTEM_ADDRESS=${EMAIL_SYSTEM_ADDRESS:[email protected]}'
- '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
@ivanu-myrmz
Copy link

ivanu-myrmz commented Jan 24, 2026

Deployed with slight adjustments from ChatGPT

services:
  server:
    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://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@db:5432/${PG_DATABASE_NAME:-default}'
      - 'SERVER_URL=${SERVICE_URL_SERVER}'
      - 'REDIS_URL=redis://redis:6379'
      - '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=${APP_SECRET:-replace_me_with_a_random_string_minimum_32_characters}'
      - '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:[email protected]}'
      - 'EMAIL_FROM_NAME=${EMAIL_FROM_NAME:-Twenty CRM}'
      - 'EMAIL_SYSTEM_ADDRESS=${EMAIL_SYSTEM_ADDRESS:[email protected]}'
      - '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:-}'
      - 'COOLIFY_CONTAINER_NAME=${COOLIFY_CONTAINER_NAME:-}'
    depends_on:
      db:
        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://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@db:5432/${PG_DATABASE_NAME:-default}'
      - 'SERVER_URL=${SERVICE_URL_SERVER}'
      - 'REDIS_URL=redis://redis:6379'
      - 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=${APP_SECRET:-replace_me_with_a_random_string_minimum_32_characters}'
      - '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:[email protected]}'
      - 'EMAIL_FROM_NAME=${EMAIL_FROM_NAME:-Twenty CRM}'
      - 'EMAIL_SYSTEM_ADDRESS=${EMAIL_SYSTEM_ADDRESS:[email protected]}'
      - '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:-}'
      - 'COOLIFY_CONTAINER_NAME=${COOLIFY_CONTAINER_NAME:-}'
    depends_on:
      db:
        condition: service_healthy
      server:
        condition: service_healthy
    restart: always
  db:
    image: 'postgres:16-alpine'
    volumes:
      - '${COOLIFY_VOLUME_DB}:/var/lib/postgresql/data'
    environment:
      - 'POSTGRES_DB=${PG_DATABASE_NAME:-default}'
      - 'POSTGRES_PASSWORD=${PG_DATABASE_PASSWORD:-postgres}'
      - 'POSTGRES_USER=${PG_DATABASE_USER:-postgres}'
    healthcheck:
      test:
        - CMD-SHELL
        - 'pg_isready -U ${PG_DATABASE_USER:-postgres} -h localhost -d postgres'
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 20s
    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

@flyingwebie
Copy link
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?

@flyingwebie
Copy link
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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment