如何使用 django docker nginx 和 postgresql 制作静态文件,因为它不为它们提供服务

cu_*_*007 18 django django-staticfiles docker docker-compose

当我尝试访问时http://127.0.0.1:8000/admin,我得到了这个。

在此输入图像描述

我的文件夹结构是:

django-react-nginx
|
|_ _ docker-compose.yml
|
  > backend
        |
        |_ Dockerfile
        |
        |_ entrypoint.sh

     > languages
          |
          |_ settings.py
     > media
     > static # This folder appears after running docker-compose -d --build
  > nginx
      |
      |_ default.conf
      |
      |_ Dockerfile
Run Code Online (Sandbox Code Playgroud)

现在

这是文件

姜戈

设置.py

DEBUG = True

ALLOWED_HOSTS = ['*']

STATIC_URL = '/static/'

STATIC_ROOT = os.path.join(BASE_DIR, 'static')

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')        

MEDIA_URL = '/media/'

Run Code Online (Sandbox Code Playgroud)

Docker 文件

FROM python:3.8

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

WORKDIR /backend

COPY  requirements.txt /backend/

RUN pip install -r requirements.txt && \
    pip install --upgrade pip

COPY ./entrypoint.sh /

ENTRYPOINT ["sh", "/entrypoint.sh"]

Run Code Online (Sandbox Code Playgroud)

入口点.sh

#!/bin/sh

python manage.py migrate --no-input

python manage.py collectstatic --no-input

gunicorn languages.wsgi:application --bind 0.0.0.0:8000

Run Code Online (Sandbox Code Playgroud)

nginx

默认配置文件

upstream django {
    server backend:8000;
}

server {
    listen 80;

    location / {
        proxy_pass http://django;
    }

    location /static/ {
        autoindex on;
        alias /backend/static;
    }

    location /media/ {
        autoindex on;
        alias /backend/static;
    }

}
Run Code Online (Sandbox Code Playgroud)

Dockerfile

FROM nginx:1.19.8-alpine

COPY ./default.conf  /etc/nginx/conf.d/default.conf

Run Code Online (Sandbox Code Playgroud)

根文件夹

Docker-compose

version: "3.7"

services:
  backend:
    build: ./backend/languages
    stdin_open: true # interactive
    tty: true        # interactive
    restart: "on-failure"
    env_file:
      .env
    volumes:
      - ./backend/languages:/backend
      - ./backend/languages/static:/backend/static
    ports:
      - 8000:8000
    networks:
      - nginx_network
      - db_network
    depends_on:
      - db
  db:
    image: postgres:11
    restart: "on-failure"
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    networks:
      - db_network
  
  nginx:
    build: ./nginx
    restart: always
    volumes:
      - ./backend/languages:/backend
      - ./backend/languages/static:/static
    ports:
      - 80:80
    networks:
      - nginx_network
    depends_on:
      - backend

networks:
  nginx_network:
    driver: bridge
  db_network:
    driver: bridge

volumes:
  postgres_data:

Run Code Online (Sandbox Code Playgroud)

如上所述,我不确定如何使静态文件工作,它们被复制到上面提到的文件夹中,因为当我可以看到创建的文件夹并且当我检查日志时我得到这个165 static files copied to '/backend/static'.

Iva*_*tin 12

Nginx 配置

Nginx 配置看起来不错。容器映射到/backend/languages/staticwith/static并且别名指向容器内的同一文件夹 - /static

nginx.conf

location /static/ {
        autoindex on;
        alias /static;
    }
Run Code Online (Sandbox Code Playgroud)

检测到更新问题:别名必须具有相同的结尾斜杠才能正常工作。所以它必须是alias /static/

nginx 正在撰写

  nginx:
    ...
    volumes:
      - ./backend/languages:/backend
      - ./backend/languages/static:/static
Run Code Online (Sandbox Code Playgroud)

Django 配置

但 Django 配置看起来已损坏。在这里,您已配置为将静态数据收集到其中的static文件夹中 BASE_DIR

设置.py

STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')        
Run Code Online (Sandbox Code Playgroud)

这正是collectstatic向您报告的内容:

165 static files copied to '/backend/static'

文件位于/backend/static,而不是/static. 然而,容器被配置为根文件夹/static

Django 中的 compose

  backend
    ...
    volumes:
      - ./backend/languages:/backend
      - ./backend/languages/static:/static
Run Code Online (Sandbox Code Playgroud)

看起来这个问题可以通过指向来解决

    volumes:
      - ./backend/languages/static:/backend/static
Run Code Online (Sandbox Code Playgroud)

尽管如此,仍有一些工作要做:Django 不应该提供媒体文件,因此建议配置 Nginx 来提供媒体文件。

Django Dockerfile

我相信映射./backend/languages:/backend是有效的,但是 Docker 化有什么意义呢?此 docker 镜像中没有应用程序,只有依赖项。在映像中包含源是“更好”的,因此最终的部署只需要更新映像并重新启动容器。

因此,作为旁注,我建议(至少尝试):

  • 更新配置以使用 Nginx 提供媒体文件
  • 将 django 应用程序源包含在您的 docker 镜像中
  • 在构建过程中收集静态文件,而不是将它们包含到 docker 镜像中
  • collectstaticentrypoint
  • 提供静态文件并将它们视为单独的产品,如果您要将它们交付到 CDN(单独的托管),请考虑它们 - 这是一个非常常见的解决方案
  • 当它们仍然位于同一主机上时,继续将它们映射到容器,就像现在一样,但以“相反”的方式:将静态文件传递到主机文件夹,以ro模式从容器访问它们

  • 并不真地。在 prod 上和/或 Debug=False 时,Django 不应提供静态文件或媒体文件。这些 url 模式仅在 Debug=True 时有效,并且对产品没有好处。 (2认同)