services: postiz: image: ghcr.io/gitroomhq/postiz-app:latest container_name: postiz restart: unless-stopped env_file: - .env.secrets # JWT_SECRET, DATABASE_URL, social-platform client IDs/secrets — never committed environment: TZ: ${TZ} MAIN_URL: ${MAIN_URL} FRONTEND_URL: ${FRONTEND_URL} NEXT_PUBLIC_BACKEND_URL: ${NEXT_PUBLIC_BACKEND_URL} BACKEND_INTERNAL_URL: ${BACKEND_INTERNAL_URL} REDIS_URL: redis://postiz-redis:6379 TEMPORAL_ADDRESS: temporal:7233 IS_GENERAL: "true" DISABLE_REGISTRATION: ${DISABLE_REGISTRATION} STORAGE_PROVIDER: ${STORAGE_PROVIDER} UPLOAD_DIRECTORY: ${UPLOAD_DIRECTORY} NEXT_PUBLIC_UPLOAD_DIRECTORY: ${UPLOAD_DIRECTORY} MASTODON_URL: ${MASTODON_URL} volumes: - /path/to/postiz/config:/config/ - /path/to/postiz/uploads:/uploads/ ports: - "${HTTP_PORT}:5000" depends_on: postiz-postgres: condition: service_healthy postiz-redis: condition: service_healthy networks: - postiz-net postiz-postgres: image: postgres:18-alpine container_name: postiz-postgres restart: unless-stopped env_file: - .env.secrets # POSTGRES_PASSWORD — never committed environment: TZ: ${TZ} POSTGRES_USER: ${POSTIZ_POSTGRES_USER} POSTGRES_DB: ${POSTIZ_POSTGRES_DB} volumes: - /path/to/postiz/postgres_data:/var/lib/postgresql healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTIZ_POSTGRES_USER} -d ${POSTIZ_POSTGRES_DB}"] interval: 10s timeout: 3s retries: 3 networks: - postiz-net postiz-redis: image: valkey/valkey:9.0-alpine container_name: postiz-redis restart: unless-stopped healthcheck: test: ["CMD-SHELL", "valkey-cli ping"] interval: 10s timeout: 3s retries: 3 volumes: - /path/to/postiz/redis_data:/data networks: - postiz-net # Temporal stack: required since Postiz v2.12.0 for all background jobs # (scheduled posting, OAuth token refresh, email digests) — not optional, # a real surprise in this app's actual deployment footprint. temporal-elasticsearch: image: elasticsearch:7.17.27 container_name: postiz-temporal-elasticsearch restart: unless-stopped environment: - cluster.routing.allocation.disk.threshold_enabled=true - cluster.routing.allocation.disk.watermark.low=512mb - cluster.routing.allocation.disk.watermark.high=256mb - cluster.routing.allocation.disk.watermark.flood_stage=128mb - discovery.type=single-node - ES_JAVA_OPTS=-Xms256m -Xmx256m - xpack.security.enabled=false volumes: - /path/to/postiz/temporal_elasticsearch_data:/usr/share/elasticsearch/data networks: - postiz-net temporal-postgres: image: postgres:18-alpine container_name: postiz-temporal-postgres restart: unless-stopped env_file: - .env.secrets.temporal-postgres # POSTGRES_PASSWORD — never committed; separate file, avoids a collision with postiz-postgres environment: TZ: ${TZ} POSTGRES_USER: ${TEMPORAL_POSTGRES_USER} volumes: - /path/to/postiz/temporal_postgres_data:/var/lib/postgresql networks: - postiz-net temporal: image: temporalio/auto-setup:1.28.1 container_name: postiz-temporal restart: unless-stopped depends_on: - temporal-postgres - temporal-elasticsearch env_file: - .env.secrets # POSTGRES_PWD — never committed environment: - DB=postgres12 - DB_PORT=5432 - POSTGRES_USER=${TEMPORAL_POSTGRES_USER} - POSTGRES_SEEDS=temporal-postgres - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml - ENABLE_ES=true - ES_SEEDS=temporal-elasticsearch - ES_VERSION=v7 - TEMPORAL_NAMESPACE=default ports: - "127.0.0.1:${TEMPORAL_PORT}:7233" # gRPC control plane, unauthenticated by default — localhost-only volumes: - ./dynamicconfig:/etc/temporal/config/dynamicconfig networks: - postiz-net temporal-admin-tools: image: temporalio/admin-tools:1.28.1-tctl-1.18.4-cli-1.4.1 container_name: postiz-temporal-admin-tools restart: unless-stopped environment: - TEMPORAL_ADDRESS=temporal:7233 - TEMPORAL_CLI_ADDRESS=temporal:7233 depends_on: - temporal stdin_open: true tty: true networks: - postiz-net temporal-ui: image: temporalio/ui:2.34.0 container_name: postiz-temporal-ui restart: unless-stopped environment: - TEMPORAL_ADDRESS=temporal:7233 - TEMPORAL_CORS_ORIGINS=http://127.0.0.1:${TEMPORAL_UI_PORT} ports: - "127.0.0.1:${TEMPORAL_UI_PORT}:8080" # unauthenticated by default — localhost-only, SSH-tunnel to debug networks: - postiz-net networks: postiz-net: external: true