Nginx 无法在数字海洋上提供 django 静态或媒体文件
Nginx failing to serve django static or media files on digital ocean
当我将 dockerised django 应用程序部署到数字海洋时,我在提供静态文件和媒体文件时遇到问题。我在这里阅读了很多类似的问题,但到目前为止 none 的答案对我有用。
大致按照本指南 https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/#nginx,我现在可以使用以下命令在本地启动我的 docker 容器并让 nginx 提供 static/media 文件完美:
sudo docker-compose -f docker-compose-prod.yml down -v
sudo docker-compose -f docker-compose-prod.yml up -d --build
sudo docker-compose -f docker-compose-prod.yml exec web python manage.py collectstatic --no-input --clear
我现在正尝试在数字海洋水滴上进行同样的工作。在远程服务器上,我 运行 使用与上面完全相同的命令启动服务。除了访问任何静态或媒体文件的能力之外,一切都按预期工作。例如,每当我访问 {my digital ocean ip}/static/admin/css/nav_sidebar.css 时,我都会遇到 404 错误。每当我看到 chrome 试图获取我的自定义 css 时,请求只会显示为“已取消”(然后如果我访问已取消请求的 URL 路径,我会看到相同的 404) .
我的代码可以在这里看到:https://github.com/PaulGilmartin/personal_website
可能与此讨论相关的部分:
nginx.conf
upstream personal_website {
server web:8000;
}
server {
listen 80;
location / {
proxy_pass http://personal_website;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
alias /var/www/personal_website/static/;
}
location /media/ {
alias /var/www/personal_website/media/;
}
}
settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
我特别困惑的是完全相同的命令在本地完美运行。这让我认为远程服务器上的 404 是基于权限的症状,但我不明白为什么会这样,因为在我的 Dockerfile.prod 中我小心翼翼地向非 root 用户发送所有内容.
任何帮助将不胜感激,因为我 运行 对问题可能是什么缺乏想法!
编辑:这是我的 docker-compose 文件:
version: '3.7'
services:
web:
build:
context: .
dockerfile: Dockerfile.prod
command: gunicorn personal_website.wsgi:application --bind 0.0.0.0:8000 --timeout 120
volumes:
- static_volume:/var/www/personal_website/static
- media_volume:/var/www/personal_website/media
env_file:
- ./.env.prod
expose:
- 8000
ports:
- "80:8000"
depends_on:
- db
db:
image: postgres:11
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./.env.prod.db
nginx:
build: ./nginx
volumes:
- static_volume:/var/www/personal_website/static
- media_volume:/var/www/personal_website/media
ports:
- 1337:80
depends_on:
- web
volumes:
postgres_data:
static_volume:
media_volume:
我感觉问题出在这里:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
这个路径实际上应该和nginx期望的一样:
/var/www/personal_website/static/
因此,您可以尝试以下操作:
尝试在 Django 设置中硬编码静态根:
STATIC_ROOT = '/var/www/personal_website/static/'
做bash到Django所在的容器运行ning:docker exec -it <container_name> /bin/bash
-运行那里collectstatic,查看静态文件是否复制到您期望的文件夹。如果没有 - 那么您可能想找到文件被复制的确切位置。
同时检查 nginx 容器内部是否也看到包含静态文件的正确卷
我遇到了完全相同的问题,静态和媒体的硬编码路径解决了这个问题
更新:
我已经克隆了这个项目,对我来说,它没有获取静态文件。所以我在 docker-compose-prod.yml 中做了以下更改,它开始工作了:
从服务中删除 ports - web:
ports:
- "80:8000"
不需要它,因为网络 (Django) 不应从外部访问。仅在公开端口 8000
上的 Docker 内部
设置nginx开放端口为80:
ports:
- 80:80
我不知道 DigitalOcean 使用哪个端口来托管站点,但默认是 80。
当我将 dockerised django 应用程序部署到数字海洋时,我在提供静态文件和媒体文件时遇到问题。我在这里阅读了很多类似的问题,但到目前为止 none 的答案对我有用。
大致按照本指南 https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/#nginx,我现在可以使用以下命令在本地启动我的 docker 容器并让 nginx 提供 static/media 文件完美:
sudo docker-compose -f docker-compose-prod.yml down -v
sudo docker-compose -f docker-compose-prod.yml up -d --build
sudo docker-compose -f docker-compose-prod.yml exec web python manage.py collectstatic --no-input --clear
我现在正尝试在数字海洋水滴上进行同样的工作。在远程服务器上,我 运行 使用与上面完全相同的命令启动服务。除了访问任何静态或媒体文件的能力之外,一切都按预期工作。例如,每当我访问 {my digital ocean ip}/static/admin/css/nav_sidebar.css 时,我都会遇到 404 错误。每当我看到 chrome 试图获取我的自定义 css 时,请求只会显示为“已取消”(然后如果我访问已取消请求的 URL 路径,我会看到相同的 404) .
我的代码可以在这里看到:https://github.com/PaulGilmartin/personal_website 可能与此讨论相关的部分:
nginx.conf
upstream personal_website {
server web:8000;
}
server {
listen 80;
location / {
proxy_pass http://personal_website;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
alias /var/www/personal_website/static/;
}
location /media/ {
alias /var/www/personal_website/media/;
}
}
settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
我特别困惑的是完全相同的命令在本地完美运行。这让我认为远程服务器上的 404 是基于权限的症状,但我不明白为什么会这样,因为在我的 Dockerfile.prod 中我小心翼翼地向非 root 用户发送所有内容.
任何帮助将不胜感激,因为我 运行 对问题可能是什么缺乏想法!
编辑:这是我的 docker-compose 文件:
version: '3.7'
services:
web:
build:
context: .
dockerfile: Dockerfile.prod
command: gunicorn personal_website.wsgi:application --bind 0.0.0.0:8000 --timeout 120
volumes:
- static_volume:/var/www/personal_website/static
- media_volume:/var/www/personal_website/media
env_file:
- ./.env.prod
expose:
- 8000
ports:
- "80:8000"
depends_on:
- db
db:
image: postgres:11
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./.env.prod.db
nginx:
build: ./nginx
volumes:
- static_volume:/var/www/personal_website/static
- media_volume:/var/www/personal_website/media
ports:
- 1337:80
depends_on:
- web
volumes:
postgres_data:
static_volume:
media_volume:
我感觉问题出在这里:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
这个路径实际上应该和nginx期望的一样:
/var/www/personal_website/static/
因此,您可以尝试以下操作:
尝试在 Django 设置中硬编码静态根:
STATIC_ROOT = '/var/www/personal_website/static/'
做bash到Django所在的容器运行ning:
docker exec -it <container_name> /bin/bash
-运行那里collectstatic,查看静态文件是否复制到您期望的文件夹。如果没有 - 那么您可能想找到文件被复制的确切位置。同时检查 nginx 容器内部是否也看到包含静态文件的正确卷
我遇到了完全相同的问题,静态和媒体的硬编码路径解决了这个问题
更新: 我已经克隆了这个项目,对我来说,它没有获取静态文件。所以我在 docker-compose-prod.yml 中做了以下更改,它开始工作了:
从服务中删除 ports - web:
ports: - "80:8000"
不需要它,因为网络 (Django) 不应从外部访问。仅在公开端口 8000
上的 Docker 内部设置nginx开放端口为80:
ports: - 80:80
我不知道 DigitalOcean 使用哪个端口来托管站点,但默认是 80。