# ============================================================================= # PLANE DOCKER COMPOSE - GHCR PRE-BUILT IMAGES (Standalone) # ============================================================================= # Fast deployment using pre-built images from GitHub Container Registry. # No build required - just pull and run! # # USAGE: # 1. Run: ./setup-env.sh # 2. Run: docker compose -f docker-compose.ghcr.yml up -d # # UPDATING: # docker compose -f docker-compose.ghcr.yml pull # docker compose -f docker-compose.ghcr.yml up -d # # ============================================================================= # ============================================================================= # SHARED ENVIRONMENT VARIABLES # ============================================================================= x-db-env: &db-env PGHOST: plane-db PGDATABASE: ${POSTGRES_DB:-plane} POSTGRES_USER: ${POSTGRES_USER:-plane} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-plane} POSTGRES_DB: ${POSTGRES_DB:-plane} POSTGRES_PORT: "5432" PGDATA: /var/lib/postgresql/data x-redis-env: &redis-env REDIS_HOST: ${REDIS_HOST:-plane-redis} REDIS_PORT: ${REDIS_PORT:-6379} REDIS_URL: ${REDIS_URL:-redis://plane-redis:6379/} x-minio-env: &minio-env MINIO_ROOT_USER: ${AWS_ACCESS_KEY_ID:-minioadmin} MINIO_ROOT_PASSWORD: ${AWS_SECRET_ACCESS_KEY:-minioadmin} x-aws-s3-env: &aws-s3-env AWS_REGION: ${AWS_REGION:-} AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-minioadmin} AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-minioadmin} AWS_S3_ENDPOINT_URL: ${AWS_S3_ENDPOINT_URL:-http://plane-minio:9000} AWS_S3_BUCKET_NAME: ${AWS_S3_BUCKET_NAME:-uploads} x-mq-env: &mq-env RABBITMQ_HOST: plane-mq RABBITMQ_PORT: ${RABBITMQ_PORT:-5672} RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER:-plane} RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD:-plane} RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_VHOST:-plane} RABBITMQ_VHOST: ${RABBITMQ_VHOST:-plane} x-live-env: &live-env API_BASE_URL: ${API_BASE_URL:-http://api:8000} LIVE_SERVER_SECRET_KEY: ${SECRET_KEY:-changeme} x-app-env: &app-env # Application settings APP_RELEASE: ${APP_RELEASE:-latest} WEB_URL: ${WEB_URL:-http://localhost} DEBUG: ${DEBUG:-0} # CORS settings CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:-${WEB_URL:-http://localhost}} # Worker configuration GUNICORN_WORKERS: ${GUNICORN_WORKERS:-2} USE_MINIO: ${USE_MINIO:-1} # Database connection DATABASE_URL: postgresql://${POSTGRES_USER:-plane}:${POSTGRES_PASSWORD:-plane}@plane-db/${POSTGRES_DB:-plane} # Security SECRET_KEY: ${SECRET_KEY:-insecure-dev-key-change-in-production} # Message queue AMQP_URL: amqp://${RABBITMQ_USER:-plane}:${RABBITMQ_PASSWORD:-plane}@plane-mq:${RABBITMQ_PORT:-5672}/${RABBITMQ_VHOST:-plane} # Rate limiting API_KEY_RATE_LIMIT: ${API_KEY_RATE_LIMIT:-60/minute} # SSL settings MINIO_ENDPOINT_SSL: ${MINIO_ENDPOINT_SSL:-0} # ============================================================================= # SERVICES - Pre-built images from GitHub Container Registry # ============================================================================= services: # --------------------------------------------------------------------------- # REVERSE PROXY (Caddy) # --------------------------------------------------------------------------- proxy: image: ghcr.io/egeorcun/plane-proxy:${APP_RELEASE:-latest} pull_policy: always ports: - "${LISTEN_HTTP_PORT:-80}:80" - "${LISTEN_HTTPS_PORT:-443}:443" environment: - APP_DOMAIN=${WEB_URL:-http://localhost} - SITE_ADDRESS=:80 - FILE_SIZE_LIMIT=${FILE_SIZE_LIMIT:-5242880} - BUCKET_NAME=${AWS_S3_BUCKET_NAME:-uploads} depends_on: - web - api - space - admin - live healthcheck: test: ['CMD', 'wget', '-qO-', 'http://127.0.0.1:80/'] interval: 10s timeout: 10s retries: 5 restart: unless-stopped # --------------------------------------------------------------------------- # FRONTEND APPLICATIONS # --------------------------------------------------------------------------- web: image: ghcr.io/egeorcun/plane-web:${APP_RELEASE:-latest} pull_policy: always depends_on: - api healthcheck: test: ['CMD-SHELL', 'wget -qO- http://localhost:3000/ || exit 0'] interval: 10s timeout: 10s retries: 5 restart: unless-stopped space: image: ghcr.io/egeorcun/plane-space:${APP_RELEASE:-latest} pull_policy: always depends_on: - api - web healthcheck: test: ['CMD', 'echo', 'ok'] interval: 10s timeout: 10s retries: 5 restart: unless-stopped admin: image: ghcr.io/egeorcun/plane-admin:${APP_RELEASE:-latest} pull_policy: always depends_on: - api - web healthcheck: test: ['CMD', 'echo', 'ok'] interval: 10s timeout: 10s retries: 5 restart: unless-stopped live: image: ghcr.io/egeorcun/plane-live:${APP_RELEASE:-latest} pull_policy: always environment: <<: [*live-env, *redis-env] depends_on: - api - web - plane-redis healthcheck: test: ['CMD', 'echo', 'ok'] interval: 10s timeout: 10s retries: 5 restart: unless-stopped # --------------------------------------------------------------------------- # BACKEND API & WORKERS # --------------------------------------------------------------------------- api: image: ghcr.io/egeorcun/plane-backend:${APP_RELEASE:-latest} pull_policy: always command: ./bin/docker-entrypoint-api.sh volumes: - logs_api:/code/plane/logs environment: <<: [*app-env, *db-env, *redis-env, *aws-s3-env, *mq-env] depends_on: plane-db: condition: service_healthy plane-redis: condition: service_healthy plane-mq: condition: service_healthy migrator: condition: service_completed_successfully healthcheck: test: ['CMD', 'echo', 'ok'] interval: 10s timeout: 10s retries: 5 restart: unless-stopped worker: image: ghcr.io/egeorcun/plane-backend:${APP_RELEASE:-latest} pull_policy: always command: ./bin/docker-entrypoint-worker.sh volumes: - logs_worker:/code/plane/logs environment: <<: [*app-env, *db-env, *redis-env, *aws-s3-env, *mq-env] depends_on: - api - plane-db - plane-redis - plane-mq healthcheck: test: ['CMD', 'echo', 'ok'] interval: 10s timeout: 10s retries: 5 restart: unless-stopped beat-worker: image: ghcr.io/egeorcun/plane-backend:${APP_RELEASE:-latest} pull_policy: always command: ./bin/docker-entrypoint-beat.sh volumes: - logs_beat:/code/plane/logs environment: <<: [*app-env, *db-env, *redis-env, *aws-s3-env, *mq-env] depends_on: - api - plane-db - plane-redis - plane-mq healthcheck: test: ['CMD', 'echo', 'ok'] interval: 10s timeout: 10s retries: 5 restart: unless-stopped migrator: image: ghcr.io/egeorcun/plane-backend:${APP_RELEASE:-latest} pull_policy: always restart: 'no' command: ./bin/docker-entrypoint-migrator.sh volumes: - logs_migrator:/code/plane/logs environment: <<: [*app-env, *db-env, *redis-env, *aws-s3-env, *mq-env] depends_on: plane-db: condition: service_healthy plane-redis: condition: service_healthy # --------------------------------------------------------------------------- # DATA STORES # --------------------------------------------------------------------------- plane-db: image: postgres:15.7-alpine command: postgres -c 'max_connections=1000' environment: <<: *db-env volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ['CMD-SHELL', 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}'] interval: 5s timeout: 20s retries: 10 restart: unless-stopped plane-redis: image: valkey/valkey:7.2.5-alpine volumes: - redisdata:/data healthcheck: test: ['CMD', 'redis-cli', 'ping'] interval: 5s timeout: 20s retries: 10 restart: unless-stopped plane-mq: image: rabbitmq:3.13.6-management-alpine environment: <<: *mq-env volumes: - rabbitmq_data:/var/lib/rabbitmq healthcheck: test: 'rabbitmq-diagnostics -q ping' interval: 30s timeout: 30s retries: 3 restart: unless-stopped plane-minio: image: minio/minio:latest command: server /export --console-address ":9090" environment: <<: *minio-env volumes: - uploads:/export healthcheck: test: ['CMD', 'mc', 'ready', 'local'] interval: 5s timeout: 20s retries: 10 restart: unless-stopped # ============================================================================= # VOLUMES # ============================================================================= volumes: pgdata: redisdata: uploads: rabbitmq_data: logs_api: logs_worker: logs_beat: logs_migrator: