diff --git a/deploy.sh b/deploy.sh index 941dc9f..904203d 100755 --- a/deploy.sh +++ b/deploy.sh @@ -11,9 +11,7 @@ PROJECT_DIR="/opt/03-business/Axil" COMPOSE_FILE="$PROJECT_DIR/docker-compose.prod.yml" ENV_FILE="$PROJECT_DIR/.env.production" DEPLOY_CONFIG="$PROJECT_DIR/.deploy-config" -NGINX_SITE="axil-accountants" -NGINX_CONF="/etc/nginx/sites-available/$NGINX_SITE" -NGINX_ENABLED="/etc/nginx/sites-enabled/$NGINX_SITE" +# Routing: Traefik (traefik-public network) — no nginx needed # ─── Colors ─────────────────────────────────────────────────────────────────── GREEN='\033[0;32m' @@ -273,75 +271,20 @@ run_migrations() { } # ============================================================================= -# Phase 6 — Nginx setup (first run only) +# Phase 6 — Traefik registration (automatic via Docker labels) # ============================================================================= setup_nginx() { - header "Phase 6 — Nginx setup" + header "Phase 6 — Traefik routing" # Load domain from deploy config - if [ ! -f "$DEPLOY_CONFIG" ]; then - warn "Deploy config not found at $DEPLOY_CONFIG — skipping Nginx setup." - return - fi - # shellcheck disable=SC1090 - source "$DEPLOY_CONFIG" - - if [ -f "$NGINX_CONF" ]; then - log "Nginx config already exists at $NGINX_CONF — skipping creation." - else - log "Writing Nginx config for ${DOMAIN}..." - cat > "$NGINX_CONF" </dev/null | grep -q "Domains.*${DOMAIN}"; then - log "SSL certificate for ${DOMAIN} already exists — skipping Certbot." - else - log "Obtaining SSL certificate for ${DOMAIN} (and www.${DOMAIN})..." - certbot --nginx \ - -d "${DOMAIN}" \ - -d "www.${DOMAIN}" \ - --non-interactive \ - --agree-tos \ - -m "${ADMIN_EMAIL}" \ - --redirect - log "SSL certificate obtained. HTTP → HTTPS redirect enabled." - fi + log "Routing handled by Traefik via Docker labels." + log "SSL certificate will be issued automatically via Cloudflare DNS resolver." + info "Route: https://${DOMAIN:-axil.ai-impress.com} → axil-app-1:3000" } # ============================================================================= diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index fc0e82f..8a978fe 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -4,8 +4,17 @@ services: context: . target: runner restart: always - ports: - - '127.0.0.1:3000:3000' + networks: + - traefik-public + - internal + labels: + - "traefik.enable=true" + - "traefik.http.routers.axil.entrypoints=websecure" + - "traefik.http.routers.axil.rule=Host(`axil.ai-impress.com`)" + - "traefik.http.routers.axil.tls.certresolver=cloudflare" + - "traefik.http.routers.axil.middlewares=security-headers@file" + - "traefik.http.services.axil.loadbalancer.server.port=3000" + - "traefik.docker.network=traefik-public" env_file: - .env.production depends_on: @@ -15,6 +24,8 @@ services: db: image: postgres:17-alpine restart: always + networks: + - internal environment: POSTGRES_USER: ${DB_USER:-axil} POSTGRES_PASSWORD: ${DB_PASSWORD} @@ -27,5 +38,11 @@ services: timeout: 5s retries: 10 +networks: + traefik-public: + external: true + internal: + driver: bridge + volumes: pgdata: