You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:用Nginx部署Docker化React+Django应用的静态文件与反向代理

问题描述

我有一个Docker化的React前端+Django后端应用,想用Nginx作为Web服务器,同时托管React和Django的静态文件,并反向代理用户请求到Gunicorn运行的Django后端。但Nginx静态文件服务的配置一直无法正常工作,已经折腾了近4个月,恳请帮忙排查。

相关配置文件

Nginx Dockerfile

FROM node:18.16-alpine as build

WORKDIR /app/frontend/

COPY ../frontend/package*.json  ./

COPY ../frontend ./

RUN npm install

RUN npm run build


# production environment
FROM nginx

COPY  ./nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/frontend/build /usr/share/nginx/html

docker-compose.yml

version: '3.9'

services:
  db:
    image: mysql:8.0
    ports:
      - '3307:3306'
    restart: unless-stopped
    env_file:
      - ./backend/.env
    volumes:
      - mysql-data:/var/lib/mysql
  backend:
    image: vinmartech-backend:latest 
    restart: always
    build: 
      context: ./backend
      dockerfile: ./Dockerfile  
    ports:
      - "8000:8000"
    volumes:
      - static:/app/backend/static/

    env_file:
      - ./backend/.env
    depends_on:
      - db
  
  nginx:
    build:
      context: .
      dockerfile: ./nginx/Dockerfile
    ports:
      - "80:80"
    volumes:
      -  static:/app/backend/static/
    restart: always
    depends_on:
      - backend
      # - frontend

volumes:
  mysql-data: 
  static:

Nginx配置文件(default.conf)

upstream mybackend {
    server backend:8000;
}

server {
    listen 80;

    location /letter/s {
        proxy_pass http://backend;
    }  

    location /contact/ {
        proxy_pass http://backend;
    }  


    location /admin/ {
        alias /static/;
    }      

    location /static/ {
        alias /static/;
    }

    location / {
      root /usr/share/nginx/html;
      try_files $uri $uri/ /index.html;
    }

}

Django静态文件配置

STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

问题排查与修复方案

1. 修正Nginx静态文件路径映射

Nginx容器中静态卷的实际挂载路径是/app/backend/static/,但原配置里的alias /static/指向容器根目录下的不存在路径,导致静态文件无法加载。

修改Nginx的/static/ location:

location /static/ {
    alias /app/backend/static/;
    # 添加缓存优化规则
    expires 30d;
    add_header Cache-Control "public, immutable";
}

2. 修复Admin路径配置

原配置中location /admin/用alias指向静态目录完全错误——Admin是Django的后端视图,需要代理到Django服务;而Admin的静态文件会被自动收集到/static/admin/,由上面的/static/规则处理。

替换原/admin/ location为代理配置:

location /admin/ {
    proxy_pass http://mybackend/admin/;
    # 必须添加这些请求头,避免Django识别请求异常
    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;
}

3. 统一代理路径的斜杠规则

原配置中location /letter/s无结尾斜杠,配合proxy_pass http://backend会导致路径拼接异常(比如请求/letter/s/1会被转发到http://backend/letter/s1)。

修改代理location的路径与转发规则:

location /letter/s/ {
    proxy_pass http://mybackend/;
    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 /contact/ {
    proxy_pass http://mybackend/;
    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;
}

4. 确认Django静态文件已收集

确保后端Dockerfile中执行了collectstatic命令,将静态文件同步到STATIC_ROOT(即挂载的静态卷路径):

在后端Dockerfile中添加:

# 需放在依赖安装完成后、服务启动前
RUN python manage.py collectstatic --noinput

5. 启用已定义的upstream

原配置中定义了upstream mybackend但未使用,建议统一用http://mybackend代替http://backend,方便后续扩展多后端实例。


内容的提问来源于stack exchange,提问作者Alphonse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 12:50:59