ATP|搭建Docker+Flask+mysql框架

假设我们的项目根目录是:my-flask-web

README.md文件(项目目录结构)

shell 复制代码
my-flask-web/
├── app/
│   ├── __init__.py          # Flask 应用工厂
│   ├── models/
│   │   ├── __init__.py
│   │   └── user.py          # 用户模型
│   └── routes/
│       ├── __init__.py
│       ├── main.py          # 主路由蓝图
│       └── api.py           # API 蓝图
├── config.py                # 配置文件
├── run.py                   # 启动文件
├── requirements.txt         # Python 依赖
├── Dockerfile               # Docker 镜像构建
├── docker-compose.yml       # Docker 编排
├── .env.example             # 环境变量示例
├── .gitignore               # Git 忽略规则
├── .dockerignore            # Docker 忽略规则
├── README.md                # 项目说明
└── venv/                    # 虚拟环境(已安装依赖)

一、创建flask必备文件

1.1 程序入口文件:./run.py

python 复制代码
from app import create_app

app = create_app()

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

1.2 Flask 应用工厂:.app/__init__.py

python 复制代码
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import config

db = SQLAlchemy()


def create_app(config_name='default'):
    """应用工厂模式"""
    app = Flask(__name__)
    app.config.from_object(config[config_name])

    # 初始化扩展
    db.init_app(app)

    # 注册蓝图
    from app.routes.main import main_bp
    from app.routes.api import api_bp

    app.register_blueprint(main_bp)
    app.register_blueprint(api_bp, url_prefix='/api')

    # 创建数据库表
    with app.app_context():
        db.create_all()

    return app

1.3 Flask配置文件:./config.py

python 复制代码
import os
from dotenv import load_dotenv

load_dotenv()


class Config:

    """基础配置"""

    SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-secret-key')

    # MySQL 数据库配置
    MYSQL_HOST = os.environ.get('MYSQL_HOST', 'localhost')
    MYSQL_PORT = os.environ.get('MYSQL_PORT', 3306)
    MYSQL_USER = os.environ.get('MYSQL_USER', 'root')
    MYSQL_PASSWORD = os.environ.get('MYSQL_PASSWORD', 'your_password_data')
    MYSQL_DATABASE = os.environ.get('MYSQL_DATABASE', 'flask_app')
    
    SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{MYSQL_USER}:{MYSQL_PASSWORD}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DATABASE}"
    SQLALCHEMY_TRACK_MODIFICATIONS = False


class DevelopmentConfig(Config):
    """开发环境配置"""
    DEBUG = True


class ProductionConfig(Config):
    """生产环境配置"""
    DEBUG = False


class TestingConfig(Config):
    """测试环境配置"""
    TESTING = True
    SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'


config = {
    'development': DevelopmentConfig,
    'production': ProductionConfig,
    'testing': TestingConfig,
    'default': DevelopmentConfig
}

1.4 用户模型./app/models/user.py

python 复制代码
from app import db
from datetime import datetime


class User(db.Model):
    """用户模型"""
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    def to_dict(self):
        """转换为字典"""
        return {
            'id': self.id,
            'username': self.username,
            'email': self.email,
            'created_at': self.created_at.isoformat() if self.created_at else None
        }

    def __repr__(self):
        return f'<User {self.username}>'

1.5 模型聚合文件:./app/models/__init__.py

python 复制代码
from app.models.user import User

__all__ = ['User']

1.6 主路由蓝图:./app/routes/main.py

python 复制代码
from flask import Blueprint, jsonify

main_bp = Blueprint('main', __name__)


@main_bp.route('/')
def index():
    """首页"""
    return jsonify({
        'message': '欢迎使用 Flask 应用',
        'status': 'success'
    })


@main_bp.route('/health')
def health():
    """健康检查端点"""
    return jsonify({
        'status': 'healthy'
    })

1.7 API 蓝图:./app/routes/api.py

python 复制代码
from flask import Blueprint, jsonify, request
from app import db
from app.models import User

api_bp = Blueprint('api', __name__)


@api_bp.route('/users', methods=['GET'])
def get_users():
    """获取所有用户"""
    users = User.query.all()
    return jsonify({
        'users': [user.to_dict() for user in users],
        'count': len(users)
    })


@api_bp.route('/users', methods=['POST'])
def create_user():
    """创建新用户"""
    data = request.get_json()
    if not data or not data.get('username') or not data.get('email'):
    return jsonify({'error': '用户名和邮箱是必填项'}), 400
        user = User(
        username=data['username'],
        email=data['email']
    )

    db.session.add(user)
    db.session.commit()
    return jsonify({
        'message': '用户创建成功',
        'user': user.to_dict()
    }), 201


@api_bp.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    """获取指定用户"""
    user = User.query.get_or_404(user_id)
    return jsonify({'user': user.to_dict()})

1.8 蓝图聚合文件:./app/routes/__init__.py

python 复制代码
from app.routes.main import main_bp
from app.routes.api import api_bp

__all__ = ['main_bp', 'api_bp']

1.9 包管理文件:·./requirements.txt

txt 复制代码
Flask==3.0.0
Flask-SQLAlchemy==3.1.1
PyMySQL==1.1.0
cryptography==41.0.7
python-dotenv==1.0.0

二、创建docker必要文件

我们项目使用flask+mysql+vue多个容器,使用docker-compose.yml文件进行编排各容器的关系

2.1 编排多个容器文件:./docker-compose.yml

yml 复制代码
version: '3.8'

services:
    web:
        build: .
        ports:
            - "5000:5000"
        environment:
            - MYSQL_HOST=db
            - MYSQL_PORT=3306
            - MYSQL_USER=root
            - MYSQL_PASSWORD=rootpassword
            - MYSQL_DATABASE=flask_app
            - SECRET_KEY=your_production_secret_key
        depends_on:
            db:
                condition: service_healthy
        networks:
            - flask-network
        volumes:
            - .:/app
    db:
        image: mysql:8.0
        environment:
            - MYSQL_ROOT_PASSWORD=rootpassword
            - MYSQL_DATABASE=flask_app
        ports:
            - "3306:3306"
        volumes:
            - mysql_data:/var/lib/mysql
        networks:
            - flask-network
        healthcheck:
            test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
            timeout: 5s
            retries: 10
networks:
    flask-network:
        driver: bridge

volumes:
    mysql_data:

2.2 Docker 镜像构建文件:./Dockerfile

用来构建 Docker 镜像的配置文件。它定义了如何把你的应用打包成一个可移植的容器。

bash 复制代码
FROM python:3.11-slim

WORKDIR /app

# Install system dependencies
RUN apt-get update && apt-get install -y \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# Copy requirements and install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY . .

# Expose port
EXPOSE 5000

# Run the application
CMD ["python", "run.py"]

2.3 docker过滤文件:./.dockerignore

作用是在构建 docker 镜像时排除不需要的文件,避免把垃圾文件打包进镜像。

bash 复制代码
__pycache__/
*.py[cod]
*$py.class
venv/
env/
.venv/
.env
.git/
.gitignore
.idea/
.vscode/
*.log
.DS_Store
*.md

2.4 环境变量模板文件:./.env.example

ini 复制代码
# 数据库配置
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=你的密码
MYSQL_DATABASE=flask_app

# Flask 配置
FLASK_APP=run.py
FLASK_ENV=development
SECRET_KEY=你的密钥
相关推荐
传说之后1 小时前
Go 网络编程:从 TCP 字节流到自定义协议设计
后端·架构
程序猿进阶1 小时前
OpenClaw Mac 安装教程
java·macos·ai·架构·agent·openclaw
喵个咪1 小时前
单体项目如何“无感”演进微服务?Core+BFF分层架构实践
后端·微服务·架构
何中应2 小时前
软件架构风格总结
架构·软考·软件架构
qq_454245032 小时前
WorkFlow 体系架构综合介绍
架构
heimeiyingwang2 小时前
【架构实战】RocketMQ实战:分布式消息中间件
分布式·架构·rocketmq
Cosolar2 小时前
智能体 Agent 完全拆解:架构、组件与实战指南
人工智能·架构·大模型·agent·智能体
OceanBase数据库官方博客2 小时前
现代数据架构:一套技术栈统一 TP、AP 与 AI
架构·oceanbase
刀法如飞3 小时前
Palantir技术原理深度分析:Ontology 存储结构与读写方式
人工智能·算法·架构