跳转至

部署与运维

📖 章节简介

本章将介绍Flask应用的部署和运维,包括使用Gunicorn、Nginx、Docker等技术将应用部署到生产环境。

🚀 生产服务器

1. Gunicorn配置

Bash
# 安装Gunicorn
pip install gunicorn

# requirements.txt
gunicorn==21.2.0
Python
# gunicorn_config.py
import multiprocessing

# 服务器socket
bind = "127.0.0.1:8000"
backlog = 2048

# Worker进程
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = 'sync'
worker_connections = 1000
max_requests = 1000
max_requests_jitter = 50
timeout = 30
keepalive = 2

# 进程命名
proc_name = 'myapp'

# 日志
accesslog = '/var/log/gunicorn/access.log'
errorlog = '/var/log/gunicorn/error.log'
loglevel = 'info'
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s'

# 进程管理
daemon = False
pidfile = '/var/run/gunicorn/gunicorn.pid'
umask = 0
user = None
group = None
tmp_upload_dir = None
Bash
# 启动Gunicorn
gunicorn -c gunicorn_config.py wsgi:app

# 或直接使用命令行
gunicorn -w 4 -b 127.0.0.1:8000 wsgi:app

# 使用systemd管理
# /etc/systemd/system/myapp.service
[Unit]
Description=My Flask Application
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/myapp
Environment="PATH=/var/www/myapp/venv/bin"
ExecStart=/var/www/myapp/venv/bin/gunicorn -c gunicorn_config.py wsgi:app
Restart=always

[Install]
WantedBy=multi-user.target

2. WSGI入口

Python
# wsgi.py
from app import create_app

app = create_app()

if __name__ == '__main__':
    app.run()

🌐 Nginx配置

1. 基本配置

Nginx Configuration File
# /etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name example.com www.example.com;

    # 重定向到HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    # SSL配置
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # 日志
    access_log /var/log/nginx/myapp_access.log;
    error_log /var/log/nginx/myapp_error.log;

    # 客户端上传大小
    client_max_body_size 10M;

    # 静态文件
    location /static {
        alias /var/www/myapp/app/static;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # 代理到Gunicorn
    location / {
        proxy_pass http://127.0.0.1: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;
        proxy_redirect off;
    }

    # 安全头
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    add_header Referrer-Policy "strict-origin-when-cross-origin";
}

2. 启用配置

Bash
# 创建符号链接
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/

# 测试配置
sudo nginx -t

# 重启Nginx
sudo systemctl restart nginx

🐳 Docker部署

1. Dockerfile

Docker
# Dockerfile
FROM python:3.12-slim  # FROM指定基础镜像

# 设置工作目录
WORKDIR /app  # WORKDIR设置工作目录

# 安装系统依赖
RUN apt-get update && apt-get install -y \  # RUN在构建时执行命令
    gcc \
    postgresql-client \
    && rm -rf /var/lib/apt/lists/*

# 复制依赖文件
COPY requirements.txt .  # COPY将文件复制到镜像中

# 安装Python依赖
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用代码
COPY . .

# 创建非root用户
RUN useradd -m -u 1000 appuser && \
    chown -R appuser:appuser /app
USER appuser

# 暴露端口
EXPOSE 8000  # EXPOSE声明容器监听的端口

# 启动应用
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8000", "wsgi:app"]  # CMD容器启动时执行的默认命令

2. Docker Compose

YAML
# docker-compose.yml
services:  # services定义各个服务容器
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/myapp
      - SECRET_KEY=${SECRET_KEY}
    depends_on:
      - db
      - redis
    volumes:
      - ./uploads:/app/uploads
    restart: unless-stopped

  db:
    image: postgres:15
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=myapp
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - web
    restart: unless-stopped

volumes:
  postgres_data:

3. 部署命令

Bash
# 构建镜像
docker-compose build

# 启动服务
docker-compose up -d

# 查看日志
docker-compose logs -f

# 停止服务
docker-compose down

# 更新服务
docker-compose pull
docker-compose up -d

📊 监控和日志

1. 应用监控

Python
# app/monitoring.py
from prometheus_flask_exporter import PrometheusMetrics

def setup_monitoring(app):
    """设置监控"""
    metrics = PrometheusMetrics(app)

    # 自定义指标
    metrics.info('app_info', 'Application info', version='1.0.0')

    return metrics

2. 日志配置

Python
# config.py
import logging
from logging.handlers import RotatingFileHandler

class Config:
    # 日志配置
    LOG_LEVEL = logging.INFO
    LOG_FILE = '/var/log/myapp/app.log'
    LOG_MAX_BYTES = 10485760  # 10MB
    LOG_BACKUP_COUNT = 10

def setup_logging(app):
    """设置日志"""
    handler = RotatingFileHandler(
        Config.LOG_FILE,
        maxBytes=Config.LOG_MAX_BYTES,
        backupCount=Config.LOG_BACKUP_COUNT
    )
    handler.setFormatter(logging.Formatter(
        '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
    ))
    handler.setLevel(Config.LOG_LEVEL)

    app.logger.addHandler(handler)
    app.logger.setLevel(Config.LOG_LEVEL)

💡 最佳实践

1. 部署检查清单

Python
# 部署检查清单
deployment_checklist = {
    '环境配置': [
        '设置正确的环境变量',
        '配置数据库连接',
        '设置SECRET_KEY',
        '配置日志路径'
    ],
    '安全配置': [
        '启用HTTPS',
        '配置安全头',
        '设置防火墙',
        '定期更新依赖'
    ],
    '性能优化': [
        '配置缓存',
        '启用压缩',
        '优化数据库查询',
        '使用CDN'
    ],
    '监控告警': [
        '配置应用监控',
        '设置错误告警',
        '配置日志收集',
        '设置性能监控'
    ]
}

2. 备份策略

Python
# 备份策略
backup_strategy = {
    '数据库备份': [
        '定期备份数据库',
        '备份文件加密',
        '异地备份',
        '定期测试恢复'
    ],
    '应用备份': [
        '版本控制',
        '配置文件备份',
        '静态资源备份'
    ]
}

📝 练习题

基础题

  1. 如何使用Gunicorn部署Flask应用?
  2. 如何配置Nginx反向代理?
  3. 如何使用Docker部署应用?

进阶题

  1. 实现应用监控。
  2. 配置日志系统。
  3. 设置自动化部署。

实践题

  1. 将Flask应用部署到生产环境。
  2. 配置Nginx和Gunicorn。
  3. 使用Docker Compose部署完整应用。

📚 推荐阅读

🔗 下一章

实战项目 - 通过一个完整的博客系统项目综合运用所学知识。