it编程 > 前端脚本 > Python

Python Flask实现多文件项目打包部署(Linux+Docker+Windows全环境)指南

7人参与 2026-01-31 Python

针对多 .py 文件的 flask 项目,本文在原有部署方案基础上,补充多文件项目结构规范windows 环境部署跨平台打包等核心内容,确保多文件项目在 linux/docker/windows 下都能稳定运行。

一、先规范多文件项目结构(核心前提)

多 .py 文件的关键是模块化拆分 + 避免循环导入 + 统一入口,示例结构如下(覆盖工具类、多蓝图、配置分层):

plaintext

flask-multi-api/
├── app/                  # 核心代码包
│   ├── __init__.py       # 应用工厂(核心)
│   ├── api/              # 接口模块(多蓝图)
│   │   ├── __init__.py
│   │   ├── user.py       # 用户相关接口
│   │   └── order.py      # 订单相关接口
│   ├── utils/            # 工具类(多py文件)
│   │   ├── __init__.py
│   │   ├── common.py     # 通用工具(加密、校验)
│   │   └── db.py         # 数据库操作
│   └── config/           # 配置分层(跨环境)
│       ├── __init__.py
│       ├── base.py       # 基础配置(通用)
│       ├── dev.py        # 开发环境(windows)
│       ├── prod.py       # 生产环境(linux/docker)
│       └── win.py        # windows 特有配置
├── run.py                # 统一启动入口
├── requirements.txt      # 依赖清单(跨平台)
├── dockerfile            # docker 构建文件
├── .dockerignore         # docker 忽略文件
├── start.bat             # windows 启动脚本
└── supervisord.conf      # linux 进程守护配置

核心文件示例(多文件关键)

app/__init__.py(应用工厂,解决多模块导入)

from flask import flask
import os

def create_app(env: str = none):
    """
    应用工厂函数(支持指定环境:dev/prod/win)
    :param env: 环境标识(dev=开发/windows, prod=生产/linux)
    """
    app = flask(__name__)
    
    # 加载配置(根据环境自动切换)
    env = env or os.getenv("flask_env", "dev")
    if env == "dev" or env == "win":
        app.config.from_object("app.config.win")
    elif env == "prod":
        app.config.from_object("app.config.prod")
    else:
        app.config.from_object("app.config.base")
    
    # 注册多蓝图(拆分的接口模块)
    from app.api.user import user_bp
    from app.api.order import order_bp
    app.register_blueprint(user_bp, url_prefix="/api/user")
    app.register_blueprint(order_bp, url_prefix="/api/order")
    
    return app

app/api/user.py(用户接口模块,多 py 文件示例)

from flask import blueprint, jsonify, request
from app.utils.common import encrypt_password  # 导入工具类(多py文件调用)

user_bp = blueprint("user", __name__)

# 用户登录接口
@user_bp.post("/login")
def login():
    data = request.get_json()
    username = data.get("username")
    password = encrypt_password(data.get("password"))  # 调用工具类
    return jsonify({
        "code": 200,
        "msg": "登录成功",
        "data": {"username": username, "token": f"token_{username}"}
    })

# 用户信息接口
@user_bp.get("/info")
def get_user_info():
    user_id = request.args.get("id")
    return jsonify({
        "code": 200,
        "data": {"id": user_id, "name": "张三", "age": 25}
    })

app/api/order.py(订单接口模块,多 py 文件示例)

from flask import blueprint, jsonify
from app.utils.db import get_order_data  # 导入数据库工具类

order_bp = blueprint("order", __name__)

# 订单列表接口
@order_bp.get("/list")
def get_order_list():
    orders = get_order_data()  # 调用工具类
    return jsonify({
        "code": 200,
        "data": orders
    })

app/utils/common.py(工具类 1)

import hashlib

def encrypt_password(password: str) -> str:
    """密码加密工具"""
    return hashlib.md5((password + "salt123").encode()).hexdigest()

def check_params(params: dict, required: list) -> bool:
    """参数校验工具"""
    return all([p in params for p in required])

app/utils/db.py(工具类 2,数据库示例)

def get_order_data():
    """模拟数据库查询订单数据"""
    return [
        {"order_id": "1001", "amount": 99.9, "status": "paid"},
        {"order_id": "1002", "amount": 199.9, "status": "unpaid"}
    ]

app/config/win.py(windows 环境配置)

debug = true  # windows 开发环境开启debug
host = "127.0.0.1"  # windows 本地访问
port = 5000
secret_key = "win-secret-key-123"
# windows 特有配置(如本地数据库路径)
db_path = "c:/flask-api/data.db"

app/config/prod.py(linux 生产环境配置)

debug = false  # 生产环境关闭debug
host = "0.0.0.0"  # 允许外部访问
port = 5000
secret_key = "prod-secret-key-456"
# linux 特有配置(如服务器数据库地址)
db_path = "/opt/flask-api/data.db"

run.py(统一启动入口)

import sys
from app import create_app

if __name__ == "__main__":
    # 识别运行环境(windows/linux)
    env = "win" if sys.platform == "win32" else "prod"
    # 手动指定环境:python run.py prod
    if len(sys.argv) > 1:
        env = sys.argv[1]
    
    app = create_app(env=env)
    app.run(
        host=app.config["host"],
        port=app.config["port"],
        debug=app.config["debug"]
    )

requirements.txt(跨平台依赖)

# 核心依赖(跨平台兼容)
flask==2.3.3
gunicorn==21.2.0  # linux/docker用(windows可选)
waitress==2.1.2   # windows替代gunicorn的wsgi服务器
requests==2.31.0
pywin32>=306      # windows 进程守护(可选)
supervisor==4.2.5 # linux 进程守护(windows也可装)

二、windows 环境部署(多文件项目)

windows 部署分开发环境(本地调试) 和生产环境(服务运行) 两种场景,重点解决 “多文件导入”“进程守护”“端口占用” 问题。

步骤 1:windows 环境准备

安装 python 3.8+(勾选 “add python to path”);

验证环境:

python --version  # 或 python3 --version
pip --version

解压 / 克隆项目到本地(如 d:\flask-multi-api)。

步骤 2:创建虚拟环境(隔离依赖)

# 进入项目目录
cd d:\flask-multi-api
# 创建虚拟环境
python -m venv venv
# 激活虚拟环境(windows 命令行)
venv\scripts\activate.bat
# 如果是powershell,执行:
# venv\scripts\activate.ps1
# 安装依赖
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

步骤 3:本地调试运行(开发环境)

# 方式1:直接启动(自动识别windows环境)
python run.py

# 方式2:手动指定win环境
python run.py win

测试接口(浏览器 / postman/curl):

# 测试用户接口
curl "http://127.0.0.1:5000/api/user/info?id=1"
# 测试订单接口
curl "http://127.0.0.1:5000/api/order/list"

步骤 4:windows 生产环境部署(后台运行 + 进程守护)

flask 内置服务器不适合生产,windows 用 waitress 替代 gunicorn,结合 supervisor 或 nssm 实现后台运行。

方案 1:waitress + supervisor(推荐)

安装 supervisor(windows 版):

pip install supervisor

创建 supervisord.conf 配置文件(项目根目录):

[unix_http_server]
file = nul  # windows 无需unix socket

[inet_http_server]
port = 127.0.0.1:9001  # supervisor 管理端口
username = admin
password = 123456

[supervisord]
logfile = d:\flask-multi-api\logs\supervisord.log
logfile_maxbytes = 50mb
logfile_backups = 10
loglevel = info
pidfile = d:\flask-multi-api\supervisord.pid
nodaemon = false  # 后台运行
minfds = 1024
minprocs = 200
environment = flask_env="win"

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl = http://127.0.0.1:9001

# flask 应用配置
[program:flask-api]
directory = d:\flask-multi-api
command = d:\flask-multi-api\venv\scripts\waitress-serve.exe --host=0.0.0.0 --port=5000 run:create_app('win')
autostart = true
autorestart = true
startretries = 3
stdout_logfile = d:\flask-multi-api\logs\flask-api.log
stdout_logfile_maxbytes = 50mb
stdout_logfile_backups = 10
redirect_stderr = true

创建日志目录:

mkdir d:\flask-multi-api\logs

启动 supervisor:

# 生成默认配置(可选)
echo_supervisord_conf > supervisord.conf
# 启动supervisor
supervisord -c supervisord.conf
# 管理命令
supervisorctl -c supervisord.conf status  # 查看状态
supervisorctl -c supervisord.conf start flask-api  # 启动应用
supervisorctl -c supervisord.conf restart flask-api  # 重启

方案 2:nssm(将 flask 注册为 windows 服务)

下载 nssm,解压到 d:\nssm

注册为 windows 服务:

# 进入nssm目录
cd d:\nssm\win64
# 注册服务(名称:flaskapi)
nssm install flaskapi d:\flask-multi-api\venv\scripts\python.exe
# 设置服务参数
nssm set flaskapi appparameters "run.py win"
nssm set flaskapi appdirectory d:\flask-multi-api
nssm set flaskapi start service_auto_start  # 开机自启
nssm set flaskapi appstdout d:\flask-multi-api\logs\stdout.log
nssm set flaskapi appstderr d:\flask-multi-api\logs\stderr.log

启动 / 管理服务:

nssm start flaskapi  # 启动
nssm stop flaskapi   # 停止
nssm restart flaskapi # 重启
nssm remove flaskapi confirm  # 卸载

步骤 5:windows 端口占用排查

# 查看5000端口占用
netstat -ano | findstr :5000
# 杀死占用进程(pid替换为实际值)
taskkill /f /pid 1234

三、linux 环境部署(多文件项目)

在原有 linux 部署基础上,适配多文件结构,核心步骤不变,仅补充细节:

步骤 1:上传多文件项目到 linux

# 创建目录
mkdir -p /opt/flask-multi-api
# 上传项目(用scp/rz/git)
scp -r d:\flask-multi-api root@<linuxip>:/opt/
cd /opt/flask-multi-api

步骤 2:虚拟环境 + 依赖安装

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

步骤 3:gunicorn 启动(多文件兼容)

# 直接启动(自动识别linux环境)
gunicorn -w 4 -b 0.0.0.0:5000 "run:create_app('prod')"

步骤 4:supervisor 配置(适配多文件)

修改 /etc/supervisord.d/flask-api.ini

[program:flask-api]
directory=/opt/flask-multi-api
command=/opt/flask-multi-api/venv/bin/gunicorn -w 4 -b 0.0.0.0:5000 "run:create_app('prod')"
autostart=true
autorestart=true
user=root
stdout_logfile=/var/log/flask-api.log

重启 supervisor:

supervisorctl reload
supervisorctl start flask-api

四、docker 部署(跨平台多文件项目)

docker 部署可统一 windows/linux 环境,核心是优化 dockerfile 适配多文件结构,支持跨平台构建。

步骤 1:优化 dockerfile(多文件兼容)

# 基础镜像(跨平台兼容)
from python:3.9-slim

# 设置工作目录
workdir /app

# 环境变量(生产环境)
env pythondontwritebytecode=1
env pythonunbuffered=1
env flask_env=prod

# 安装系统依赖
run apt update && apt install -y --no-install-recommends gcc \
    && rm -rf /var/lib/apt/lists/*

# 复制依赖清单
copy requirements.txt .
run pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

# 复制所有多文件代码(关键:保留目录结构)
copy . .

# 暴露端口
expose 5000

# 启动命令(多文件入口)
cmd ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "run:create_app('prod')"]

步骤 2:windows 下构建 docker 镜像

安装 docker desktop(windows),开启 wsl2 后端;

进入项目目录,构建镜像:

docker build -t flask-multi-api:v1 .

步骤 3:启动 docker 容器(跨平台通用)

# windows/linux 通用命令
docker run -d \
  --name flask-multi-api \
  -p 5000:5000 \
  --restart=always \
  -v /var/log/flask-api:/app/logs \  # 挂载日志(linux)
  # windows 挂载日志:-v d:\flask-multi-api\logs:/app/logs
  flask-multi-api:v1

步骤 4:docker compose(多容器 + 多文件)

编写 docker-compose.yml

version: '3.8'
services:
  flask-api:
    build: .
    ports:
      - "5000:5000"
    restart: always
    volumes:
      - ./logs:/app/logs  # 挂载日志(跨平台)
    environment:
      - flask_env=prod
    networks:
      - flask-network

networks:
  flask-network:
    driver: bridge

启动:

# windows
docker-compose up -d
# linux
docker-compose up -d

五、多文件项目部署关键注意事项

导入路径问题

跨平台配置

依赖跨平台兼容

避免依赖仅支持单一系统(如 pywin32 仅 windows,在 linux/docker 中跳过);

requirements.txt 中可通过 ; sys_platform == "win32" 区分依赖:

pywin32>=306 ; sys_platform == "win32"
gunicorn==21.2.0 ; sys_platform != "win32"
waitress==2.1.2 ; sys_platform == "win32"

docker 跨平台构建

日志持久化:多文件项目日志需统一目录,docker/windows/linux 均挂载日志目录,避免日志丢失。

六、常见问题排查(多文件 + 跨平台)

问题场景原因解决方案
多文件导入报错 modulenotfounderror缺少 __init__.py 或导入路径错误给所有包目录加 __init__.py,使用绝对导入
windows 启动 supervisor 报错路径用了 / 而非 \配置文件中路径用 d:\xxx 或 /d/xxx
docker 构建失败(多文件)复制时遗漏目录copy . . 确保复制所有目录,检查 .dockerignore 未忽略核心文件
linux 下 gunicorn 启动报错 create_app not found入口函数调用格式错误用双引号包裹:"run:create_app('prod')"
windows 服务启动后无响应waitress 命令错误检查 waitress-serve 路径,确保调用 create_app 返回 app 实例

通过以上方案,多 .py 文件的 flask 项目可在 windows(开发 / 生产)、linux(生产)、docker(跨平台)下稳定部署,兼顾模块化拆分和环境适配。

init.py 的核心作用与使用场景详解

在 python 项目(尤其是 flask 多文件项目)中,__init__.py 是包(package) 的核心标识文件,理解它的作用能彻底解决多文件导入、模块化拆分的问题。以下从「核心作用」「实战场景」「常见误区」三个维度讲清楚:

init.py 的核心作用(为什么必须有)

python 中「目录」和「包」的唯一区别就是是否有 __init__.py —— 没有这个文件,目录只是普通文件夹,无法被 import;有了它,目录才会被识别为python 包,支持模块化导入。

作用 1:标记目录为 python 包(最基础)

# 无 __init__.py 的情况(普通文件夹)
flask-api/
└── app/          # 普通文件夹,无法 import
    ├── user.py
    └── order.py

# 导入报错(python 不识别 app 为包)
from app import user  # modulenotfounderror: no module named 'app'
# 有 __init__.py 的情况(包)
flask-api/
└── app/          # python 包
    ├── __init__.py  # 空文件也生效
    ├── user.py
    └── order.py

# 导入成功
from app import user
from app.user import user_bp

作用 2:控制包的导出(简化导入)

如果直接让用户导入 app/user.py 里的 user_bp,路径太长且暴露内部结构;可以在 app/__init__.py 中「导出」常用对象,让导入更简洁。

示例:简化多文件导入

# app/__init__.py
# 从子模块导出核心对象
from app.user import user_bp
from app.order import order_bp
from app.utils.common import encrypt_password

# 定义 __all__(配合 from app import * 时生效)
__all__ = ["user_bp", "order_bp", "encrypt_password"]
# 外部导入(简化前)
from app.user import user_bp
from app.order import order_bp
from app.utils.common import encrypt_password

# 外部导入(简化后)
from app import user_bp, order_bp, encrypt_password
# 或
from app import *  # 仅导入 __all__ 中的对象

作用 3:初始化包的资源(统一加载)

__init__.py 在包被导入时自动执行,可以在这里完成包的初始化逻辑(如加载配置、初始化数据库、注册蓝图等)—— 这也是 flask 多文件项目的核心用法。

示例:flask 应用工厂(核心实战)

# app/__init__.py
from flask import flask
import os

# 包导入时自动执行的初始化逻辑
def create_app(env: str = none):
    app = flask(__name__)
    
    # 加载配置
    env = env or os.getenv("flask_env", "dev")
    if env == "prod":
        app.config.from_object("app.config.prod")
    else:
        app.config.from_object("app.config.dev")
    
    # 统一注册所有蓝图(无需在 run.py 中逐个导入)
    from app.user import user_bp
    from app.order import order_bp
    app.register_blueprint(user_bp, url_prefix="/api/user")
    app.register_blueprint(order_bp, url_prefix="/api/order")
    
    return app

# 可选:初始化数据库连接(全局生效)
from app.utils.db import init_db
init_db()
# run.py(只需导入 create_app,无需关心内部模块)
from app import create_app

app = create_app()
app.run()

作用 4:解决循环导入问题

多文件项目最容易遇到「循环导入」(如 user.py 导入 db.pydb.py 又导入 user.py),通过 __init__.py 延迟导入可解决。

示例:解决循环导入

# 问题场景:循环导入
# app/user.py
from app.utils.db import db  # 导入 db
db.add_user(...)

# app/utils/db.py
from app.user import user_bp  # 又导入 user_bp → 循环导入报错
# 解决方案:在 __init__.py 中延迟导入
# app/__init__.py
def create_app():
    app = flask(__name__)
    
    # 延迟导入(直到函数调用时才导入,避免初始化时循环)
    from app.user import user_bp
    from app.utils.db import init_db
    
    init_db(app)  # 把 app 传入 db 模块,避免 db 导入 user
    app.register_blueprint(user_bp)
    return app

作用 5:定义包的元数据(可选)

可以在 __init__.py 中定义包的版本、作者等元数据,方便外部调用。

# app/__init__.py
__version__ = "1.0.0"
__author__ = "xxx"
__description__ = "flask 多文件 api 项目"
# 外部获取元数据
import app
print(app.__version__)  # 1.0.0
print(app.__author__)   # xxx

不同场景下init.py 的写法

场景init.py 写法说明
仅标记为包空文件最简单,仅让目录可导入
简化导入导出子模块对象 + 定义 all外部导入更简洁
flask 项目核心包编写应用工厂函数 + 统一注册蓝图 / 初始化资源多文件项目的标准用法
工具类包导出常用工具函数 + 初始化全局资源如 utils/init.py
避免循环导入延迟导入(在函数内部导入子模块)解决多文件依赖问题

常见误区(避坑)

误区 1:python 3.3+ 不需要init.py?

python 3.3 引入了「隐式命名空间包」,即使没有 __init__.py,也能导入目录;但:

误区 2:所有init.py 都要写复杂逻辑?

不是!子包的 __init__.py 可以是空文件(仅标记为包),只有「根包」(如 app/__init__.py)需要写初始化逻辑。

示例:合理的分层写法

app/
├── __init__.py  # 核心逻辑(应用工厂、蓝图注册)
├── user.py
├── order.py
└── utils/       # 子包
    ├── __init__.py  # 空文件(仅标记为包)
    ├── common.py
    └── db.py

误区 3:init.py 执行多次?

__init__.py 仅在包第一次被导入时执行一次,后续导入会复用已加载的模块(python 模块缓存机制),无需担心性能问题。

总结

核心结论通俗解释
为什么要有?让普通目录变成「python 包」,支持导入
空文件行不行?行(仅满足基础导入),但工程化项目建议写逻辑
flask 项目中核心作用?统一初始化应用、注册蓝图、简化导入、解决循环依赖
哪些目录需要?所有需要被 import 的目录(如 app/、app/utils/)

简单来说:__init__.py 是 python 模块化的「入口门牌号」—— 没有它,python 找不到你的代码;有了它,你还能控制代码怎么被找到、怎么初始化。

到此这篇关于python flask实现多文件项目打包部署(linux+docker+windows全环境)指南的文章就介绍到这了,更多相关python flask打包内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

用OpenCV和Python进行人脸识别实战

01-31

10 个Python统计分析常用的经典脚本分享

01-31

8个Python中批量处理数据的核心库使用指南

01-31

Python使用PyQt5打造桌面应用的入门指南

01-31

Python使用pytest高效编写和管理单元测试的完整指南

01-31

一文分享4个Python实用脚本让你效率爆表

01-31

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论