共享主机passenger_wsgi部署Django时静态文件403错误求助
共享主机Passenger部署Django静态文件403错误解决方案建议
问题背景
在共享主机通过Passenger_wsgi部署Django应用,主域名可正常运行并读取数据库,但访问静态资源(CSS/JS/Images)时出现403错误。相关配置及环境信息如下:
文件夹结构
public_html django static css js images SMC_website templates
核心配置
settings.py:
STATIC_URL = 'static/' STATICFILES_DIRS = [ '/home/xxxxxx/public_html/django/static/', '/home/xxxxxx/public_html/django/static/css', '/home/xxxxxx/public_html/django/static/js', '/home/xxxxxx/public_html/django/static/images', ]
urls.py:
urlpatterns = [ path('admin/', admin.site.urls), re_path(r"^$", views.index, name="Home Page"), ] urlpatterns += static(settings.STATIC_URL, document_root=os.path.join(settings.BASE_DIR, 'static'))
权限信息
drwxr-x--- 2 xxxxxx xxxxxx 4096 Dec 17 18:30 css drwxr-x--- 8 xxxxxx xxxxxx 4096 Dec 17 18:30 images drwxr-x--- 3 xxxxxx xxxxxx 4096 Dec 17 18:30 js drwxr-xr-x 5 xxxxxx xxxxxx 4096 Dec 11 14:24 SMC_website drwxr-xr-x 3 xxxxxx xxxxxx 4096 Dec 11 14:24 logs -rw-r--r-- 1 xxxxxx xxxxxx 689 Dec 11 14:24 manage.py -rw-r--r-- 1 xxxxxx xxxxxx 1442 Dec 17 18:08 passenger_wsgi.py -rw-r--r-- 1 xxxxxx xxxxxx 245760 Dec 11 14:24 smcDB.sqlite3 drwxr-xr-x 10 xxxxxx xxxxxx 4096 Dec 11 14:31 static
额外现象
- 在
manage.py shell中执行static(settings.STATIC_URL, document_root=os.path.join(settings.BASE_DIR, 'static'))返回空列表[] - 浏览器请求静态资源的URL正确,例如:
<script type="text/javascript" src="https://southmetrochorale.org/static/js/smc.js"></script>
问题根源分析
static()返回空列表是正常现象:生产环境下(DEBUG=False),Django不会生成静态文件的URL路由,因为生产环境应由Web服务器直接处理静态资源,而非Django框架。此现象不是403错误的原因。- 文件夹权限不足:静态子目录(css/js/images)的权限为
drwxr-x---,仅允许所属用户和用户组访问,而Web服务器运行的系统用户(如apache、www-data)不在该用户组内,无法读取目录内容,导致403权限拒绝。 - 静态资源配置不符合生产环境规范:未使用
STATIC_ROOT收集静态资源,而是依赖STATICFILES_DIRS,且配置冗余(重复添加根目录和子目录),导致Web服务器无法正确定位资源。
具体解决步骤
1. 修复静态资源目录权限
给静态文件及所有子目录添加其他用户的读取和执行权限(Web服务器需要遍历目录并读取文件):
chmod -R o+rx /home/xxxxxx/public_html/django/static/
执行后,子目录权限应变为drwxr-xr-x,确保Web服务器用户可访问。
2. 配置生产环境静态资源收集
生产环境需将所有静态文件统一收集到指定目录,便于Web服务器直接处理:
- 修改
settings.py,添加STATIC_ROOT并简化STATICFILES_DIRS:STATIC_URL = 'static/' # 统一收集静态文件的目录 STATIC_ROOT = '/home/xxxxxx/public_html/django/static_collected/' # 仅保留静态资源根目录即可,无需重复添加子目录 STATICFILES_DIRS = [ '/home/xxxxxx/public_html/django/static/', ] - 执行收集命令,将所有静态文件复制到
STATIC_ROOT:
执行时确认覆盖提示,完成后python manage.py collectstaticstatic_collected目录会包含所有静态资源。
3. 配置Web服务器直接处理静态URL
通过.htaccess文件让Web服务器(Apache/Nginx)直接响应/static/请求,指向收集后的静态目录:
在public_html/django目录下创建或修改.htaccess文件:
Alias /static /home/xxxxxx/public_html/django/static_collected <Directory /home/xxxxxx/public_html/django/static_collected> Require all granted Options -Indexes </Directory>
此配置会将所有/static/开头的请求直接映射到static_collected目录,绕过Django处理,提升性能并解决权限问题。
4. 确认生产环境配置
确保settings.py中DEBUG = False,生产环境开启DEBUG会带来安全风险,且Django不会自动处理静态资源。
内容的提问来源于stack exchange,提问作者Volker Petersen
相关产品推荐
相关产品推荐

