核心是nginx作为统一入口,前端走静态服务、api请求反向代理至后端容器;各服务通过自定义网络以服务名通信,proxy_pass须指向backend:8000而非localhost,spa需配置try_files,docker-compose.yml须含networks、volumes及正确依赖关系。

用 Docker Compose 编排 Nginx + 前后端分离项目,核心是把 Nginx 当作统一入口,前端走静态服务,API 请求反向代理到后端容器,所有服务通过一个 docker-compose.yml 协调启动。关键不在单个容器怎么跑,而在服务之间怎么通信、路径怎么映射、配置怎么解耦。
明确各服务职责与网络关系
Nginx 不再是宿主机上的进程,而是独立容器,和 frontend、backend、mysql 处于同一自定义 Docker 网络中。这意味着:
- Nginx 容器可通过服务名(如
backend)直接访问后端容器,无需host.docker.internal或 IP; - 前端构建产物(
dist/)应 COPY 进 Nginx 镜像,或挂载为只读卷; - 后端容器暴露内部端口(如
8000),不映射到宿主机,仅供 Nginx 容器内部调用; - MySQL 使用命名卷持久化数据,避免容器删除后丢失;
Nginx 配置要适配容器内通信
在 nginx/default.conf 中,proxy_pass 必须指向 Compose 中定义的后端服务名和端口,例如:
location /api/ {
proxy_pass http://backend:8000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
注意:
- 不要写
http://localhost:8000或http://127.0.0.1:8000,这在容器内会失败; - 若后端是 FastAPI/Flask,默认监听
0.0.0.0:8000,确保它不绑定127.0.0.1; - 前端路由为 SPA 时,
location /需配try_files $uri $uri/ /index.html;;
docker-compose.yml 关键字段不能漏
一份最小可行编排需包含以下要点:
-
networks:自定义桥接网络(如app-network),所有服务加入; -
volumes:定义命名卷(如mysql-data)用于数据库持久化; -
frontend:构建镜像或直接用 Nginx 镜像 + 挂载dist目录; -
backend:构建后仅暴露内部端口,设depends_on保证 MySQL 先启动; -
nginx:构建时 COPY 配置和静态文件,或运行时挂载default.conf和dist/; -
mysql:设置MYSQL_ROOT_PASSWORD,挂载初始化 SQL(可选),并使用命名卷;
构建与部署流程要闭环
本地验证和生产部署可共用同一套 Compose 文件,只需切换环境变量:
- 前端先执行
npm run build,生成dist/放入frontend/目录; - 后端打包代码(如 Python 的
pip install -e .或 Java 的mvn package)进镜像; - 运行
docker compose up --build -d一次性拉起全部服务; - 检查日志:
docker compose logs nginx、docker compose logs backend; - 访问
http://localhost,确认页面加载且 API 调用返回正确响应头(X-Powered-By或Server: nginx);











