gpt4 book ai didi

Django-Nginx-Gunicorn 使用 Docker Compose 返回错误的媒体文件路径

转载 作者:行者123 更新时间:2023-12-04 10:05:46 24 4
gpt4 key购买 nike

我在使用 docker compose 在生产模式下部署 Django REST 框架应用程序时遇到了问题。问题是当我的端点返回带有 ImageField 的模型时,它返回错误的路径,特别是缺少 url 端口。静态文件与响应 url 中包含的端口一起工作正常。

例如:

当前值:http://127.0.0.1/media/machines/034793bb-8516-45e3-a50a-4e00e7488617.png

预期:http://127.0.0.1:8000/media/machines/034793bb-8516-45e3-a50a-4e00e7488617.png

设置.py

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATE_DIR = os.path.join(BASE_DIR, 'templates')
STATIC_DIR = os.path.join(BASE_DIR,'static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

STATIC_URL = '/static/'
STATIC_ROOT = '/app/static/'

** Docker 文件 **
FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir /app
WORKDIR /app
ADD . /app/
RUN pip install -r requirements.txt

CMD ["gunicorn", "-c", "config/gunicorn/conf.py", "--bind", ":8000", "--chdir",
"app_api.wsgi:application"]

Docker-compose
version: '3.7'

services:
web-service:
build: .
command: bash -c "pip install -r requirements.txt && python manage.py makemigrations && python
manage.py migrate && python manage.py collectstatic --noinput && python manage.py runserver
0.0.0.0:8000"
container_name: app_backend
volumes:
- static:/app/static
- media:/app/media
- .:/app
depends_on:
- db
restart: on-failure:2
db:
image: postgres
container_name: app_postgres
environment:
- POSTGRES_USER=bd_user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=new_database
ports:
- "5432:5432"
volumes:
- postgres:/var/lib/postgresql/data
restart: on-failure:2
nginx:
image: nginx:latest
ports:
- 8000:80
volumes:
- ./config/nginx/conf.d:/etc/nginx/conf.d
- static:/app/static
- media:/app/media
depends_on:
- web-service
volumes:
media:
static:
postgres:
driver: local

Nginx 配置文件
upstream django_server {
server web-service:8000;
}

server {
listen 80;
server_name localhost;

location /static/ {
alias /app/static/;
}

location /media/ {
alias /app/media/;
}

location / {
proxy_pass http://django_server;
proxy_set_header X-Fowarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}

** Gunicorn 配置 **
name = 'docker_django'
loglevel = 'info'
errorlog = '-'
accesslog = '-'
workers = 2

型号
class Machine(models.Model):
name = models.CharField(max_length=100, blank=False, null=False)
description = models.CharField(max_length=250, blank=True, null=True)
image = models.ImageField(upload_to = 'machines', default='default.png')
provider = models.TextField(blank=True, null=True)
model = models.CharField(max_length=250, blank=True, null=True)
data_source = models.ForeignKey(DataSource, related_name='data_source', on_delete=models.CASCADE)

def __str__(self):
return self.name

最佳答案

最简单的选择是使用 $http_host在 nginx 而不是 $host因为 $host不包含端口信息。然而$http_host某些客户端可能为空。

        proxy_set_header Host $host;

Differences described in this SO answer

由于 nginx 对 8000 一无所知它在 docker 主机上公开的端口没有办法设置它。一种选择是采取 Host来自请求的 http header (请求中可能不存在,可能在某些极少数情况下)。

另一种选择是将端口 nginx 作为环境变量公开到 nginx 容器中,并在附加到 $host 的配置中使用此变量。对于 nginx 可以用 envsubst 来完成。在自定义入口点运行。

它适用于静态文件的原因 - 静态文件 url 包含在模板(不是 api 响应)中,并带有相对于当前网站根目录(无论它是什么)的链接,并且它们不需要 build_absolute_uri()由 Django 运行。

关于Django-Nginx-Gunicorn 使用 Docker Compose 返回错误的媒体文件路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61599811/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com