name: twenty

services:
  server:
    image: twentycrm/twenty:${TAG:-latest}
    volumes:
      - type: bind
        source: ./server_local_data
        target: /app/packages/twenty-server/.local-storage
    ports:
      - "3000:3000"
    environment:
      NODE_PORT: 3000
      PG_DATABASE_URL: postgres://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@${PG_DATABASE_HOST:-db}:${PG_DATABASE_PORT:-5432}/default
      SERVER_URL: ${SERVER_URL}
      REDIS_URL: ${REDIS_URL:-redis://redis:6379}
      DISABLE_DB_MIGRATIONS: ${DISABLE_DB_MIGRATIONS}
      DISABLE_CRON_JOBS_REGISTRATION: ${DISABLE_CRON_JOBS_REGISTRATION}

      STORAGE_TYPE: ${STORAGE_TYPE}
      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}
    labels:
      - "traefik.http.middlewares.twenty-add-response-headers.headers.customresponseheaders.Strict-Transport-Security=max-age=31536000; includeSubDomains"
      - "traefik.http.middlewares.twenty-add-response-headers.headers.customresponseheaders.Access-Control-Allow-Origin=*"
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      - "traefik.http.routers.twenty.rule=Host(`twenty.hyteck.de`)"
      - "traefik.http.routers.twenty.middlewares=twenty-add-response-headers"
      - "traefik.http.routers.twenty.service=twenty-service"
      - "traefik.http.routers.twenty.entrypoints=web-secure"
      - "traefik.http.routers.twenty.tls=true"
      - "traefik.http.routers.twenty.tls.certResolver=default"
      - "traefik.http.services.twenty-service.loadbalancer.server.port=3000"
    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: curl --fail http://localhost:3000/healthz
      interval: 5s
      timeout: 5s
      retries: 20
    restart: always
    networks:
      - traefik
      - default

  worker:
    image: twentycrm/twenty:${TAG:-latest}
    volumes:
      - type: bind
        source: ./server_local_data
        target: /app/packages/twenty-server/.local-storage
    command: [ "yarn", "worker:prod" ]
    environment:
      PG_DATABASE_URL: postgres://${PG_DATABASE_USER:-postgres}:${PG_DATABASE_PASSWORD:-postgres}@${PG_DATABASE_HOST:-db}:${PG_DATABASE_PORT:-5432}/default
      SERVER_URL: ${SERVER_URL}
      REDIS_URL: ${REDIS_URL:-redis://redis:6379}
      DISABLE_DB_MIGRATIONS: "true" # it already runs on the server
      DISABLE_CRON_JOBS_REGISTRATION: "true" # it already runs on the server

      STORAGE_TYPE: ${STORAGE_TYPE}
      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}

    depends_on:
      db:
        condition: service_healthy
      server:
        condition: service_healthy
    restart: always
    networks:
      - default

  db:
    image: postgres:16
    volumes:
      - type: bind
        source: ./db_data
        target: /var/lib/postgresql/data
    environment:
      POSTGRES_USER: ${PG_DATABASE_USER:-postgres}
      POSTGRES_PASSWORD: ${PG_DATABASE_PASSWORD:-postgres}
    healthcheck:
      test: pg_isready -U ${PG_DATABASE_USER:-postgres} -h localhost -d postgres
      interval: 5s
      timeout: 5s
      retries: 10
    restart: always

  redis:
    image: redis
    restart: always
    command: [ "--maxmemory-policy", "noeviction" ]

networks:
  traefik:
    name: "traefik"
    external: true
