fix(deploy): isolate production web api proxy
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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;"]
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user