# ====================================================== # STACK POR COMPAÑÍA # - API Node.js # - Web React (Nginx) # - MariaDB # - Integrado con Traefik # ====================================================== services: # --- Base de datos MariaDB --- db: image: mariadb:lts-noble container_name: factuges_${COMPANY}_db restart: unless-stopped environment: MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASS} MARIADB_USER: ${DB_USER} MARIADB_PASSWORD: ${DB_PASS} MARIADB_DATABASE: ${DB_NAME} volumes: - /opt/factuges/${COMPANY}/volumes/db_data:/var/lib/mysql networks: - internal - edge ports: - 3306:3306 healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] interval: 20s timeout: 5s retries: 10 phpmyadmin: image: phpmyadmin/phpmyadmin container_name: factuges_${COMPANY}_phpmyadmin restart: always environment: PMA_HOST: db PMA_USER: ${DB_USER} PMA_PASSWORD: ${DB_PASS} PMA_VERBOSES: "FactuGES Rodax" MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS} UPLOAD_LIMIT: 64M networks: - internal - edge depends_on: - db ports: - 8080:80 labels: traefik.enable: "true" # Router traefik.http.routers.${COMPANY}-phpmyadmin.rule: Host(`${PMA_DOMAIN}`) traefik.http.routers.${COMPANY}-phpmyadmin.entrypoints: websecure traefik.http.routers.${COMPANY}-phpmyadmin.tls.certresolver: cfresolver # Servicio traefik.http.services.${COMPANY}-phpmyadmin.loadbalancer.server.port: "80" # Middleware: whitelist por IP traefik.http.routers.${COMPANY}-phpmyadmin.middlewares: "${COMPANY}-phpmyadmin-ipwhitelist@docker" traefik.http.middlewares.${COMPANY}-phpmyadmin-ipwhitelist.ipwhitelist.sourcerange: "79.116.183.41/32" # --- API (imagen versionada generada por build-factuges.sh) --- api: image: ${API_IMAGE} container_name: factuges_${COMPANY}_api restart: unless-stopped depends_on: db: condition: service_healthy environment: NODE_ENV: production COMPANY: ${COMPANY} PORT: ${API_PORT:-3002} DB_DIALECT: "mysql" DB_HOST: "db" DB_PORT: ${DB_PORT} DB_NAME: ${DB_NAME} DB_USER: ${DB_USER} DB_PASSWORD: ${DB_PASS} FRONTEND_URL: ${FRONTEND_URL} networks: - internal - edge ports: - ${API_PORT:-3002}:${API_PORT:-3002} labels: traefik.enable: "true" # Router traefik.http.routers.${COMPANY}-api.rule: Host(`${API_DOMAIN}`) traefik.http.routers.${COMPANY}-api.entrypoints: websecure traefik.http.routers.${COMPANY}-api.tls.certresolver: cfresolver # Servicio traefik.http.services.${COMPANY}-api.loadbalancer.server.port: "${API_PORT:-3002}" # --- Web estática (React compilado por build-factuges.sh) --- web: container_name: caddy image: caddy:alpine volumes: - /opt/factuges/${COMPANY}/Caddyfile:/etc/caddy/Caddyfile # Monta el archivo de configuración - caddy_data:/data # Almacena los certificados en este volumen - caddy_config:/config # Configuración de Caddy - /opt/factuges/${COMPANY}/web/latest/dist/:/srv ports: - 81:80 # Puerto HTTP (Caddy lo redirige automáticamente a HTTPS) - 444:443 # Puerto HTTPS - 13001:13001 # reverse proxy al backend networks: - internal - edge restart: on-failure depends_on: - api labels: traefik.enable: "true" traefik.http.routers.factuges_rodax_web.rule: Host(`${DOMAIN}`) traefik.http.routers.factuges_rodax_web.entrypoints: web traefik.http.services.factuges_rodax_web.loadbalancer.server.port: "444" networks: edge: external: true # red pública manejada por Traefik internal: driver: bridge # red privada de la compañía volumes: db_data: caddy_data: caddy_config: