You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Docker容器中实现Flask与notification.py子进程并行运行?

解决Flask与notification.py并行运行的问题

问题根源

  • subprocess.run()是阻塞调用,会卡住Flask启动流程,必须等notification.py运行结束才会继续,导致Flask无法正常启动。
  • subprocess.Popen()没效果,大概率是因为你用了stdout=subprocess.PIPE但未读取输出,子进程会因输出缓冲区被占满而挂起,看起来像没运行。

可行方案

方案1:用Python multiprocessing模块(单进程内并行)

直接用Python自带的多进程模块启动脚本,更可控:

from multiprocessing import Process
import os
import sys

def run_notification():
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    notification_path = os.path.join(BASE_DIR, "notifications_script.py")
    # 导入脚本并执行(假设脚本有main入口函数)
    sys.path.insert(0, BASE_DIR)
    import notifications_script
    notifications_script.main()

# 在Flask启动前启动子进程
if __name__ == '__main__':
    p = Process(target=run_notification)
    p.daemon = True  # 设置为守护进程,Flask退出时自动结束
    p.start()
    # 启动Flask应用
    from app import app
    app.run(host='0.0.0.0', port=5000)

如果notification.py是直接执行的脚本(无main函数),可以配合subprocess并处理输出:

from multiprocessing import Process
import subprocess
import os

def run_notification():
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    notification_path = os.path.join(BASE_DIR, "notifications_script.py")
    # 重定向输出到容器日志,避免缓冲区阻塞
    subprocess.Popen(
        ['python', notification_path],
        shell=False,
        stdout=open('/proc/self/fd/1', 'w'),
        stderr=subprocess.STDOUT
    )

if __name__ == '__main__':
    p = Process(target=run_notification)
    p.daemon = True
    p.start()
    from app import app
    app.run(host='0.0.0.0', port=5000)

方案2:Docker多容器部署(推荐)

既然已经用Docker,把Flask和notification拆成两个独立容器,用Docker Compose管理,更符合容器化最佳实践:

# docker-compose.yml
version: '3.8'
services:
  flask-app:
    build: ./flask
    ports:
      - "5000:5000"
    # 按需添加环境变量、卷挂载等配置
    depends_on:
      - notification-service

  notification-service:
    build: ./flask  # 复用Flask镜像,或单独构建
    command: python notifications_script.py
    # 按需添加环境变量、卷挂载等配置

两个服务独立运行,互不干扰,日志也能分开查看。

方案3:用Supervisor管理单容器内多进程

如果必须在同一个容器运行,用Supervisor进程管理器同时启动Flask和脚本:

  1. Dockerfile中安装supervisor:
RUN apt-get update && apt-get install -y supervisor
  1. 创建supervisord.conf配置文件:
[supervisord]
nodaemon=true

[program:flask]
command=gunicorn -w 4 -b 0.0.0.0:5000 app:app  # 生产环境用gunicorn替代内置服务器
directory=/app
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

[program:notification]
command=python notifications_script.py
directory=/app
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
  1. Dockerfile最后设置启动命令:
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
CMD ["supervisord"]

内容的提问来源于stack exchange,提问作者mick_dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 01:15:33