diff --git a/.env b/.env old mode 100644 new mode 100755 index c4083c2..ac62150 --- a/.env +++ b/.env @@ -20,8 +20,6 @@ PGADMIN_DEFAULT_PASSWORD=XDjhSX7H7z SUPER_ADMIN_USER_PASSWORD=akuuURkxM7 # ====== Redis Configuration ====== REDIS_PASSWORD=admin -# ====== Worker Configuration ====== -RUN_JOB_QUEUE=0 # ===== Metris Configuration ====== # Loki API URL -> The IP 5.75.153.161 is the Grafana Server where it has a firewall rule to allow the connection. Please, if you change here, need to be change in NGINX too. LOKI_URL=http://grafana.phx-erp.de:3100/loki/api/v1/push diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/alpha_backup.sql b/alpha_backup.sql old mode 100644 new mode 100755 diff --git a/backups/dump_db.sql b/backups/dump_db.sql old mode 100644 new mode 100755 diff --git a/backups/dump_db_1.sql b/backups/dump_db_1.sql old mode 100644 new mode 100755 diff --git a/crash_diagnose.sh b/crash_diagnose.sh new file mode 100644 index 0000000..8417ef6 --- /dev/null +++ b/crash_diagnose.sh @@ -0,0 +1,87 @@ +#!/bin/bash +set -euo pipefail + +YELLOW='\033[1;33m' +RED='\033[1;31m' +NC='\033[0m' # No color + +echo -e "šŸ“¦ ${YELLOW}PHX Crash Diagnostic Tool (Docker + Linux Server)${NC}" +echo "šŸ” Boot Timeline:" +journalctl --list-boots | head -3 + +echo -e "\nāš ļø OOM Kills:" +journalctl -b -1 | grep -i 'killed process' || echo "None found." + +echo -e "\nāš ļø Out of Memory Events:" +journalctl -b -1 | grep -i 'out of memory' || echo "None found." + +echo -e "\nāš ļø systemd-oomd Events:" +journalctl -b -1 | grep systemd-oomd || echo "None found." + +echo -e "\nšŸ”„ CPU/Load Pressure (dmesg/syslog):" +journalctl -b -1 | grep -Ei 'cpu|load average|soft lockup|hung task' || echo "None found." + +echo -e "\n🚨 System Errors (priority 0–3):" +journalctl -b -1 -p 3..0 || echo "None found." + +if command -v docker &> /dev/null && docker info >/dev/null 2>&1; then + echo -e "\n🐳 Docker detected and running." + + CONTAINERS=$(docker ps -aq) + if [[ -z "$CONTAINERS" ]]; then + echo -e "\nāš ļø No containers found. Skipping container-specific diagnostics." + else + echo -e "\n🐳 Docker OOM-Killed Containers:" + docker inspect $CONTAINERS 2>/dev/null | grep -B10 '"OOMKilled": true' || echo "No containers were OOMKilled." + + echo -e "\nšŸ” Recently Restarted Containers:" + docker ps -a --format '{{.Names}}\t{{.Status}}' | grep -i 'restarted' || echo "No recent restarts." + + echo -e "\nšŸ“‰ Top 5 Containers by Memory Usage (now):" + docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}" | sort -k2 -hr | head -n 6 + + echo -e "\nšŸ“ˆ Top 5 Containers by CPU Usage (now):" + docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}" | sort -k2 -hr | head -n 6 + + echo -e "\nšŸ“‹ Docker Container Memory Limits:" + docker inspect $CONTAINERS --format '{{ .Name }}: {{ .HostConfig.Memory }} bytes' | grep -v ': 0' || echo "None set" + + echo -e "\nšŸ“‹ Containers With No Memory Limit:" + docker inspect $CONTAINERS --format '{{ .Name }}: {{ .HostConfig.Memory }}' | awk '$2 == 0 {print $1}' + + echo -e "\nšŸ“ Last 100 Log Lines from PHX Containers:" + for name in $(docker ps -a --format '{{.Names}}' | grep -i 'phoenix\|pgadmin\|postgres'); do + echo -e "\n--- Logs for $name ---" + docker logs --tail=100 "$name" 2>/dev/null || echo "No logs for $name" + done + fi +else + echo -e "\n🐳 ${RED}Docker is not installed or not running.${NC}" +fi + +# Historical CPU/memory usage with 'sar' +if command -v sar &> /dev/null; then + echo -e "\nšŸ“Š Analyzing Memory and CPU Usage via sar (last 60 mins if possible)..." + + echo -e "\nšŸ” Memory Usage (High Usage if >90%):" + sar -r | awk ' + BEGIN { OFS="\t"; print "Time", "%memused", "%commit", "Status" } + /^[0-9]/ { + memused = $4; commit = $8; + status = (memused+0 > 90 || commit+0 > 95) ? "āš ļø HIGH" : "OK"; + printf "%s\t%s%%\t%s%%\t%s\n", $1, memused, commit, status; + }' + + echo -e "\nšŸ” CPU Usage (High if %idle < 10 or %system > 90):" + sar -u | awk ' + BEGIN { OFS="\t"; print "Time", "%user", "%system", "%idle", "Status" } + /^[0-9]/ { + user = $3; sys = $5; idle = $8; + status = (idle+0 < 10 || sys+0 > 90) ? "āš ļø HIGH" : "OK"; + printf "%s\t%s%%\t%s%%\t%s%%\t%s\n", $1, user, sys, idle, status; + }' +else + echo -e "\nā„¹ļø 'sar' (sysstat) is not installed. Skipping historical CPU/memory analysis." +fi + +echo -e "\nāœ… ${YELLOW}Done. Use this script after crashes or schedule it in cron for proactive monitoring.${NC}" \ No newline at end of file diff --git a/docker-compose copy.yaml b/docker-compose copy.yaml old mode 100644 new mode 100755 diff --git a/docker-compose-OLD.yaml b/docker-compose-OLD.yaml old mode 100644 new mode 100755 diff --git a/docker-compose.yaml b/docker-compose.yaml index 8c0e7db..62133c1 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,415 +1,590 @@ ---- -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 +--- +services: + postgres-auto-upgrade: + profiles: + - postgres-upgrade # 🟢 This isolates the service + image: alpine:3.19 + container_name: postgres_auto_upgrade + working_dir: /opt/phx + volumes: + - .:/opt/phx:rw + - /var/run/docker.sock:/var/run/docker.sock + entrypoint: > + sh -c " + apk add --no-cache bash coreutils grep sed findutils curl docker-cli dos2unix && + mkdir -p ~/.docker/cli-plugins && + curl -SL https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose && + chmod +x ~/.docker/cli-plugins/docker-compose && + chmod +x ./postgres_upgrade.sh && + ./postgres_upgrade.sh" + restart: 'no' + depends_on: [] + network_mode: bridge + postgres-auto-rollback: + profiles: + - postgres-rollback # 🟢 This isolates the service + image: alpine:3.19 + container_name: postgres_rollback + working_dir: /opt/phx + volumes: + - .:/opt/phx:rw + - /var/run/docker.sock:/var/run/docker.sock + entrypoint: > + sh -c " + apk add --no-cache bash coreutils grep sed findutils curl docker-cli dos2unix && + mkdir -p ~/.docker/cli-plugins && + curl -SL https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose && + chmod +x ~/.docker/cli-plugins/docker-compose && + chmod +x ./rollback_postgres_upgrade.sh && + ./rollback_postgres_upgrade.sh" + restart: 'no' + depends_on: [] + network_mode: bridge + 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" + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "0.75" # Maximum CPU cores (75% of one core) + # memory: 768M # Maximum memory usage (768 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.25" # Reserved CPU cores (25% of one core) + # memory: 256M # Reserved memory (256 megabytes) + 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:9.6.0 + 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 + mem_limit: 512M + memswap_limit: 512M + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "1.0" # Maximum CPU cores (100% of one core) + memory: 512M # Maximum memory usage (512 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.15" # Reserved CPU cores (15% of one core) + memory: 250M # Reserved memory (250 megabytes) + 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: 120s + 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: + - ./app_custom:/usr/share/nginx/html/assets/custom + # - ./nginx/nginx.conf:/etc/nginx/nginx.conf # Uncomment this if you want to use override the default nginx.conf + # - ./nginx/includes:/etc/nginx/includes:ro # Uncomment this if you want to use override the default includes + networks: + - backend + - frontend + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "0.35" # Maximum CPU cores (35% of one core) + # memory: 384M # Maximum memory usage (384 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.10" # Reserved CPU cores (10% of one core) + # memory: 128M # Reserved memory (128 megabytes) + 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: always + 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=${DB_HOST}" + - "DB_NAME=${DB_NAME}" + - "DB_PASSWORD=${POSTGRES_PASSWORD}" + - "DB_USERNAME=${DB_USERNAME}" + - "SUPER_ADMIN_USER_PASSWORD=${SUPER_ADMIN_USER_PASSWORD}" + - "REDIS_PASSWORD=${REDIS_PASSWORD}" + - NODE_ENV=${NODE_ENV} + - PHX_HOST_NAME=${PHX_HOST_NAME} + - PERFORMANCE_STRUCTURED_LOGGING=${PERFORMANCE_STRUCTURED_LOGGING} + - PERFORMANCE_WARNING_THRESHOLD=${PERFORMANCE_WARNING_THRESHOLD} + - PERFORMANCE_DETAILED_MEMORY=${PERFORMANCE_DETAILED_MEMORY} + 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 + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "1.50" # Maximum CPU cores (150% of one core) + # memory: 1600M # Maximum memory usage (1600 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.50" # Reserved CPU cores (50% of one core) + # memory: 768M # Reserved memory (768 megabytes) + 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: 10s # Max time to wait for each check + retries: 20 # Number of failures before marking as unhealthy + start_period: 60s # Grace period before health checks start + volumes: + - "./assets:/usr/src/app/packages/dev-server/assets" + - "./server_custom:/usr/src/app/packages/dev-server/custom" + # - "./logs:/usr/src/app/packages/dev-server/logs" + phoenix-worker: + restart: always + 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=${DB_HOST}" + - "DB_NAME=${DB_NAME}" + - "DB_PASSWORD=${POSTGRES_PASSWORD}" + - "DB_USERNAME=${DB_USERNAME}" + - "SUPER_ADMIN_USER_PASSWORD=${SUPER_ADMIN_USER_PASSWORD}" + - REDIS_PASSWORD=${REDIS_PASSWORD} + - NODE_ENV=${NODE_ENV} + - PHX_HOST_NAME=${PHX_HOST_NAME} + - PERFORMANCE_STRUCTURED_LOGGING=${PERFORMANCE_STRUCTURED_LOGGING} + - PERFORMANCE_WARNING_THRESHOLD=${PERFORMANCE_WARNING_THRESHOLD} + - PERFORMANCE_DETAILED_MEMORY=${PERFORMANCE_DETAILED_MEMORY} + command: ['npm', 'run', 'start:worker'] + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: '2.0' # Maximum CPU cores (200% of one core) + # memory: 2G # Maximum memory usage (2 gigabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: '0.5' # Reserved CPU cores (50% of one core) + # memory: 512M # Reserved memory (512 megabytes) + 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: + - "./assets:/usr/src/app/packages/dev-server/assets" + - "./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 # Not good, but as agreed. At some point i can start using this: --maxmemory + add eviction policy + 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} + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "0.25" # Maximum CPU cores (25% of one core) + # memory: 100M # Maximum memory usage (100 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.05" # Reserved CPU cores (5% of one core) + # memory: 32M # Reserved memory (32 megabytes) + healthcheck: + test: [ + "CMD-SHELL", + "redis-cli --no-auth-warning -a ${REDIS_PASSWORD} ping | grep PONG && test -w /bitnami/redis/data" + ] + interval: 5s + retries: 10 + timeout: 5s + depends_on: + postgres: + condition: service_healthy + volumes: + - "./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} + REDIS_PASSWORD: ${REDIS_PASSWORD} + 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 + memswap_limit: 512M + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.5" # Maximum CPU cores (50% of one core) + memory: 256M # Maximum memory usage (256 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.1" # Reserved CPU cores (10% of one core) + memory: 64M # Reserved memory (64 megabytes) + 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 + memswap_limit: 512M + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.25" # Maximum CPU cores (25% of one core) + memory: 128M # Maximum memory usage (128 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.05" # Reserved CPU cores (5% of one core) + memory: 32M # Reserved memory (32 megabytes) + depends_on: + phoenix-worker: # This is to avoid alocation of resources to the node-exporter if the phoenix-worker is not healthy yet. + condition: service_healthy + 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://phoenix-app/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 + memswap_limit: 512M + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.5" # Maximum CPU cores (50% of one core) + memory: 256M # Maximum memory usage (256 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.1" # Reserved CPU cores (10% of one core) + memory: 64M # Reserved memory (64 megabytes) + depends_on: + # pgadmin: + # condition: service_healthy + postgres: + condition: service_healthy + fail2ban: + restart: always + 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 + memswap_limit: 512M + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.5" # Maximum CPU cores (50% of one core) + memory: 100M # Maximum memory usage (100 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.1" # Reserved CPU cores (10% of one core) + memory: 35M # Reserved memory (32 megabytes) + depends_on: + phoenix-worker: # This is to avoid alocation of resources to the fail2ban if the phoenix-worker is not healthy yet. + condition: service_healthy + +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 diff --git a/docker-compose.yaml.1923550.2025-07-30@18:08:43~ b/docker-compose.yaml.1923550.2025-07-30@18:08:43~ new file mode 100755 index 0000000..4373b72 --- /dev/null +++ b/docker-compose.yaml.1923550.2025-07-30@18:08:43~ @@ -0,0 +1,583 @@ +--- +services: + postgres-auto-upgrade: + profiles: + - postgres-upgrade # 🟢 This isolates the service + image: alpine:3.19 + container_name: postgres_auto_upgrade + working_dir: /opt/phx + volumes: + - .:/opt/phx:rw + - /var/run/docker.sock:/var/run/docker.sock + entrypoint: > + sh -c " + apk add --no-cache bash coreutils grep sed findutils curl docker-cli dos2unix && + mkdir -p ~/.docker/cli-plugins && + curl -SL https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose && + chmod +x ~/.docker/cli-plugins/docker-compose && + chmod +x ./postgres_upgrade.sh && + ./postgres_upgrade.sh" + restart: 'no' + depends_on: [] + network_mode: bridge + postgres-auto-rollback: + profiles: + - postgres-rollback # 🟢 This isolates the service + image: alpine:3.19 + container_name: postgres_rollback + working_dir: /opt/phx + volumes: + - .:/opt/phx:rw + - /var/run/docker.sock:/var/run/docker.sock + entrypoint: > + sh -c " + apk add --no-cache bash coreutils grep sed findutils curl docker-cli dos2unix && + mkdir -p ~/.docker/cli-plugins && + curl -SL https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose && + chmod +x ~/.docker/cli-plugins/docker-compose && + chmod +x ./rollback_postgres_upgrade.sh && + ./rollback_postgres_upgrade.sh" + restart: 'no' + depends_on: [] + network_mode: bridge + 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" + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "0.75" # Maximum CPU cores (75% of one core) + # memory: 768M # Maximum memory usage (768 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.25" # Reserved CPU cores (25% of one core) + # memory: 256M # Reserved memory (256 megabytes) + 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 + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "1.0" # Maximum CPU cores (100% of one core) + memory: 512M # Maximum memory usage (512 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.15" # Reserved CPU cores (15% of one core) + memory: 128M # Reserved memory (128 megabytes) + 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: 120s + 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: + - ./app_custom:/usr/share/nginx/html/assets/custom + # - ./nginx/nginx.conf:/etc/nginx/nginx.conf # Uncomment this if you want to use override the default nginx.conf + # - ./nginx/includes:/etc/nginx/includes:ro # Uncomment this if you want to use override the default includes + networks: + - backend + - frontend + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "0.35" # Maximum CPU cores (35% of one core) + # memory: 384M # Maximum memory usage (384 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.10" # Reserved CPU cores (10% of one core) + # memory: 128M # Reserved memory (128 megabytes) + 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: always + 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=${DB_HOST}" + - "DB_NAME=${DB_NAME}" + - "DB_PASSWORD=${POSTGRES_PASSWORD}" + - "DB_USERNAME=${DB_USERNAME}" + - "SUPER_ADMIN_USER_PASSWORD=${SUPER_ADMIN_USER_PASSWORD}" + - "REDIS_PASSWORD=${REDIS_PASSWORD}" + - NODE_ENV=${NODE_ENV} + - PHX_HOST_NAME=${PHX_HOST_NAME} + - PERFORMANCE_STRUCTURED_LOGGING=${PERFORMANCE_STRUCTURED_LOGGING} + - PERFORMANCE_WARNING_THRESHOLD=${PERFORMANCE_WARNING_THRESHOLD} + - PERFORMANCE_DETAILED_MEMORY=${PERFORMANCE_DETAILED_MEMORY} + 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 + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "1.50" # Maximum CPU cores (150% of one core) + # memory: 1600M # Maximum memory usage (1600 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.50" # Reserved CPU cores (50% of one core) + # memory: 768M # Reserved memory (768 megabytes) + 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" + - "./server_custom:/usr/src/app/packages/dev-server/custom" + # - "./logs:/usr/src/app/packages/dev-server/logs" + phoenix-worker: + restart: always + 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=${DB_HOST}" + - "DB_NAME=${DB_NAME}" + - "DB_PASSWORD=${POSTGRES_PASSWORD}" + - "DB_USERNAME=${DB_USERNAME}" + - "SUPER_ADMIN_USER_PASSWORD=${SUPER_ADMIN_USER_PASSWORD}" + - REDIS_PASSWORD=${REDIS_PASSWORD} + - NODE_ENV=${NODE_ENV} + - PHX_HOST_NAME=${PHX_HOST_NAME} + - PERFORMANCE_STRUCTURED_LOGGING=${PERFORMANCE_STRUCTURED_LOGGING} + - PERFORMANCE_WARNING_THRESHOLD=${PERFORMANCE_WARNING_THRESHOLD} + - PERFORMANCE_DETAILED_MEMORY=${PERFORMANCE_DETAILED_MEMORY} + command: ['npm', 'run', 'start:worker'] + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: '2.0' # Maximum CPU cores (200% of one core) + # memory: 2G # Maximum memory usage (2 gigabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: '0.5' # Reserved CPU cores (50% of one core) + # memory: 512M # Reserved memory (512 megabytes) + 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: + - "./assets:/usr/src/app/packages/dev-server/assets" + - "./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 # Not good, but as agreed. At some point i can start using this: --maxmemory + add eviction policy + # 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} + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "0.25" # Maximum CPU cores (25% of one core) + # memory: 100M # Maximum memory usage (100 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.05" # Reserved CPU cores (5% of one core) + # memory: 32M # Reserved memory (32 megabytes) + 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: + - type: bind + source: ./redis/data + target: /bitnami/redis/data + bind: + propagation: rshared + 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: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.5" # Maximum CPU cores (50% of one core) + memory: 256M # Maximum memory usage (256 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.1" # Reserved CPU cores (10% of one core) + memory: 64M # Reserved memory (64 megabytes) + 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: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.25" # Maximum CPU cores (25% of one core) + memory: 128M # Maximum memory usage (128 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.05" # Reserved CPU cores (5% of one core) + memory: 32M # Reserved memory (32 megabytes) + depends_on: + phoenix-worker: # This is to avoid alocation of resources to the node-exporter if the phoenix-worker is not healthy yet. + condition: service_healthy + 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://phoenix-app/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 + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.5" # Maximum CPU cores (50% of one core) + memory: 256M # Maximum memory usage (256 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.1" # Reserved CPU cores (10% of one core) + memory: 64M # Reserved memory (64 megabytes) + depends_on: + # pgadmin: + # condition: service_healthy + postgres: + condition: service_healthy + fail2ban: + restart: always + 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 + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.5" # Maximum CPU cores (50% of one core) + memory: 256M # Maximum memory usage (256 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.1" # Reserved CPU cores (10% of one core) + memory: 64M # Reserved memory (64 megabytes) + depends_on: + phoenix-worker: # This is to avoid alocation of resources to the fail2ban if the phoenix-worker is not healthy yet. + condition: service_healthy + +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 diff --git a/docker-compose.yaml.1926319.2025-07-30@18:12:28~ b/docker-compose.yaml.1926319.2025-07-30@18:12:28~ new file mode 100755 index 0000000..88e97e0 --- /dev/null +++ b/docker-compose.yaml.1926319.2025-07-30@18:12:28~ @@ -0,0 +1,580 @@ +--- +services: + postgres-auto-upgrade: + profiles: + - postgres-upgrade # 🟢 This isolates the service + image: alpine:3.19 + container_name: postgres_auto_upgrade + working_dir: /opt/phx + volumes: + - .:/opt/phx:rw + - /var/run/docker.sock:/var/run/docker.sock + entrypoint: > + sh -c " + apk add --no-cache bash coreutils grep sed findutils curl docker-cli dos2unix && + mkdir -p ~/.docker/cli-plugins && + curl -SL https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose && + chmod +x ~/.docker/cli-plugins/docker-compose && + chmod +x ./postgres_upgrade.sh && + ./postgres_upgrade.sh" + restart: 'no' + depends_on: [] + network_mode: bridge + postgres-auto-rollback: + profiles: + - postgres-rollback # 🟢 This isolates the service + image: alpine:3.19 + container_name: postgres_rollback + working_dir: /opt/phx + volumes: + - .:/opt/phx:rw + - /var/run/docker.sock:/var/run/docker.sock + entrypoint: > + sh -c " + apk add --no-cache bash coreutils grep sed findutils curl docker-cli dos2unix && + mkdir -p ~/.docker/cli-plugins && + curl -SL https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose && + chmod +x ~/.docker/cli-plugins/docker-compose && + chmod +x ./rollback_postgres_upgrade.sh && + ./rollback_postgres_upgrade.sh" + restart: 'no' + depends_on: [] + network_mode: bridge + postgres: + restart: always + image: "postgres:17.5-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" + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "0.75" # Maximum CPU cores (75% of one core) + # memory: 768M # Maximum memory usage (768 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.25" # Reserved CPU cores (25% of one core) + # memory: 256M # Reserved memory (256 megabytes) + 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 + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "1.0" # Maximum CPU cores (100% of one core) + memory: 512M # Maximum memory usage (512 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.15" # Reserved CPU cores (15% of one core) + memory: 128M # Reserved memory (128 megabytes) + 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: 120s + 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: + - ./app_custom:/usr/share/nginx/html/assets/custom + # - ./nginx/nginx.conf:/etc/nginx/nginx.conf # Uncomment this if you want to use override the default nginx.conf + # - ./nginx/includes:/etc/nginx/includes:ro # Uncomment this if you want to use override the default includes + networks: + - backend + - frontend + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "0.35" # Maximum CPU cores (35% of one core) + # memory: 384M # Maximum memory usage (384 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.10" # Reserved CPU cores (10% of one core) + # memory: 128M # Reserved memory (128 megabytes) + 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: always + 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=${DB_HOST}" + - "DB_NAME=${DB_NAME}" + - "DB_PASSWORD=${POSTGRES_PASSWORD}" + - "DB_USERNAME=${DB_USERNAME}" + - "SUPER_ADMIN_USER_PASSWORD=${SUPER_ADMIN_USER_PASSWORD}" + - "REDIS_PASSWORD=${REDIS_PASSWORD}" + - NODE_ENV=${NODE_ENV} + - PHX_HOST_NAME=${PHX_HOST_NAME} + - PERFORMANCE_STRUCTURED_LOGGING=${PERFORMANCE_STRUCTURED_LOGGING} + - PERFORMANCE_WARNING_THRESHOLD=${PERFORMANCE_WARNING_THRESHOLD} + - PERFORMANCE_DETAILED_MEMORY=${PERFORMANCE_DETAILED_MEMORY} + 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 + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "1.50" # Maximum CPU cores (150% of one core) + # memory: 1600M # Maximum memory usage (1600 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.50" # Reserved CPU cores (50% of one core) + # memory: 768M # Reserved memory (768 megabytes) + 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: 10s # Max time to wait for each check + retries: 20 # Number of failures before marking as unhealthy + start_period: 60s # Grace period before health checks start + volumes: + - "./assets:/usr/src/app/packages/dev-server/assets" + - "./server_custom:/usr/src/app/packages/dev-server/custom" + # - "./logs:/usr/src/app/packages/dev-server/logs" + phoenix-worker: + restart: always + 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=${DB_HOST}" + - "DB_NAME=${DB_NAME}" + - "DB_PASSWORD=${POSTGRES_PASSWORD}" + - "DB_USERNAME=${DB_USERNAME}" + - "SUPER_ADMIN_USER_PASSWORD=${SUPER_ADMIN_USER_PASSWORD}" + - REDIS_PASSWORD=${REDIS_PASSWORD} + - NODE_ENV=${NODE_ENV} + - PHX_HOST_NAME=${PHX_HOST_NAME} + - PERFORMANCE_STRUCTURED_LOGGING=${PERFORMANCE_STRUCTURED_LOGGING} + - PERFORMANCE_WARNING_THRESHOLD=${PERFORMANCE_WARNING_THRESHOLD} + - PERFORMANCE_DETAILED_MEMORY=${PERFORMANCE_DETAILED_MEMORY} + command: ['npm', 'run', 'start:worker'] + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: '2.0' # Maximum CPU cores (200% of one core) + # memory: 2G # Maximum memory usage (2 gigabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: '0.5' # Reserved CPU cores (50% of one core) + # memory: 512M # Reserved memory (512 megabytes) + 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: + - "./assets:/usr/src/app/packages/dev-server/assets" + - "./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 # Not good, but as agreed. At some point i can start using this: --maxmemory + add eviction policy + 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} + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "0.25" # Maximum CPU cores (25% of one core) + # memory: 100M # Maximum memory usage (100 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.05" # Reserved CPU cores (5% of one core) + # memory: 32M # Reserved memory (32 megabytes) + 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: + - "./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: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.5" # Maximum CPU cores (50% of one core) + memory: 256M # Maximum memory usage (256 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.1" # Reserved CPU cores (10% of one core) + memory: 64M # Reserved memory (64 megabytes) + 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: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.25" # Maximum CPU cores (25% of one core) + memory: 128M # Maximum memory usage (128 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.05" # Reserved CPU cores (5% of one core) + memory: 32M # Reserved memory (32 megabytes) + depends_on: + phoenix-worker: # This is to avoid alocation of resources to the node-exporter if the phoenix-worker is not healthy yet. + condition: service_healthy + 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://phoenix-app/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 + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.5" # Maximum CPU cores (50% of one core) + memory: 256M # Maximum memory usage (256 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.1" # Reserved CPU cores (10% of one core) + memory: 64M # Reserved memory (64 megabytes) + depends_on: + # pgadmin: + # condition: service_healthy + postgres: + condition: service_healthy + fail2ban: + restart: always + 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 + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.5" # Maximum CPU cores (50% of one core) + memory: 256M # Maximum memory usage (256 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.1" # Reserved CPU cores (10% of one core) + memory: 64M # Reserved memory (64 megabytes) + depends_on: + phoenix-worker: # This is to avoid alocation of resources to the fail2ban if the phoenix-worker is not healthy yet. + condition: service_healthy + +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 diff --git a/docker-compose.yaml.3576322.2025-08-03@18:18:45~ b/docker-compose.yaml.3576322.2025-08-03@18:18:45~ new file mode 100755 index 0000000..9cb5ba0 --- /dev/null +++ b/docker-compose.yaml.3576322.2025-08-03@18:18:45~ @@ -0,0 +1,580 @@ +--- +services: + postgres-auto-upgrade: + profiles: + - postgres-upgrade # 🟢 This isolates the service + image: alpine:3.19 + container_name: postgres_auto_upgrade + working_dir: /opt/phx + volumes: + - .:/opt/phx:rw + - /var/run/docker.sock:/var/run/docker.sock + entrypoint: > + sh -c " + apk add --no-cache bash coreutils grep sed findutils curl docker-cli dos2unix && + mkdir -p ~/.docker/cli-plugins && + curl -SL https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose && + chmod +x ~/.docker/cli-plugins/docker-compose && + chmod +x ./postgres_upgrade.sh && + ./postgres_upgrade.sh" + restart: 'no' + depends_on: [] + network_mode: bridge + postgres-auto-rollback: + profiles: + - postgres-rollback # 🟢 This isolates the service + image: alpine:3.19 + container_name: postgres_rollback + working_dir: /opt/phx + volumes: + - .:/opt/phx:rw + - /var/run/docker.sock:/var/run/docker.sock + entrypoint: > + sh -c " + apk add --no-cache bash coreutils grep sed findutils curl docker-cli dos2unix && + mkdir -p ~/.docker/cli-plugins && + curl -SL https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose && + chmod +x ~/.docker/cli-plugins/docker-compose && + chmod +x ./rollback_postgres_upgrade.sh && + ./rollback_postgres_upgrade.sh" + restart: 'no' + depends_on: [] + network_mode: bridge + 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" + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "0.75" # Maximum CPU cores (75% of one core) + # memory: 768M # Maximum memory usage (768 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.25" # Reserved CPU cores (25% of one core) + # memory: 256M # Reserved memory (256 megabytes) + 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 + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "1.0" # Maximum CPU cores (100% of one core) + memory: 512M # Maximum memory usage (512 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.15" # Reserved CPU cores (15% of one core) + memory: 128M # Reserved memory (128 megabytes) + 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: 120s + 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: + - ./app_custom:/usr/share/nginx/html/assets/custom + # - ./nginx/nginx.conf:/etc/nginx/nginx.conf # Uncomment this if you want to use override the default nginx.conf + # - ./nginx/includes:/etc/nginx/includes:ro # Uncomment this if you want to use override the default includes + networks: + - backend + - frontend + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "0.35" # Maximum CPU cores (35% of one core) + # memory: 384M # Maximum memory usage (384 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.10" # Reserved CPU cores (10% of one core) + # memory: 128M # Reserved memory (128 megabytes) + 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: always + 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=${DB_HOST}" + - "DB_NAME=${DB_NAME}" + - "DB_PASSWORD=${POSTGRES_PASSWORD}" + - "DB_USERNAME=${DB_USERNAME}" + - "SUPER_ADMIN_USER_PASSWORD=${SUPER_ADMIN_USER_PASSWORD}" + - "REDIS_PASSWORD=${REDIS_PASSWORD}" + - NODE_ENV=${NODE_ENV} + - PHX_HOST_NAME=${PHX_HOST_NAME} + - PERFORMANCE_STRUCTURED_LOGGING=${PERFORMANCE_STRUCTURED_LOGGING} + - PERFORMANCE_WARNING_THRESHOLD=${PERFORMANCE_WARNING_THRESHOLD} + - PERFORMANCE_DETAILED_MEMORY=${PERFORMANCE_DETAILED_MEMORY} + 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 + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "1.50" # Maximum CPU cores (150% of one core) + # memory: 1600M # Maximum memory usage (1600 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.50" # Reserved CPU cores (50% of one core) + # memory: 768M # Reserved memory (768 megabytes) + 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: 10s # Max time to wait for each check + retries: 20 # Number of failures before marking as unhealthy + start_period: 60s # Grace period before health checks start + volumes: + - "./assets:/usr/src/app/packages/dev-server/assets" + - "./server_custom:/usr/src/app/packages/dev-server/custom" + # - "./logs:/usr/src/app/packages/dev-server/logs" + phoenix-worker: + restart: always + 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=${DB_HOST}" + - "DB_NAME=${DB_NAME}" + - "DB_PASSWORD=${POSTGRES_PASSWORD}" + - "DB_USERNAME=${DB_USERNAME}" + - "SUPER_ADMIN_USER_PASSWORD=${SUPER_ADMIN_USER_PASSWORD}" + - REDIS_PASSWORD=${REDIS_PASSWORD} + - NODE_ENV=${NODE_ENV} + - PHX_HOST_NAME=${PHX_HOST_NAME} + - PERFORMANCE_STRUCTURED_LOGGING=${PERFORMANCE_STRUCTURED_LOGGING} + - PERFORMANCE_WARNING_THRESHOLD=${PERFORMANCE_WARNING_THRESHOLD} + - PERFORMANCE_DETAILED_MEMORY=${PERFORMANCE_DETAILED_MEMORY} + command: ['npm', 'run', 'start:worker'] + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: '2.0' # Maximum CPU cores (200% of one core) + # memory: 2G # Maximum memory usage (2 gigabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: '0.5' # Reserved CPU cores (50% of one core) + # memory: 512M # Reserved memory (512 megabytes) + 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: + - "./assets:/usr/src/app/packages/dev-server/assets" + - "./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 # Not good, but as agreed. At some point i can start using this: --maxmemory + add eviction policy + 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} + # deploy: + # restart_policy: # Define how the service should restart when it fails + # condition: on-failure # Only restart if the container exits with a non-zero code + # delay: 5s # Wait 5 seconds before attempting to restart + # max_attempts: 5 # Maximum number of restart attempts before giving up + # window: 120s # Time window to evaluate restart attempts (resets counter after this period) + # resources: # Resource allocation and limits for the container + # limits: # Maximum resources the container can use + # cpus: "0.25" # Maximum CPU cores (25% of one core) + # memory: 100M # Maximum memory usage (100 megabytes) + # reservations: # Guaranteed minimum resources for the container + # cpus: "0.05" # Reserved CPU cores (5% of one core) + # memory: 32M # Reserved memory (32 megabytes) + 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: + - "./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: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.5" # Maximum CPU cores (50% of one core) + memory: 256M # Maximum memory usage (256 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.1" # Reserved CPU cores (10% of one core) + memory: 64M # Reserved memory (64 megabytes) + 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: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.25" # Maximum CPU cores (25% of one core) + memory: 128M # Maximum memory usage (128 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.05" # Reserved CPU cores (5% of one core) + memory: 32M # Reserved memory (32 megabytes) + depends_on: + phoenix-worker: # This is to avoid alocation of resources to the node-exporter if the phoenix-worker is not healthy yet. + condition: service_healthy + 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://phoenix-app/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 + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.5" # Maximum CPU cores (50% of one core) + memory: 256M # Maximum memory usage (256 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.1" # Reserved CPU cores (10% of one core) + memory: 64M # Reserved memory (64 megabytes) + depends_on: + # pgadmin: + # condition: service_healthy + postgres: + condition: service_healthy + fail2ban: + restart: always + 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 + deploy: + restart_policy: # Define how the service should restart when it fails + condition: on-failure # Only restart if the container exits with a non-zero code + delay: 5s # Wait 5 seconds before attempting to restart + max_attempts: 5 # Maximum number of restart attempts before giving up + window: 120s # Time window to evaluate restart attempts (resets counter after this period) + resources: # Resource allocation and limits for the container + limits: # Maximum resources the container can use + cpus: "0.5" # Maximum CPU cores (50% of one core) + memory: 256M # Maximum memory usage (256 megabytes) + reservations: # Guaranteed minimum resources for the container + cpus: "0.1" # Reserved CPU cores (10% of one core) + memory: 64M # Reserved memory (64 megabytes) + depends_on: + phoenix-worker: # This is to avoid alocation of resources to the fail2ban if the phoenix-worker is not healthy yet. + condition: service_healthy + +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 diff --git a/helper.md b/helper.md old mode 100644 new mode 100755 diff --git a/nginx/includes/pgadmin.conf b/nginx/includes/pgadmin.conf old mode 100644 new mode 100755 diff --git a/nginx/nginx copy 2.conf b/nginx/nginx copy 2.conf old mode 100644 new mode 100755 diff --git a/nginx/nginx copy.conf b/nginx/nginx copy.conf old mode 100644 new mode 100755 diff --git a/nginx/nginx.conf b/nginx/nginx.conf old mode 100644 new mode 100755 diff --git a/phoenix_backup.sql b/phoenix_backup.sql old mode 100644 new mode 100755 diff --git a/redis.conf b/redis.conf old mode 100644 new mode 100755 diff --git a/server_custom/xconfig.ts b/server_custom/deprecated-config.ts old mode 100644 new mode 100755 similarity index 100% rename from server_custom/xconfig.ts rename to server_custom/deprecated-config.ts