如何使用Docker、docker-compose和NGINX部署Angular 18 SSR应用?
Angular 18 SSR 部署调整方案
针对你的场景,Angular 18 SSR 需要 Node.js 运行环境(不再是纯静态文件托管),所以要从镜像选择、容器配置到 Nginx 反向代理全流程调整,具体步骤如下:
1. 确认 Angular 项目已启用 SSR
先确保前端项目完成 SSR 初始化:
- 若未启用,执行:
ng add @angular/ssr - 构建 SSR 版本:
ng build --ssr,构建完成后dist目录下会生成{你的项目名}/server(SSR 服务端代码)和{你的项目名}/browser(静态资源)两个子目录
2. 修改前端 Dockerfile(替换 Nginx 镜像为 Node.js)
把原来基于 Nginx 的镜像改成 Node.js,用来运行 SSR 服务:
FROM node:20-alpine WORKDIR /app # 复制构建后的所有文件 COPY dist/ /app/dist/ # 复制 package.json 并安装生产依赖 COPY package*.json ./ RUN npm ci --only=production # 暴露 SSR 服务端口(Angular 默认 SSR 端口为 4000,可自行修改) EXPOSE 4000 # 启动 SSR 服务,注意替换为你的项目名对应的 server 文件路径 CMD ["node", "dist/myapod-fe/server/server.mjs"]
3. 更新 docker-compose.yml 中的前端服务配置
调整前端容器的端口映射,让 Node 服务在容器内部的 4000 端口对外暴露:
myapod-fe: image: myapod-fe container_name: myapod-fe build: context: ./myapod-fe ports: - "4000:4000" # 映射 Node SSR 服务端口 depends_on: - myapod-be
4. 调整 Nginx 配置,反向代理到 SSR 服务
把原来的静态文件托管逻辑改成反向代理,让 Nginx 处理 HTTPS 后转发到 Node SSR 服务:
upstream docker-be { server myapod-be:80 max_conns=200; } # 新增 SSR 服务的上游配置 upstream docker-fe-ssr { server myapod-fe:4000; } server { listen 80; server_name myapod.com; return 301 https://$server_name$request_uri; } server { include /etc/nginx/extra-conf.d/*.conf; listen 443 ssl; server_name myapod.com; # 修改为你的实际域名,而非容器名称 ssl_certificate /etc/nginx/conf.d/certificates/ssl-bundle.crt; ssl_certificate_key /etc/nginx/conf.d/certificates/myapod.key; ssl_session_cache builtin:1000 shared:SSL:10m; ssl_protocols TLSv1.2 TLSv1.3; # 建议只保留现代安全协议 ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; ssl_prefer_server_ciphers on; server_tokens off; charset UTF-8; # GZIP 配置保留 gzip on; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; gzip_proxied any; gzip_comp_level 5; gzip_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/rss+xml text/javascript image/x-icon image/bmp image/svg+xml; gzip_vary on; gzip_min_length 256; # 日志配置保留 access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; reset_timedout_connection on; client_body_timeout 5s; client_header_timeout 5s; client_body_buffer_size 20K; client_header_buffer_size 2k; client_max_body_size 20k; large_client_header_buffers 3 1k; keepalive_timeout 15; send_timeout 10; # 主请求转发到 SSR 服务 location / { proxy_pass http://docker-fe-ssr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; include /etc/nginx/conf.d/security-headers.conf; } # 后端接口转发保留 location /myapod-be/ { proxy_pass http://docker-be; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; } }
5. 重新部署
执行以下命令更新前端服务:
# 重新构建前端镜像 docker-compose build myapod-fe # 重启前端容器 docker-compose up -d myapod-fe
验证部署
- 访问你的域名,检查页面是否正常渲染
- 查看 SSR 服务日志:
docker logs myapod-fe,确认无启动错误 - 查看页面源代码,应该能看到完整的渲染内容(而非只有空的
app-root标签)
内容的提问来源于stack exchange,提问作者Mario Proietti
相关产品推荐
相关产品推荐

