From 401292539b19761c809e459751d2092075030a6b Mon Sep 17 00:00:00 2001 From: david Date: Mon, 15 Dec 2025 19:00:34 +0100 Subject: [PATCH] =?UTF-8?q?Scripts=20para=20puesta=20en=20producci=C3=B3n?= =?UTF-8?q?=20para=20Rodax?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/stacks/rodax/docker-compose.yml | 192 ++++++++++++++++++ scripts/stacks/rodax/env.rodax | 0 scripts/stacks/rodax/nginx.conf | 16 ++ .../rodax/traefik/dynamic/certificates.yml | 7 + .../rodax/traefik/dynamic/dashboard.yml | 16 ++ scripts/stacks/rodax/traefik/traefik.yml | 38 ++++ 6 files changed, 269 insertions(+) create mode 100644 scripts/stacks/rodax/docker-compose.yml create mode 100644 scripts/stacks/rodax/env.rodax create mode 100644 scripts/stacks/rodax/nginx.conf create mode 100644 scripts/stacks/rodax/traefik/dynamic/certificates.yml create mode 100644 scripts/stacks/rodax/traefik/dynamic/dashboard.yml create mode 100644 scripts/stacks/rodax/traefik/traefik.yml diff --git a/scripts/stacks/rodax/docker-compose.yml b/scripts/stacks/rodax/docker-compose.yml new file mode 100644 index 00000000..c1fd9e48 --- /dev/null +++ b/scripts/stacks/rodax/docker-compose.yml @@ -0,0 +1,192 @@ +name: factuges-rodax + +services: + # --- Base de datos MariaDB --- + db: + image: mariadb:lts-noble + container_name: factuges_rodax_db + restart: unless-stopped + environment: + MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASS} + MARIADB_USER: ${DB_USER} + MARIADB_PASSWORD: ${DB_PASS} + MARIADB_DATABASE: ${DB_NAME} + volumes: + - ./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_rodax_phpmyadmin + restart: unless-stopped + environment: + PMA_ARBITRARY: 1 + PMA_ABSOLUTE_URI: https://factuges.rodax-software.local/phpmyadmin/ + PMA_HOST: db + PMA_USER: ${DB_USER} + PMA_PASSWORD: ${DB_PASS} + PMA_VERBOSES: "FactuGES Rodax" + MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS} + UPLOAD_LIMIT: 64M + depends_on: + db: + condition: service_healthy + networks: + - internal + - edge + ports: + - "8080:8080" + labels: + traefik.enable: "true" + + # /phpmyadmin → phpMyAdmin + traefik.http.routers.factuges_rodax_phpmyadmin.rule: "Host(`factuges.rodax-software.local`) && PathPrefix(`/phpmyadmin/`)" + traefik.http.routers.factuges_rodax_phpmyadmin.entrypoints: "websecure" + traefik.http.routers.factuges_rodax_phpmyadmin.tls: "true" + traefik.http.routers.factuges_rodax_phpmyadmin.priority: "110" + traefik.http.routers.factuges_rodax_phpmyadmin.service: "factuges_rodax_phpmyadmin" + traefik.http.services.factuges_rodax_phpmyadmin.loadbalancer.server.port: "80" + + # strip /phpmyadmin del path antes de llegar al contenedor + traefik.http.middlewares.factuges_rodax_phpmyadmin_strip.stripprefix.prefixes: "/phpmyadmin/" + + # whitelist a tu IP + #traefik.http.middlewares.factuges_rodax_phpmyadmin_ipwhitelist.ipwhitelist.sourcerange: "192.168.0.0/24" + + # encadenar middlewares + traefik.http.routers.factuges_rodax_phpmyadmin.middlewares: "factuges_rodax_phpmyadmin_strip" + + + # --- API (imagen versionada generada por build-api.sh) --- + api: + image: ${API_IMAGE} + container_name: factuges_rodax_api + restart: unless-stopped + depends_on: + db: + condition: service_healthy + environment: + NODE_ENV: production + COMPANY: rodax + PORT: ${SERVER_PORT:-3002} + DB_DIALECT: "mysql" + DB_HOST: "db" + DB_PORT: ${DB_PORT} + DB_NAME: ${DB_NAME} + DB_USER: ${DB_USER} + DB_PASS: ${DB_PASS} + FRONTEND_URL: ${FRONTEND_URL} + TEMPLATES_PATH: ${TEMPLATES_PATH} + volumes: + - ./templates:/repo/apps/server/templates:ro + networks: + - internal + - edge + labels: + traefik.enable: "true" + + # /api → backend + traefik.http.routers.factuges_rodax_api.rule: "Host(`factuges.rodax-software.local`) && PathPrefix(`/api`)" + traefik.http.routers.factuges_rodax_api.entrypoints: "websecure" + traefik.http.routers.factuges_rodax_api.tls: "true" + + traefik.http.routers.factuges_rodax_api.priority: "100" + traefik.http.routers.factuges_rodax_api.service: "factuges_rodax_api" + + # Servicio + traefik.http.services.factuges_rodax_api.loadbalancer.server.port: "${API_PORT:-3002}" + + # --- Web estática (React compilado) --- + web: + image: nginx:alpine + container_name: factuges_rodax_web + restart: unless-stopped + depends_on: + - api + environment: + VITE_API_SERVER_URL: https://factuges.rodax-software.local/api/v1 + volumes: + # Build de Vite (en el host) -> Nginx + - ./web/latest/dist:/usr/share/nginx/html:ro + # Config de Nginx con try_files para SPA + - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro + networks: + - edge + labels: + traefik.enable: "true" + + # Router HTTPS + traefik.http.routers.factuges_rodax_web.rule: "Host(`factuges.rodax-software.local`)" + traefik.http.routers.factuges_rodax_web.entrypoints: "websecure" + traefik.http.routers.factuges_rodax_web.tls: "true" + + # Servicio + traefik.http.services.factuges_rodax_web.loadbalancer.server.port: "80" + + + factuges_sync: + image: "factuges-sync:rodax-latest" + container_name: "factuges_rodax_sync" + restart: "no" + environment: + ENV: "production" + LOCAL_TZ: "Europe/Madrid" + STATE_PATH: "${STATE_PATH}" + + FACTUGES_HOST: "${FACTUGES_HOST}" + FACTUGES_PORT: "${FACTUGES_PORT}" + FACTUGES_DATABASE: "${FACTUGES_DATABASE}" + FACTUGES_USER: "${FACTUGES_USER}" + FACTUGES_PASSWORD: "${FACTUGES_PASSWORD}" + + FWEB_MYSQL_HOST: "db" + FWEB_MYSQL_PORT: "${DB_PORT}" + FWEB_MYSQL_DATABASE: "${DB_NAME}" + FWEB_MYSQL_USER: "${DB_USER}" + FWEB_MYSQL_PASSWORD: "${DB_PASS}" + + CTE_COMPANY_ID: "${CTE_COMPANY_ID}" + CTE_SERIE: "${CTE_SERIE}" + CTE_STATUS_INVOICE: "${CTE_STATUS_INVOICE}" + CTE_IS_PROFORMA: "${CTE_IS_PROFORMA}" + CTE_STATUS_VERIFACTU: "${CTE_STATUS_VERIFACTU}" + CTE_LANGUAGE_CODE: "${CTE_LANGUAGE_CODE}" + CTE_COUNTRY_CODE: "${CTE_COUNTRY_CODE}" + CTE_IS_COMPANY: "${CTE_IS_COMPANY}" + CTE_SYNC_RESULT_OK: "${CTE_SYNC_RESULT_OK}" + CTE_SYNC_RESULT_FAIL: "${CTE_SYNC_RESULT_FAIL}" + + VERIFACTU_API_KEY: "${VERIFACTU_API_KEY}" + VERIFACTU_BASE_URL: "${VERIFACTU_BASE_URL}" + VERIFACTU_NIFS_API_KEY: "${VERIFACTU_NIFS_API_KEY}" + depends_on: + db: + condition: service_healthy + networks: + - internal + - edge + volumes: + - ./volumes/db_sync:/app/rodax + + +networks: + edge: + name: edge + external: true + internal: + name: factuges_rodax_internal + external: false + + +volumes: + # Solo declarativo; usamos ruta ./volumes/db_data arriba + db_data: diff --git a/scripts/stacks/rodax/env.rodax b/scripts/stacks/rodax/env.rodax new file mode 100644 index 00000000..e69de29b diff --git a/scripts/stacks/rodax/nginx.conf b/scripts/stacks/rodax/nginx.conf new file mode 100644 index 00000000..40b2a42e --- /dev/null +++ b/scripts/stacks/rodax/nginx.conf @@ -0,0 +1,16 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + location /assets/ { + expires 1h; + add_header Cache-Control "public, immutable"; + } +} diff --git a/scripts/stacks/rodax/traefik/dynamic/certificates.yml b/scripts/stacks/rodax/traefik/dynamic/certificates.yml new file mode 100644 index 00000000..cf553f6c --- /dev/null +++ b/scripts/stacks/rodax/traefik/dynamic/certificates.yml @@ -0,0 +1,7 @@ +tls: + stores: + default: + defaultCertificate: + certFile: "/etc/traefik/certs/factuges-local.crt" + keyFile: "/etc/traefik/certs/factuges-local.key" + diff --git a/scripts/stacks/rodax/traefik/dynamic/dashboard.yml b/scripts/stacks/rodax/traefik/dynamic/dashboard.yml new file mode 100644 index 00000000..58408b36 --- /dev/null +++ b/scripts/stacks/rodax/traefik/dynamic/dashboard.yml @@ -0,0 +1,16 @@ +http: + middlewares: + dashboard-auth: + basicAuth: + users: + - "admin:$apr1$cfPd6Z11$bS8dOI/CxBOAmg3e5jIGJ/" + + routers: + dashboard: + rule: "Host(`traefik.factuges.rodax-software.local`)" + entryPoints: + - websecure + service: api@internal + middlewares: + - dashboard-auth + tls: {} diff --git a/scripts/stacks/rodax/traefik/traefik.yml b/scripts/stacks/rodax/traefik/traefik.yml new file mode 100644 index 00000000..99a518db --- /dev/null +++ b/scripts/stacks/rodax/traefik/traefik.yml @@ -0,0 +1,38 @@ +global: + checkNewVersion: false + sendAnonymousUsage: false + +entryPoints: + web: + address: ":80" + http: + redirections: + entryPoint: + to: websecure + scheme: https + + websecure: + address: ":443" + +api: + dashboard: true + insecure: false + + +providers: + file: + directory: "/etc/traefik/dynamic" + watch: true + + docker: + endpoint: "unix:///var/run/docker.sock" + watch: true + exposedByDefault: false + #useBindPortIP: true + +log: + level: INFO + format: json + filePath: "/var/log/traefik/traefik.log" + +accessLog: {}