如何用Python全栈框架容器化部署到生产环境

wen 全栈框架 3

本文目录导读:

  1. 项目结构
  2. 后端Dockerfile
  3. 前端Dockerfile
  4. Nginx反向代理
  5. Docker Compose配置
  6. 环境变量配置
  7. Django生产配置
  8. 部署步骤
  9. 生产环境优化
  10. CI/CD集成(GitHub Actions)
  11. 性能优化建议

我来详细介绍Python全栈框架的容器化部署方案,以Django + Vue + PostgreSQL为例。

项目结构

myapp/
├── backend/
│   ├── Dockerfile
│   ├── requirements.txt
│   ├── manage.py
│   └── myapp/
├── frontend/
│   ├── Dockerfile
│   ├── package.json
│   └── src/
├── nginx/
│   ├── Dockerfile
│   └── nginx.conf
├── docker-compose.yml
└── .env

后端Dockerfile

# backend/Dockerfile
FROM python:3.11-slim
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    gcc \
    libpq-dev \
    && rm -rf /var/lib/apt/lists/*
WORKDIR /app
# 安装依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制项目文件
COPY . .
# 收集静态文件
RUN python manage.py collectstatic --noinput
# 使用gunicorn启动
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "myapp.wsgi:application"]
# backend/requirements.txt
Django==4.2.7
gunicorn==21.2.0
djangorestframework==3.14.0
django-cors-headers==4.3.1
psycopg2-binary==2.9.9
whitenoise==6.6.0

前端Dockerfile

# frontend/Dockerfile
FROM node:18-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 生产环境 - 使用nginx
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
# frontend/nginx.conf
server {
    listen 80;
    server_name _;
    location / {
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
    }
    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;
    }
    location /static/ {
        alias /usr/share/nginx/html/static/;
    }
}

Nginx反向代理

# nginx/nginx.conf
upstream backend {
    server backend:8000;
}
upstream frontend {
    server frontend:80;
}
server {
    listen 80;
    server_name your-domain.com;
    # 前端静态文件
    location / {
        proxy_pass http://frontend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
    # API请求
    location /api/ {
        proxy_pass http://backend;
        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 /static/ {
        alias /static/;
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }
    # 媒体文件
    location /media/ {
        alias /media/;
        expires 30d;
    }
}

Docker Compose配置

# docker-compose.yml
version: '3.8'
services:
  db:
    image: postgres:15
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped
    networks:
      - app-network
  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    restart: unless-stopped
    networks:
      - app-network
  backend:
    build: ./backend
    environment:
      DJANGO_SETTINGS_MODULE: myapp.production_settings
      DB_HOST: db
      DB_PORT: 5432
      DB_NAME: ${DB_NAME}
      DB_USER: ${DB_USER}
      DB_PASSWORD: ${DB_PASSWORD}
      REDIS_URL: redis://redis:6379/0
      SECRET_KEY: ${DJANGO_SECRET_KEY}
      DEBUG: 'False'
    volumes:
      - static_volume:/app/staticfiles
      - media_volume:/app/media
    depends_on:
      - db
      - redis
    restart: unless-stopped
    networks:
      - app-network
  frontend:
    build: ./frontend
    volumes:
      - frontend_dist:/usr/share/nginx/html
    restart: unless-stopped
    networks:
      - app-network
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - static_volume:/static
      - media_volume:/media
    depends_on:
      - backend
      - frontend
    restart: unless-stopped
    networks:
      - app-network
volumes:
  postgres_data:
  redis_data:
  static_volume:
  media_volume:
  frontend_dist:
networks:
  app-network:
    driver: bridge

环境变量配置

# .env
DB_NAME=myapp_db
DB_USER=myapp_user
DB_PASSWORD=your_secure_password_here
DJANGO_SECRET_KEY=your-secret-key-here

Django生产配置

# backend/myapp/production_settings.py
from .settings import *
DEBUG = False
ALLOWED_HOSTS = ['your-domain.com', 'localhost']
# 数据库配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('DB_NAME'),
        'USER': os.environ.get('DB_USER'),
        'PASSWORD': os.environ.get('DB_PASSWORD'),
        'HOST': os.environ.get('DB_HOST', 'db'),
        'PORT': os.environ.get('DB_PORT', '5432'),
    }
}
# 静态文件
STATIC_ROOT = '/app/staticfiles'
STATIC_URL = '/static/'
# 媒体文件
MEDIA_ROOT = '/app/media'
MEDIA_URL = '/media/'
# 安全配置
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True

部署步骤

# 1. 克隆项目
git clone https://github.com/yourusername/myapp.git
cd myapp
# 2. 创建环境变量文件
cp .env.example .env
# 编辑.env文件,填入实际值
# 3. 构建并启动容器
docker-compose build
docker-compose up -d
# 4. 执行数据库迁移
docker-compose exec backend python manage.py migrate
# 5. 创建超级用户
docker-compose exec backend python manage.py createsuperuser
# 6. 收集静态文件
docker-compose exec backend python manage.py collectstatic --noinput
# 7. 查看日志
docker-compose logs -f
# 8. 停止服务
docker-compose down

生产环境优化

# docker-compose.prod.yml
version: '3.8'
services:
  # ... 其他服务配置
  nginx:
    image: nginx:alpine
    ports:
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
      - static_volume:/static
      - media_volume:/media
    environment:
      - NGINX_HOST=your-domain.com
    restart: always
  # 使用HPA自动扩缩容(Kubernetes环境下)
  backend:
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

CI/CD集成(GitHub Actions)

# .github/workflows/deploy.yml
name: Deploy to Production
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Build and push Docker images
      run: |
        docker build -t myapp-backend:latest ./backend
        docker build -t myapp-frontend:latest ./frontend
        docker tag myapp-backend:latest registry.example.com/myapp-backend:latest
        docker push registry.example.com/myapp-backend:latest
    - name: Deploy to server
      uses: appleboy/ssh-action@v0.1.5
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.SSH_KEY }}
        script: |
          cd /opt/myapp
          docker-compose pull
          docker-compose up -d --force-recreate

性能优化建议

  1. 数据库连接池:使用PgBouncer连接池
  2. 缓存策略:前后端分离时使用Redis缓存
  3. CDN加速:静态资源使用CDN
  4. 日志管理:使用ELK或Loki收集日志
  5. 监控告警:集成Prometheus + Grafana
  6. 自动备份:设置定期数据库备份

这个方案提供了完整的容器化部署流程,你可以根据实际项目需求调整配置。

标签: 容器化部署

抱歉,评论功能暂时关闭!