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

Ubuntu 18.04上mod_wsgi适配双Python版本部署Django应用问题

解决方案:同一Apache服务器部署多版本Python Django应用

核心问题原因

mod_wsgi与编译时指定的Python版本强绑定,单个mod_wsgi模块只能适配一个Python版本,因此无法同时兼容Python3.6和Python3.11的虚拟环境。以下提供两种可行方案:


方案一:编译多个mod_wsgi实例,分虚拟主机加载

为每个Python版本单独编译mod_wsgi,在对应虚拟主机中加载适配的模块,实现版本隔离。

1. 编译不同版本的mod_wsgi

  • 编译Python3.6适配的mod_wsgi
    激活Pyenv的Python3.6.8环境,下载mod_wsgi/4.6.5源码后编译安装到独立目录:

    pyenv activate 3.6.8
    ./configure --with-python=$(pyenv which python3.6) --prefix=/usr/local/mod_wsgi-py36
    make && sudo make install
    
  • 编译Python3.11适配的mod_wsgi
    激活Pyenv的Python3.11+环境,下载mod_wsgi/4.9.4源码后编译安装到独立目录:

    pyenv activate 3.11.x  # 替换为实际3.11版本号
    ./configure --with-python=$(pyenv which python3.11) --prefix=/usr/local/mod_wsgi-py311
    make && sudo make install
    

2. 配置Apache虚拟主机

先注释掉全局的LoadModule wsgi_module配置(通常在/etc/apache2/mods-available/wsgi.load或主配置文件中),然后为两个应用分别配置虚拟主机:

  • 旧应用(Python3.6)虚拟主机配置

    <VirtualHost *:80>
        ServerName old-app.example.com
    
        # 加载Python3.6对应的mod_wsgi模块
        LoadModule wsgi_module /usr/local/mod_wsgi-py36/lib/apache2/modules/mod_wsgi.so
    
        WSGIDaemonProcess old-app python-home=/home/ubuntu/.pyenv/versions/3.6.8/envs/old-app-env
        WSGIProcessGroup old-app
        WSGIScriptAlias / /var/www/old-app/wsgi.py process-group=old-app
    
        <Directory /var/www/old-app>
            Require all granted
        </Directory>
    
        ErrorLog ${APACHE_LOG_DIR}/old-app-error.log
        CustomLog ${APACHE_LOG_DIR}/old-app-access.log combined
    </VirtualHost>
    
  • 新应用(Python3.11)虚拟主机配置

    <VirtualHost *:80>
        ServerName new-app.example.com
    
        # 加载Python3.11对应的mod_wsgi模块
        LoadModule wsgi_module /usr/local/mod_wsgi-py311/lib/apache2/modules/mod_wsgi.so
    
        WSGIDaemonProcess new-app python-home=/home/ubuntu/.pyenv/versions/3.11.x/envs/new-app-env
        WSGIProcessGroup new-app
        WSGIScriptAlias / /var/www/new-app/wsgi.py process-group=new-app
    
        <Directory /var/www/new-app>
            Require all granted
        </Directory>
    
        ErrorLog ${APACHE_LOG_DIR}/new-app-error.log
        CustomLog ${APACHE_LOG_DIR}/new-app-access.log combined
    </VirtualHost>
    

3. 验证并重启服务

sudo apache2ctl configtest
sudo systemctl restart apache2

方案二:uWSGI+Apache反向代理(推荐长期方案)

将每个Django应用通过uWSGI运行(绑定各自的Python虚拟环境),Apache作为反向代理转发请求,实现完全的版本隔离。

1. 为每个应用安装uWSGI

在各自的虚拟环境中安装uWSGI:

# 旧应用虚拟环境
pyenv activate old-app-env
pip install uwsgi

# 新应用虚拟环境
pyenv activate new-app-env
pip install uwsgi

2. 编写uWSGI配置文件

  • 旧应用uwsgi.ini

    [uwsgi]
    chdir = /var/www/old-app
    module = wsgi:application
    home = /home/ubuntu/.pyenv/versions/3.6.8/envs/old-app-env
    socket = /tmp/old-app.sock
    chmod-socket = 666
    master = true
    processes = 4
    vacuum = true
    
  • 新应用uwsgi.ini

    [uwsgi]
    chdir = /var/www/new-app
    module = wsgi:application
    home = /home/ubuntu/.pyenv/versions/3.11.x/envs/new-app-env
    socket = /tmp/new-app.sock
    chmod-socket = 666
    master = true
    processes = 4
    vacuum = true
    

3. 配置systemd管理uWSGI进程

创建服务文件确保应用开机自启:

  • 旧应用服务文件 /etc/systemd/system/old-app-uwsgi.service

    [Unit]
    Description=uWSGI instance for old Django app
    After=network.target
    
    [Service]
    User=ubuntu
    Group=www-data
    WorkingDirectory=/var/www/old-app
    Environment="PATH=/home/ubuntu/.pyenv/versions/3.6.8/envs/old-app-env/bin"
    ExecStart=/home/ubuntu/.pyenv/versions/3.6.8/envs/old-app-env/bin/uwsgi --ini uwsgi.ini
    
    [Install]
    WantedBy=multi-user.target
    
  • 新应用服务文件 /etc/systemd/system/new-app-uwsgi.service

    [Unit]
    Description=uWSGI instance for new Django app
    After=network.target
    
    [Service]
    User=ubuntu
    Group=www-data
    WorkingDirectory=/var/www/new-app
    Environment="PATH=/home/ubuntu/.pyenv/versions/3.11.x/envs/new-app-env/bin"
    ExecStart=/home/ubuntu/.pyenv/versions/3.11.x/envs/new-app-env/bin/uwsgi --ini uwsgi.ini
    
    [Install]
    WantedBy=multi-user.target
    

启动并启用服务:

sudo systemctl daemon-reload
sudo systemctl start old-app-uwsgi new-app-uwsgi
sudo systemctl enable old-app-uwsgi new-app-uwsgi

4. 配置Apache反向代理

先启用必要模块:

sudo a2enmod proxy proxy_http proxy_uwsgi

然后配置虚拟主机:

  • 旧应用虚拟主机

    <VirtualHost *:80>
        ServerName old-app.example.com
    
        ProxyPass / unix:/tmp/old-app.sock|uwsgi://localhost/
        ProxyPassReverse / unix:/tmp/old-app.sock|uwsgi://localhost/
    
        ErrorLog ${APACHE_LOG_DIR}/old-app-error.log
        CustomLog ${APACHE_LOG_DIR}/old-app-access.log combined
    </VirtualHost>
    
  • 新应用虚拟主机

    <VirtualHost *:80>
        ServerName new-app.example.com
    
        ProxyPass / unix:/tmp/new-app.sock|uwsgi://localhost/
        ProxyPassReverse / unix:/tmp/new-app.sock|uwsgi://localhost/
    
        ErrorLog ${APACHE_LOG_DIR}/new-app-error.log
        CustomLog ${APACHE_LOG_DIR}/new-app-access.log combined
    </VirtualHost>
    

重启Apache生效:

sudo systemctl restart apache2

方案对比

  • 多mod_wsgi实例:无需额外进程管理,但编译和配置复杂度高,Apache版本需兼容不同mod_wsgi版本。
  • uWSGI反向代理:应用完全隔离,升级或修改单个应用不影响其他服务,排查问题更便捷,适合长期维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 00:54:51