Python3+Flask+PostgreSQL18+Vue3项目生产环境用docker如何部署?

生产环境用 Docker 部署 Vue3 + Flask + PostgreSQL 18,最稳妥的方式是使用 Docker Compose 编排三个服务:Nginx(托管 Vue 静态文件并反向代理 API)、Gunicorn(运行 Flask)、PostgreSQL 18。核心要点是:前端构建产物交给 Nginx,API 请求通过 Docker 内部 DNS 转发到 Flask 容器,数据库使用命名卷持久化。

一、项目结构建议

复制代码
project/
├── docker-compose.prod.yml
├── backend/
│   ├── Dockerfile
│   ├── requirements.txt
│   └── app.py (或你的 Flask 入口)
├── frontend/
│   ├── Dockerfile
│   ├── nginx.conf
│   └── (Vue 项目源码)
└── ssl/ (如需 HTTPS)
    ├── nginx.crt
    └── nginx.key

二、后端 Flask Dockerfile

生产环境不使用 flask run,而应使用 Gunicorn。

复制代码
# backend/Dockerfile
FROM python:3.12-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt gunicorn

COPY . .

EXPOSE 8000
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8000", "app:app"]

三、前端 Vue3 Dockerfile(多阶段构建)

在构建阶段用 Node 生成 dist,运行阶段用 Nginx 托管。

复制代码
# frontend/Dockerfile
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

四、Nginx 配置(关键:SPA 路由与 API 代理)

这是最容易出错的地方。必须用 location ^~ /api/ 优先匹配 API 请求,其余请求全部 fallback 到 index.html,否则 Vue Router 的页面刷新会 404。

复制代码
# frontend/nginx.conf
server {
    listen 80;
    server_name _;
    root /usr/share/nginx/html;
    index index.html;

    # API 请求转发给 Flask 容器(backend 是 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;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Vue SPA 路由 fallback
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 静态资源缓存(文件名带 hash 时可长缓存)
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}

五、docker-compose.prod.yml

复制代码
services:
  db:
    image: postgres:18
    container_name: prod_db
    restart: always
    environment:
      POSTGRES_USER: prod_user
      POSTGRES_PASSWORD: ${DB_PASSWORD}  # 建议用 .env 文件管理
      POSTGRES_DB: prod_dbname
    volumes:
      - pgdata_prod:/var/lib/postgresql/data
    # 生产环境不对外暴露 5432 端口,仅容器内部访问

  backend:
    build: ./backend
    container_name: prod_backend
    restart: always
    environment:
      DATABASE_URL: postgresql://prod_user:${DB_PASSWORD}@db:5432/prod_dbname
    depends_on:
      - db
    expose:
      - "8000"
    # 注意:depends_on 只保证启动顺序,不保证数据库已就绪
    # Flask 应用需有数据库连接重试逻辑

  frontend:
    build: ./frontend
    container_name: prod_frontend
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      # 如需 HTTPS,挂载证书
      - ./ssl/nginx.crt:/etc/nginx/ssl/nginx.crt:ro
      - ./ssl/nginx.key:/etc/nginx/ssl/nginx.key:ro
    depends_on:
      - backend

volumes:
  pgdata_prod:

六、关键注意事项

数据库初始化:PostgreSQL 官方镜像仅在数据目录首次为空时执行 /docker-entrypoint-initdb.d/ 下的脚本。如果已有数据卷,再修改 POSTGRES_PASSWORD 环境变量不会生效,需要进入容器手动改密码或删除卷重建。

服务间通信:Flask 连接数据库时,DATABASE_URL 中的主机名必须是 Compose 服务名 db,而不是 localhost 或 127.0.0.1。同理,Nginx 的 proxy_pass 写 http://backend:8000。

Gunicorn 监听地址:必须绑定 0.0.0.0,不能是 127.0.0.1,否则 Nginx 无法从容器外部访问到 Flask。

Vue 的 API 基地址:前端代码中请求 API 的 base URL 应设为 /api(相对路径),这样生产环境走 Nginx 代理,开发环境可走 Vite 代理。不要在代码里写死 http://backend:8000,那是容器内部地址,浏览器无法解析。

HTTPS 配置:上述 Nginx 配置只监听了 80。如需启用 443,在 frontend/nginx.conf 中增加 listen 443 ssl; 并配置 ssl_certificate 路径指向挂载的证书。

七、部署命令

复制代码
# 启动
docker compose -f docker-compose.prod.yml up -d --build

# 查看日志
docker compose -f docker-compose.prod.yml logs -f backend

# 停止(保留数据)
docker compose -f docker-compose.prod.yml down

如果部署后出现 502,优先检查 Flask 容器是否正常运行、Gunicorn 是否绑定 0.0.0.0;出现 404,检查 Nginx 的 try_files 是否指向了正确的 index.html 路径。

相关推荐
特立独行的猫A28 分钟前
少 3 个环节、少 1 次 ABI、少 3500 行代码:cj-tauri 与 Ionic/Capacitor 的鸿蒙桥接机制对比
java·后端·python
特立独行的猫A1 小时前
cj-tauri vs Rust/Tauri 同款播放器实测:编译 21 秒 vs 11 分钟,磁盘 12 MB vs 1.2 GB
java·后端·python
duansamve1 小时前
详解Flask中Session和Cookie
python·flask
威哥爱编程2 小时前
模拟面试智能体开发实战 04:面试聊到哪算哪?用状态机把整场面试编排起来
python·agent·harmonyos
威哥爱编程2 小时前
模拟面试智能体开发实战 03:AI 面试官太客气?人设 Prompt 让它像个真考官
python·agent·harmonyos
量化分析码农2 小时前
股票数据接口返回字段逐项解析:从在线验证到 Python 数据校验
python
Dmz丶3 小时前
前端转 AI 100 天 Day 42:跨模型对比实战——用数据选模型,不靠“听说”
python
路溪非溪3 小时前
python标准库使用总结
开发语言·python
青少儿编程课堂4 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:折半搜索优化子集枚举(Meet in the Middle)解析
c++·python·算法·bfs·信息学竞赛