背景#
Python 环境和依赖都准备好了,用 Supervisor 管理应用进程,实现开机自启和崩溃自动重启。这一步的问题集中在:Supervisor 配置本身没问题,但应用就是起不来。
问题一:can’t find command#
报错信息:
flask FATAL can't find command '/var/www/flask-app/venv/bin/gunicorn'
streamlit FATAL can't find command '/var/www/streamlit-app/venv/bin/streamlit'虚拟环境里没装对应的包,或路径写错了。
# 先检查文件是否存在
ls -la /var/www/flask-app/venv/bin/gunicorn
ls -la /var/www/streamlit-app/venv/bin/streamlit
# 不存在的话重新安装
cd /var/www/flask-app
source venv/bin/activate
pip install gunicorn
deactivate
cd /var/www/streamlit-app
source venv/bin/activate
pip install streamlit
deactivate
sudo supervisorctl restart all问题二:No module named ‘_ssl’#
报错信息:
ModuleNotFoundError: No module named '_ssl'Python 编译时没有 SSL 支持,需要先编译 OpenSSL 1.1.1,再重新编译 Python,然后重建虚拟环境。具体步骤见系列第二篇。
重建虚拟环境:
cd /var/www/streamlit-app
rm -rf venv
python3.11 -m venv venv
source venv/bin/activate
pip install streamlit
deactivate问题三:Exited too quickly#
报错信息:
flask FATAL Exited too quickly (process log may have details)先查日志:
cat /var/log/flask.err.log | tail -30
cat /var/log/streamlit.err.log | tail -30日志里会有具体的报错信息,根据提示排查。
问题四:App failed to load#
报错信息:
gunicorn.errors.HaltServer: <HaltServer 'App failed to load.' 4>Flask 应用本身有问题,无法导入。手动测试:
cd /var/www/flask-app
source venv/bin/activate
python -c "from app import app; print('OK')"根据报错信息修复。
问题五:Failed to find attribute ‘app’ in ‘app’(最坑的一个)#
报错信息:
Failed to find attribute 'app' in 'app'.项目里同时存在 app.py 文件和 app/ 文件夹,Python 导入时优先导入了文件夹,找不到 app 属性:
flask-app/
├── app.py ← 入口文件
├── app/ ← 应用包(与 app.py 同名,冲突!)
│ ├── __init__.py
│ └── ...把入口文件改名解决:
cd /var/www/flask-app
mv app.py wsgi.pywsgi.py 内容:
import os
from app import create_app
env = os.getenv('APP_ENV', 'development')
config_name = 'production' if env == 'prod' else 'development'
app = create_app(config_name)
if __name__ == '__main__':
app.run()修改 Supervisor 配置(app:app 改为 wsgi:app):
[program:flask]
command=/var/www/flask-app/venv/bin/gunicorn -w 2 -b 127.0.0.1:5000 wsgi:app重启:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl restart flask问题六:No module named ‘config’#
报错信息:
ModuleNotFoundError: No module named 'config'配置文件不存在,手动创建:
cat > /var/www/flask-app/config.py << 'EOF'
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'your-secret-key-here'
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR, 'data', 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
class DevelopmentConfig(Config):
DEBUG = True
class ProductionConfig(Config):
DEBUG = False
config = {
'development': DevelopmentConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
EOF
mkdir -p /var/www/flask-app/data完整的 Supervisor 配置#
# /etc/supervisord.d/apps.ini
[program:streamlit]
command=/var/www/streamlit-app/venv/bin/streamlit run app.py --server.port 8501 --server.address 127.0.0.1
directory=/var/www/streamlit-app
environment=APP_ENV="prod"
user=root
autostart=true
autorestart=true
stderr_logfile=/var/log/streamlit.err.log
stdout_logfile=/var/log/streamlit.out.log
[program:flask]
command=/var/www/flask-app/venv/bin/gunicorn -w 2 -b 127.0.0.1:5000 wsgi:app
directory=/var/www/flask-app
environment=APP_ENV="prod"
user=root
autostart=true
autorestart=true
stderr_logfile=/var/log/flask.err.log
stdout_logfile=/var/log/flask.out.logSupervisor 常用命令#
# 重新加载配置
sudo supervisorctl reread
sudo supervisorctl update
# 查看状态
sudo supervisorctl status
# 启动/停止/重启
sudo supervisorctl start flask
sudo supervisorctl stop flask
sudo supervisorctl restart flask
sudo supervisorctl restart all
# 实时查看日志
tail -f /var/log/flask.err.log
tail -f /var/log/streamlit.out.log标准排查流程#
# 1. 看状态
sudo supervisorctl status
# 2. FATAL 就看日志
cat /var/log/flask.err.log | tail -30
# 3. 手动测试能否导入
cd /var/www/flask-app
source venv/bin/activate
python -c "from wsgi import app; print('OK')"
# 4. 手动启动测试
gunicorn -w 1 -b 127.0.0.1:5000 wsgi:app
# 5. 修复后重启
sudo supervisorctl restart flaskStreamlit 配置文件#
mkdir -p /root/.streamlit
cat > /root/.streamlit/config.toml << 'EOF'
[server]
headless = true
port = 8501
enableCORS = false
enableXsrfProtection = false
[browser]
gatherUsageStats = false
EOF问题汇总#
| 问题 | 根因 | 解决方案 |
|---|---|---|
| can’t find command | 包未安装 | 重新 pip install |
| No module ‘_ssl’ | Python 缺 SSL 支持 | 重编 Python |
| Exited too quickly | 应用启动失败 | 查看错误日志 |
| App failed to load | 应用代码问题 | 手动测试导入 |
| attribute not found | 文件/文件夹名冲突 | 重命名入口文件为 wsgi.py |
| config 缺失 | 配置文件不存在 | 手动创建 |
系列小结#
到这里,整个部署流程走完了。最终架构:
Nginx(80/443)
├── misaku.site → Hugo 静态文件
├── app1.misaku.site → Streamlit(8501)
└── app2.misaku.site → Flask(5000)
↑
Supervisor 守护CentOS 7 真的太老了,各种兼容性问题耗费了大量时间。新项目建议直接用 Rocky Linux 9 或 Ubuntu 22.04,能省掉本系列大部分麻烦。