# Zynklog server installation. Generated settings are kept in the adjacent .env file.
# Email activation is handled by Codify Control.
name: zynklog
x-api-image: &api-image ghcr.io/kauanfrodrigues98/zynklog-api:${ZYNKLOG_API_VERSION:-v1.1.0}
services:
  init:
    image: *api-image
    user: '0:0'
    command: ['init']
    restart: 'no'
    environment:
      ZYNKLOG_POSTGRES_SECRET_DIR: /run/postgres-secret
      ZYNKLOG_REDIS_SECRET_DIR: /run/redis-secret
    volumes:
      - secrets:/run/zynklog
      - postgres-secret:/run/postgres-secret
      - redis-secret:/run/redis-secret
    network_mode: none
  postgres:
    image: postgres:18.6-alpine
    restart: unless-stopped
    depends_on:
      init:
        condition: service_completed_successfully
    environment:
      POSTGRES_USER: zynklog
      POSTGRES_DB: zynklog
      POSTGRES_PASSWORD_FILE: /run/postgres-secret/password
    volumes:
      - postgres-data:/var/lib/postgresql
      - postgres-secret:/run/postgres-secret:ro
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U zynklog -d zynklog']
      interval: 5s
      timeout: 3s
      retries: 30
  redis:
    image: redis:8.2.11-alpine
    restart: unless-stopped
    depends_on:
      init:
        condition: service_completed_successfully
    entrypoint: ['/bin/sh', '-ec']
    command:
      - 'exec /usr/local/bin/docker-entrypoint.sh redis-server --appendonly yes --maxmemory-policy noeviction --requirepass "$$(cat /run/redis-secret/password)"'
    volumes:
      - redis-data:/data
      - redis-secret:/run/redis-secret:ro
    healthcheck:
      test: ['CMD-SHELL', 'REDISCLI_AUTH="$$(cat /run/redis-secret/password)" redis-cli ping | grep -q PONG']
      interval: 5s
      timeout: 3s
      retries: 30
  api:
    image: *api-image
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      NODE_ENV: production
      PORT: '3000'
      HTTP_HOST: 0.0.0.0
      PUBLIC_APP_URL: https://${ZYNKLOG_APP_HOST:?Configure ZYNKLOG_APP_HOST}
      AUTH_ALLOWED_ORIGINS: https://${ZYNKLOG_APP_HOST:?Configure ZYNKLOG_APP_HOST}
      AUTH_COOKIE_SECURE: 'true'
      AUTH_ALLOW_PUBLIC_REGISTRATION: 'false'
      HTTP_TRUSTED_PROXIES: ${ZYNKLOG_EDGE_IP:-172.30.78.11}/32
      OPENAPI_ACCESS: disabled
      CONTROL_ENABLED: 'true'
      CONTROL_URL: ${CONTROL_URL:?Configure the central HTTPS API}
      CONTROL_OWNER_EMAIL: ${CONTROL_OWNER_EMAIL:?Configure the installation owner}
      CONTROL_PRODUCT_ID: ${CONTROL_PRODUCT_ID:?Configure product identity}
      CONTROL_REGISTRATION_KEY: ${CONTROL_REGISTRATION_KEY:?Configure public enrollment key}
      CONTROL_PUBLIC_KEY: ${CONTROL_PUBLIC_KEY:?Configure pinned Ed25519 public key}
      PRODUCT_LIMITS_ENABLED: 'false'
      ZYNKLOG_RELEASES_URL: ${ZYNKLOG_RELEASES_URL-https://zynklog.codifylabs.com.br/releases/stable.json}
    volumes:
      - secrets:/run/zynklog
    healthcheck:
      test: ['CMD', 'node', '-e', 'const s=require("node:net").connect(3000,"127.0.0.1",()=>{s.end();process.exit(0)});s.on("error",()=>process.exit(1));setTimeout(()=>process.exit(1),2000).unref()']
      interval: 10s
      timeout: 3s
      retries: 30
      start_period: 120s
  web:
    image: ghcr.io/kauanfrodrigues98/zynklog-front:${ZYNKLOG_FRONT_VERSION:-v1.1.0}
    restart: unless-stopped
    depends_on:
      api:
        condition: service_healthy
    environment:
      ZYNKLOG_EXTERNAL_SCHEME: https
    networks:
      default:
        ipv4_address: ${ZYNKLOG_PROXY_IP:-172.30.78.10}
  caddy:
    image: caddy:2-alpine
    restart: unless-stopped
    depends_on:
      web:
        condition: service_healthy
      api:
        condition: service_healthy
    environment:
      ZYNKLOG_APP_HOST: ${ZYNKLOG_APP_HOST:?Configure ZYNKLOG_APP_HOST}
      ZYNKLOG_API_HOST: ${ZYNKLOG_API_HOST:?Configure ZYNKLOG_API_HOST}
      ZYNKLOG_ACME_EMAIL: ${ZYNKLOG_ACME_EMAIL:?Configure ZYNKLOG_ACME_EMAIL}
    ports:
      - '80:80'
      - '443:443'
      - '443:443/udp'
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    networks:
      default:
        ipv4_address: ${ZYNKLOG_EDGE_IP:-172.30.78.11}
    healthcheck:
      test: ['CMD', 'wget', '-q', '-O', '/dev/null', 'http://127.0.0.1:2019/config/']
      interval: 10s
      timeout: 3s
      retries: 12
networks:
  default:
    ipam:
      config:
        - subnet: ${ZYNKLOG_SUBNET:-172.30.78.0/24}
volumes:
  secrets:
  postgres-secret:
  redis-secret:
  postgres-data:
  redis-data:
  caddy-data:
  caddy-config:
