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

如何在同一Web服务器部署多个Django应用并分配独立PostgreSQL权限

我完全懂你这种维护多个Apache实例的痛苦——零散的配置、不同的系统用户,时间长了确实会变成一团乱麻。咱们可以用「单Web服务器反向代理 + 独立应用进程 + 最小权限数据库用户」的架构来解决,既实现权限隔离,又能大幅降低维护成本。

核心思路

放弃多Apache实例的模式,用**一台主Web服务器(Apache或Nginx)**做反向代理,每个Django应用通过独立的应用服务器进程(比如uWSGI或Gunicorn)运行,每个进程使用专属的系统用户,同时为每个应用分配仅能访问自身数据库的PostgreSQL用户,严格遵循最小权限原则。

具体实现步骤

1. 切换到反向代理架构

如果你还在用Apache直接跑Django,建议转向「Apache + uWSGI」的组合:Apache负责处理静态文件和反向代理请求,uWSGI负责运行Django应用。这样主Apache只需要一个实例,所有应用的请求都通过它转发。

首先启用Apache的必要模块:

sudo a2enmod proxy proxy_uwsgi rewrite

2. 为每个Django应用创建独立系统用户

每个应用用专属的系统用户运行,确保进程级别的隔离:

# 为app1创建用户,-m创建家目录,-s指定shell
sudo useradd -m -s /bin/bash app1_user
# 同理为其他应用创建,比如app2_user、app3_user

然后把应用代码目录的权限转移给这个用户:

sudo chown -R app1_user:app1_user /var/www/app1

3. 配置PostgreSQL最小权限用户

给每个应用创建专属的数据库和用户,只分配它需要的权限,绝对不给跨库访问的权限:

首先进入PostgreSQL命令行:

sudo -u postgres psql

然后执行以下SQL(替换对应的名称):

-- 创建应用专属数据库用户
CREATE USER app1_db_user WITH PASSWORD '你的强密码';
-- 创建应用专属数据库,并让该用户成为所有者
CREATE DATABASE app1_db OWNER app1_db_user;
-- 仅授予该用户访问自身数据库的权限
GRANT CONNECT ON DATABASE app1_db TO app1_db_user;
-- 授予schema的使用权限,以及表的必要操作权限(按需调整)
GRANT ALL PRIVILEGES ON SCHEMA public TO app1_db_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app1_db_user;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app1_db_user;

最后在Django的settings.py里配置对应的数据库连接:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'app1_db',
        'USER': 'app1_db_user',
        'PASSWORD': '你的强密码',
        'HOST': 'localhost',
        'PORT': '',
    }
}

4. 用uWSGI以专属用户运行Django应用

每个应用配置独立的uWSGI实例,指定运行的系统用户,确保进程权限隔离。

创建uWSGI配置文件/var/www/app1/app1_uwsgi.ini:

[uwsgi]
project = app1
base = /var/www
chdir = %(base)/%(project)
# 指向你的虚拟环境路径
home = %(base)/%(project)/venv
module = %(project).wsgi:application
master = true
processes = 2
# 指定运行该进程的系统用户和组
uid = app1_user
gid = app1_user
# 创建套接字文件,Apache通过这个套接字和uWSGI通信
socket = /run/uwsgi/%(project).sock
# 设置套接字权限,让Apache的组能访问
chmod-socket = 660
vacuum = true
die-on-term = true

然后创建systemd服务文件/etc/systemd/system/app1_uwsgi.service,让应用随系统启动:

[Unit]
Description=uWSGI实例:运行app1应用
After=network.target

[Service]
User=root
Group=root
ExecStart=/var/www/app1/venv/bin/uwsgi --ini /var/www/app1/app1_uwsgi.ini

[Install]
WantedBy=multi-user.target

启动并启用服务:

sudo systemctl daemon-reload
sudo systemctl start app1_uwsgi
sudo systemctl enable app1_uwsgi

5. 配置Apache反向代理规则

为每个应用创建独立的Apache虚拟主机配置,把请求转发到对应的uWSGI套接字:

创建/etc/apache2/sites-available/app1.conf:

<VirtualHost *:80>
    ServerName app1.yourdomain.com

    # 静态文件直接由Apache处理,提升性能
    Alias /static/ /var/www/app1/static/
    <Directory /var/www/app1/static/>
        Require all granted
    </Directory>

    # 将动态请求转发到uWSGI套接字
    ProxyPass / unix:/run/uwsgi/app1.sock|uwsgi://app1/
    ProxyPassReverse / unix:/run/uwsgi/app1.sock|uwsgi://app1/

    # 日志分离,方便排查问题
    ErrorLog ${APACHE_LOG_DIR}/app1_error.log
    CustomLog ${APACHE_LOG_DIR}/app1_access.log combined
</VirtualHost>

启用该站点并重启Apache:

sudo a2ensite app1.conf
sudo systemctl reload apache2
方案优势
  • 权限完全隔离:每个应用有独立的系统用户和数据库用户,无法访问其他应用的资源
  • 维护成本低:只有一个Apache实例需要维护,应用配置模块化,可复用
  • 性能更优:应用服务器(uWSGI)专门处理Django请求,比Apache直接运行效率更高
  • 扩展性强:后续新增应用只需要重复用户、数据库、uWSGI、Apache配置的步骤,非常清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:29:05