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

如何在单个VirtualHost上部署Django与Gatsby(Apache+mod_wsgi)

实现同一域名下Gatsby前端与Django后端的分离部署(Apache+mod_wsgi)

完全理解你的偏好——方案二确实是更优雅的选择,前后端职责清晰,维护起来也更省心,不会把静态托管的逻辑混进Django里。下面就一步步教你配置Apache VirtualHost,实现你想要的访问规则:

核心思路

让Apache同时承担两个角色:

  • 作为静态文件服务器,处理根路径/的所有请求,直接返回Gatsby生成的静态页面
  • 作为WSGI网关,将/api和/admin开头的请求转发给Django的mod_wsgi进程处理

完整VirtualHost配置

先把配置代码贴出来,后面再逐个解释关键部分:

<VirtualHost *:443>
    ServerName my-domain.com

    # SSL证书配置(根据你的实际证书路径调整)
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/my-domain.crt
    SSLCertificateKeyFile /etc/ssl/private/my-domain.key
    SSLCertificateChainFile /etc/ssl/certs/chain.crt # 若使用CA证书链则添加

    # 1. 处理Gatsby前端:根路径指向静态文件目录
    Alias / /var/www/gatsby/public/
    <Directory /var/www/gatsby/public/>
        Options -Indexes +FollowSymLinks
        AllowOverride None
        Require all granted
        
        # 关键:处理Gatsby SPA路由(刷新子页面不会404)
        RewriteEngine On
        RewriteBase /
        RewriteRule ^index\.html$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.html [L]
    </Directory>

    # 2. 配置Django的mod_wsgi运行环境
    WSGIDaemonProcess django \
        python-home=/var/www/django/venv \ # Django虚拟环境路径
        python-path=/var/www/django/project # Django项目根目录(包含settings.py的目录)
    WSGIProcessGroup django

    # 3. 路由/api和/admin请求到Django
    RewriteEngine On
    RewriteCond %{REQUEST_URI} ^/api/ [OR]
    RewriteCond %{REQUEST_URI} ^/admin/
    RewriteRule ^/(.*)$ /var/www/django/project/wsgi.py/$1 [PT]

    WSGIScriptAlias / /var/www/django/project/wsgi.py process-group=django
    <Directory /var/www/django/project>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

    # 关键:允许传递Authorization头给Django(API认证必备)
    WSGIPassAuthorization On
</VirtualHost>

关键配置解释

  1. Gatsby静态文件处理

    • Alias / /var/www/gatsby/public/:把根路径映射到Gatsby构建后的public目录(运行gatsby build生成)
    • 内部的Rewrite规则是为了解决SPA的路由问题:当用户刷新/about这类前端路由时,Apache会把请求转发到index.html,让Gatsby的前端路由去处理,避免404
  2. Django mod_wsgi配置

    • WSGIDaemonProcess:指定Django运行的虚拟环境和项目路径,确保mod_wsgi用正确的Python环境加载Django
    • Rewrite规则:只匹配/api或/admin开头的请求,通过[PT]标志传递给后续的WSGIScriptAlias处理,这样Django收到的请求路径和你在urls.py中配置的一致(比如/api/users就是Django中path('api/users/', ...)对应的路由)
    • WSGIPassAuthorization On:如果你的API使用Token认证(比如JWT),必须开启这个选项,否则Apache会自动丢弃Authorization请求头,导致Django无法识别认证信息

额外准备工作

Gatsby端

  • 运行gatsby build生成静态文件,把public目录放到Apache能访问的路径(比如/var/www/gatsby/public)
  • 确保目录权限正确:设置Apache运行用户(通常是www-data)对该目录有可读权限

Django端

  • 确保ALLOWED_HOSTS包含my-domain.com
  • 运行python manage.py collectstatic把admin的静态文件收集到STATIC_ROOT,并在Apache中配置Alias /static/指向该目录(可选补充配置:Alias /static/ /var/www/django/static/,然后对应Directory权限设置为Require all granted)
  • 安装并配置django-cors-headers,允许Gatsby前端跨域调用API:
    # settings.py
    INSTALLED_APPS = [
        # ...
        'corsheaders',
    ]
    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.common.CommonMiddleware',
        # ...
    ]
    CORS_ALLOWED_ORIGINS = [
        "https://my-domain.com",
    ]
    

为什么方案二更优?

  • 职责分离:Gatsby专注于静态页面构建,Django专注于API和后台管理,各自独立迭代部署
  • 灵活性高:以后如果要替换前端框架(比如换成Next.js),只需要替换静态文件目录,不需要改动Django配置
  • 性能更好:静态文件直接由Apache处理,比通过Django转发效率更高

验证步骤

  1. 重启Apache服务:sudo systemctl restart apache2
  2. 访问https://my-domain.com,确认Gatsby前端正常加载
  3. 访问https://my-domain.com/admin,确认Django后台正常显示
  4. 测试API接口,比如https://my-domain.com/api/hello,确认能返回预期数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:02:30