---
services:
  postgres:
    restart: always
    image: "postgres:15.1-alpine"
    container_name: phoenixDB # Hostname
    # logging:
    #   driver: loki
    #   options:
    #     loki-url: "${LOKI_URL}"
    #     loki-retries: "${LOKI_RETRIES}"
    #     loki-batch-size: "${LOKI_BATCH_SIZE}"
    #     loki-external-labels: "service=phx-postgres,env=prod"
    networks:
      - backend
    environment:
      DEBUG: true
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - "./database:/var/lib/postgresql/data"
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U postgres" ]
      interval: 5s # Time between each health check
      timeout: 2s # Number of failures before marking as unhealthy
      retries: 5  # Grace period before health checks start
  pgadmin:
    restart: always
    image: dpage/pgadmin4
    container_name: pgadmin4-ui
    user: "5050:5050"
    # logging:
    #   driver: loki
    #   options:
    #     loki-url: "${LOKI_URL}"
    #     loki-retries: "${LOKI_RETRIES}"
    #     loki-batch-size: "${LOKI_BATCH_SIZE}"
    #     loki-external-labels: "service=phx-pgadmin,env=prod"
    networks:
      - backend
      - frontend
    environment:
      PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
      PGADMIN_DEFAULT_PASSWORD: ${SUPER_ADMIN_USER_PASSWORD}
      PGADMIN_CONFIG_SERVER_MODE: 'True'
      PGADMIN_CONFIG_WSGI_SCRIPT_NAME: "'/pgadmin4'"
      PGADMIN_CONFIG_PROXY_X_PROTO_COUNT: 1
      PGADMIN_SERVER_JSON_FILE: '/var/lib/pgadmin/servers.json'
      PGADMIN_REPLACE_SERVERS_ON_STARTUP: 'True'
      PGADMIN_CONFIG_DATA_DIR: "'/var/lib/pgadmin'"
      PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: 'False'

      # pgpass dynamic vars
      PGPASSFILE: /var/lib/pgadmin/pgpass
      PGPASS_HOST: ${DB_HOST}
      PGPASS_PORT: ${DB_PORT}
      PGPASS_DB: ${DB_NAME}
      PGPASS_USER: ${DB_USERNAME}
      PGPASS_PASSWORD: ${POSTGRES_PASSWORD}

      # Other config
      ALLOW_SAVE_PASSWORD: 'False'
      MFA_ENABLED: 'True'
      MFA_FORCE_REGISTRATION: 'False'
      MFA_SUPPORTED_METHODS: 'email'
      MFA_EMAIL_SUBJECT: 'Your MFA code by PHX-ERP'
      MAX_LOGIN_ATTEMPTS: 5
      ENHANCED_COOKIE_PROTECTION: 'True'
      SHOW_GRAVATAR_IMAGE: 'True'
      SECURITY_EMAIL_SENDER: ${SECURITY_EMAIL_SENDER}
      MAIL_SERVER: ${MAIL_SERVER}
      MAIL_PORT: ${MAIL_PORT}
      MAIL_USE_SSL: 'False'
      MAIL_USE_TLS: 'False'
      MAIL_USERNAME: ${MAIL_USERNAME}
      MAIL_PASSWORD: ${MAIL_PASSWORD}
      MAIL_DEBUG: 'False'
    volumes:
      - ./pgadmin/data:/var/lib/pgadmin
      - ./pgadmin/pgadmin-entrypoint.sh:/docker-entrypoint.sh:ro
    entrypoint: ["/bin/sh", "/docker-entrypoint.sh"]
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "-O", "-", "http://localhost:80/misc/ping"]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 60s
  phoenix-app:
    restart: always
    image: "phxerp/phoenix-app:alpha"
    container_name: phoenix-app
    ports:
      - "3000:3000" # Restrict to only allow access from Grafana Server IP
    # logging:
    #   driver: loki
    #   options:
    #     loki-url: "${LOKI_URL}"
    #     loki-retries: "${LOKI_RETRIES}"
    #     loki-batch-size: "${LOKI_BATCH_SIZE}"
    #     loki-external-labels: "service=phx-app,env=prod,project=phoenix"
    volumes:
      - "/opt/containers/phx/app_custom:/usr/share/nginx/html/assets/custom"
      - "/opt/containers/phx/nginx/nginx.conf:/etc/nginx/nginx.conf"
      - ./nginx/includes:/etc/nginx/includes:ro
    networks:
      - backend
      - frontend
    depends_on:
      pgadmin:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://phoenix-app/login"] # localhost checks that the NGINX server inside the container is serving something at the root 
      interval: 10s       # check every 10 seconds
      timeout: 5s         # allow 5 seconds per check
      retries: 5          # mark as unhealthy after 5 failures
      start_period: 15s   # wait 15 seconds after container start before checking
  phoenix-system:
    restart: "no"
    image: "phxerp/phoenix-system:alpha"
    # logging:
    #   driver: loki
    #   options:
    #     loki-url: "${LOKI_URL}"
    #     loki-retries: "${LOKI_RETRIES}"
    #     loki-batch-size: "${LOKI_BATCH_SIZE}"
    #     loki-external-labels: "service=phoenix-system,env=prod"
    environment:
      - "DB_HOST=phoenixDB"
      - "DB_NAME=${DB_NAME}"
      - "DB_PASSWORD=${POSTGRES_PASSWORD}"
      - "DB_USERNAME=postgres"
      - "SUPER_ADMIN_USER_PASSWORD=${SUPER_ADMIN_USER_PASSWORD}"
      - "REDIS_PASSWORD=${REDIS_PASSWORD}"
      - RUN_JOB_QUEUE=${RUN_JOB_QUEUE}
      - NODE_ENV=${NODE_ENV}
    command: ["npm", "run", "start:server"]
    deploy:
      replicas: ${PHOENIX_SYSTEM_REPLICAS} #change here if u want to have more replicas. Cant find a way to set via variable right now
    networks:
      backend:
        aliases:
          - phoenix-system
    depends_on:
      postgres:
        condition: service_healthy
      phoenix-redis:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "curl -s http://phoenix-system:3000/health | grep -q '\"admin-api\":{\"status\":\"up\"}' && curl -s http://phoenix-system:3000/health | grep -q '\"database\":{\"status\":\"up\"}'"] # Checks both admin-api and database status
      interval: 10s # Time between each health check
      timeout: 6s # Max time to wait for each check
      retries: 10 # Number of failures before marking as unhealthy
      start_period: 40s  # Grace period before health checks start
    volumes:
      - "./assets:/usr/src/app/packages/dev-server/assets"
      - "/opt/containers/phx/server_custom:/usr/src/app/packages/dev-server/custom" # it seems tobe no effect if we make changes, not 100% of sure!
      - "./logs:/usr/src/app/packages/dev-server/logs"
  phoenix-worker:
    restart: "no"
    image: "phxerp/phoenix-system:alpha"
    container_name: "phoenix-worker"
    ports:
      - "3001:3001" # Restrict to only allow access from Grafana Server IP
    # logging:
    #   driver: loki
    #   options:
    #     loki-url: "${LOKI_URL}"
    #     loki-retries: "${LOKI_RETRIES}"
    #     loki-batch-size: "${LOKI_BATCH_SIZE}"
    #     loki-external-labels: "service=phx-worker,env=prod"
    networks:
      - backend
    environment:
      - DB_HOST=phoenixDB
      - "DB_NAME=${DB_NAME}"
      - "DB_PASSWORD=${POSTGRES_PASSWORD}"
      - DB_USERNAME=postgres
      - "SUPER_ADMIN_USER_PASSWORD=${SUPER_ADMIN_USER_PASSWORD}"
      - REDIS_PASSWORD=${REDIS_PASSWORD}
      - NODE_ENV=${NODE_ENV}
    command: ['npm', 'run', 'start:worker']
    depends_on:
      phoenix-system:
        condition: service_healthy
      postgres:
        condition: service_healthy
    healthcheck:
      test: [ "CMD-SHELL", "curl -s http://phoenix-worker:3001/health | grep -q '\"status\":\"ok\"'" ] # Check if worker responds with status ok
      interval: 10s   # Time between each health check
      timeout: 6s     # Max time to wait for each check
      retries: 20     # Grace period before health checks start
      start_period: 30s  # Grace period before health checks start
    volumes:
      #  - "/opt/containers/phx/assets:/usr/src/app/packages/dev-server/custo/assets"
      - "./assets:/usr/src/app/packages/dev-server/assets"
      - "/opt/containers/phx/server_custom:/usr/src/app/packages/dev-server/custom"
      - "./logs:/usr/src/app/packages/dev-server/logs"
  phoenix-redis:
    image: 'bitnami/redis:latest'
    container_name: redis
    command: /opt/bitnami/scripts/redis/run.sh --maxmemory 100mb
    user: root
    # logging:
    #   driver: loki
    #   options:
    #     loki-url: "${LOKI_URL}"
    #     loki-retries: "${LOKI_RETRIES}"
    #     loki-batch-size: "${LOKI_BATCH_SIZE}"
    #     loki-external-labels: "service=phx-redis,env=prod"
    networks:
      - backend
    restart: always
    environment:
      ALLOW_EMPTY_PASSWORD: "no"
      REDIS_PASSWORD: ${REDIS_PASSWORD}
    healthcheck:
      test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]
      interval: 5s
      retries: 10  # Increase retries if Redis takes a while to start
      timeout: 5s  # Increase timeout if needed
    depends_on:
      postgres:
        condition: service_healthy
    volumes:
      - /opt/containers/phx/redis/data:/bitnami/redis/data
  phoenix-health-exporter:
    image: phxerp/phoenix-health-exporter:alpha
    container_name: health_exporter
    restart: unless-stopped
    # logging:
    #   driver: loki
    #   options:
    #     loki-url: "${LOKI_URL}"
    #     loki-retries: "${LOKI_RETRIES}"
    #     loki-batch-size: "${LOKI_BATCH_SIZE}"
    #     loki-external-labels: "service=phx-health-exporter,env=prod"
    ports:
      - "9800:9800"
    environment:
      DB_HOST: ${DB_HOST}
      DB_NAME: ${DB_NAME}
      DB_PASSWORD: ${POSTGRES_PASSWORD}
      DB_USERNAME: ${DB_USERNAME}
    networks:
      - frontend
      - backend
    volumes:
      - /etc/hostname:/etc/host_hostname:ro # This ensures the container always uses the real machine hostname, even if restarted or recreated.
    security_opt:
      - no-new-privileges:true
    deploy:
      resources:
        limits:
            cpus: '0.25'
            memory: 128M
    depends_on:
      phoenix-system:
        condition: service_healthy
      phoenix-worker:
        condition: service_healthy
      postgres:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "curl -sf http://localhost:9800/healthz || exit 1"]
      interval: 1m
      timeout: 5s
      retries: 3
      start_period: 15s
  node-exporter:
    image: quay.io/prometheus/node-exporter:latest
    container_name: node_exporter
    # logging:
    #   driver: loki
    #   options:
    #     loki-url: "${LOKI_URL}"
    #     loki-retries: "${LOKI_RETRIES}"
    #     loki-batch-size: "${LOKI_BATCH_SIZE}"
    #     loki-external-labels: "service=phx-node-exporter,env=prod"
    networks:
      - metrics
      - frontend
    restart: unless-stopped
    ports:
      - "9100:9100"  # Restrict to only allow access from Grafana Server IP
    command:
      - "--path.procfs=/host/proc"
      - "--path.sysfs=/host/sys"
      - "--path.rootfs=/host"
      - "--collector.filesystem.ignored-mount-points=^/(sys|proc|dev)($$|/)"
    volumes:
      - "/proc:/host/proc:ro"
      - "/sys:/host/sys:ro"
      - "/:/host:ro,rslave"
    security_opt:
      - no-new-privileges:true
    deploy:
      resources:
        limits:
            cpus: '0.25'
            memory: 128M
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:9100/metrics"]
      interval: 15s
      timeout: 5s
      retries: 3
      start_period: 20s
  # nginx-exporter:
  #   image: nginx/nginx-prometheus-exporter:1.4.2
  #   container_name: nginx_exporter
  #   restart: unless-stopped
  #   # logging:
  #   #   driver: loki
  #   #   options:
  #   #     loki-url: "${LOKI_URL}"
  #   #     loki-retries: "${LOKI_RETRIES}"
  #   #     loki-batch-size: "${LOKI_BATCH_SIZE}"
  #   #     loki-external-labels: "service=phx-nginx-exporter,env=prod"
  #   ports:
  #     - "9113:9113" # Restrict to only allow access from Grafana Server IP
  #   command:
  #     - '--nginx.scrape-uri=http://phoenixApp/stub_status'
  #   security_opt:
  #     - no-new-privileges:true
  #   deploy:
  #     resources:
  #       limits:
  #           cpus: '0.25'
  #           memory: 128M
  #   depends_on:
  #     phoenix-app:
  #       condition: service_healthy
  #   networks:
  #     - frontend
  #     - metrics
    # healthcheck:
    #   test: ["CMD", "wget", "-qO-", "http://localhost:9113/metrics"] # Not working as expected
    #   interval: 15s
    #   timeout: 5s
    #   retries: 3
    #   start_period: 10s
  https_portal:
    container_name: https_portal
    image: "steveltn/https-portal:1.21"
    restart: unless-stopped
    # logging:
    #   driver: loki
    #   options:
    #     loki-url: "${LOKI_URL}"
    #     loki-retries: "${LOKI_RETRIES}"
    #     loki-batch-size: "${LOKI_BATCH_SIZE}"
    #     loki-external-labels: "service=phx-https-portal,env=prod"
    networks:
      - frontend # [ PgAdmin, Phoenix-App ]
    ports:
      - "80:80"
      - "443:443"
      # - host:container
    environment:
      STAGE: "production" # Use Let's Encrypt production server
      WEBSOCKET: "true" # Enable websocket support
      DEBUG: "true"
      RENEW_MARGIN_DAYS: 30
      CLIENT_MAX_BODY_SIZE: 0
      SERVER_NAMES_HASH_BUCKET_SIZE: 128 # Increase hash bucket size for server names - good for bigger domains names, if not set correctly, it will throw an error, break the container.
      # FORCE_RENEW: 'true'
      DOMAINS: "${HTTPS_PORTAL_DOMAINS}"
    volumes:
      - ./https_portal/data:/var/lib/https-portal # ssl_certs, vhost.d, htdocs
      - ./https_portal/log:/var/log/nginx # nginx logs
      # - ./https_portal/config/custom_nginx.conf:/opt/custom_nginx.conf:ro  # ✅ Mount file in a safe path
    depends_on:
      pgadmin:
        condition: service_healthy
      postgres:
        condition: service_healthy
  fail2ban:
    image: crazymax/fail2ban:latest
    container_name: fail2ban
    network_mode: 'host'
    cap_add:
        - NET_ADMIN
        - NET_RAW
    volumes:
        - ./fail2ban/data:/data
        - ./fail2ban/jail.d:/etc/fail2ban/jail.d
        - /var/log:/var/log:ro
    restart: always
    
volumes:
  asset-data: null

networks:
  backend:
    driver: bridge
    external: false
    ipam:
      config:
        - subnet: 172.19.0.0/16

  frontend:
    driver: bridge
    external: false
    ipam:
      config:
        - subnet: 172.20.0.0/16
  
  metrics:
    driver: bridge
    external: false
    ipam:
      config:
        - subnet: 172.22.0.0/16
