fix(deploy): isolate production web api proxy

This commit is contained in:
Xiaoxia AI
2026-06-22 10:02:03 +08:00
parent 1939878dec
commit 1cf43fa6a0
5 changed files with 44 additions and 1 deletions
+2
View File
@@ -50,6 +50,8 @@ services:
build:
context: ../..
dockerfile: ${WEB_DOCKERFILE:-infra/docker/web.Dockerfile}
args:
NGINX_CONF: ${WEB_NGINX_CONF:-infra/docker/nginx.conf}
container_name: xiaoxia-web-${ENV:-staging}
restart: unless-stopped
ports:
+1
View File
@@ -44,6 +44,7 @@ export DOCKER_BUILDKIT=0
export COMPOSE_DOCKER_CLI_BUILD=0
export COMPOSE_PROJECT_NAME=xiaoxia-production-app
export WEB_DOCKERFILE=infra/docker/web-artifact.Dockerfile
export WEB_NGINX_CONF=infra/docker/nginx-production.conf
docker compose --env-file "$ENV_FILE" build --pull=false api
docker compose --env-file "$ENV_FILE" build --pull=false worker
+28
View File
@@ -0,0 +1,28 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml+rss;
location /api/ {
proxy_pass http://xiaoxia-api-production:8000/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
try_files $uri $uri/ /index.html;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
+2 -1
View File
@@ -1,6 +1,7 @@
FROM docker.m.daocloud.io/library/nginx:alpine AS runner
ARG NGINX_CONF=infra/docker/nginx.conf
WORKDIR /usr/share/nginx/html
COPY apps/web/dist ./
COPY infra/docker/nginx.conf /etc/nginx/conf.d/default.conf
COPY ${NGINX_CONF} /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
+11
View File
@@ -26,6 +26,7 @@ def test_deploy_production_uses_production_infra_and_project():
assert "apps/web/dist/index.html" in script
assert "Production deploy must not build frontend assets on the server" in script
assert "WEB_DOCKERFILE=infra/docker/web-artifact.Dockerfile" in script
assert "WEB_NGINX_CONF=infra/docker/nginx-production.conf" in script
assert "xiaoxia-postgres-production" in script
assert "xiaoxia-redis-production" in script
assert "xiaoxia-postgres\n" not in script
@@ -79,12 +80,22 @@ def test_deploy_scripts_build_web_image_explicitly():
assert "docker compose build --pull=false web" in staging_script
assert "docker compose --env-file \"$ENV_FILE\" build --pull=false web" in production_script
assert "dockerfile: ${WEB_DOCKERFILE:-infra/docker/web.Dockerfile}" in compose
assert "NGINX_CONF: ${WEB_NGINX_CONF:-infra/docker/nginx.conf}" in compose
def test_production_nginx_proxies_to_production_api_container():
config = Path("infra/docker/nginx-production.conf").read_text(encoding="utf-8")
assert "proxy_pass http://xiaoxia-api-production:8000/api/;" in config
assert "proxy_pass http://api:8000/api/;" not in config
def test_web_artifact_dockerfile_does_not_build_frontend_on_server():
dockerfile = Path("infra/docker/web-artifact.Dockerfile").read_text(encoding="utf-8")
assert "COPY apps/web/dist ./" in dockerfile
assert "ARG NGINX_CONF=infra/docker/nginx.conf" in dockerfile
assert "COPY ${NGINX_CONF} /etc/nginx/conf.d/default.conf" in dockerfile
assert "npm" not in dockerfile
assert "node" not in dockerfile.lower()