【问题标题】:Serving static files with Ngnix, Django and Docker使用 Nginx、Django 和 Docker 提供静态文件
【发布时间】:2019-02-22 22:13:09
【问题描述】:

我对 Nginx 和 Docker 还很陌生,目前正面临有关 docker 容器设置的问题。该设置由三个容器组成:Nginx、Django 和 Postgres。它在大多数情况下都按预期工作,但是我无法通过 Nginx 访问静态文件。

这里是 nginx.conf:

user nginx;
worker_processes  1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
  worker_connections 1024;
}
http {
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
  log_format main '$remote_addr - $remote_user [$time_local]'
                  '"$request" $status $body_bytes_sent'
                  '"$http_referer" "$http_user_agent"'
                  '"$http_x_forwarded_for"';
  access_log /var/log/nginx/access.log main;
  upstream server {
    server server:8000;
  }
  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name localhost;
    charset utf-8;
    root /usr/share/nginx/html;
    index index.html;
    location / {
      try_files $uri $uri/ @rewrites;
    }
    location @rewrites {
      rewrite ^(.+)$ /index.html last;
    }
    location ^~ /static/ {
      autoindex on;
      alias /usr/share/nginx/html/static/; 
    }
    location ~ ^/api {
      proxy_pass http://server;
    }
    location ~ ^/admin {
      proxy_pass http://server;
    }
  }
}

当我访问地址 localhost:8000/static 时,我希望 Nginx 能够为 /usr/share/nginx/html/static/ 提供服务。我确实检查了 /usr/share/nginx/html/static/ 的容器 fs,并且存在静态文件。

这里是 docker-compose.yml:

version: "3"
services:
  nginx:
    container_name: nginx
    build:
      context: .
      dockerfile: ./nginx/Dockerfile
    image: nginx
    restart: always
    volumes:
      - ./server/static:/usr/share/nginx/html/static
    ports:
      - 80:80
    depends_on:
      - server
    command: nginx -g 'daemon off';
  server:
    container_name: server
    build:
      context: ./server
      dockerfile: Dockerfile
    hostname: server
    ports:
      - 8000:8000
    volumes:
      - ./server:/src/project
    depends_on:
      - "db"
    restart: on-failure
    env_file: .env
    command: >
      bash -c '
      python manage.py makemigrations &&
      python manage.py migrate &&
      gunicorn project.wsgi -b 0.0.0.0:8000'
  db:
    container_name: postgres
    image: postgres:latest
    hostname: postgres
    ports:
      - 5432:5432
    volumes:
      - /var/lib/postgresql/data

文件夹./server/static 包含所有通过python manage.py collectstatic 组装的静态文件,并将它们添加到卷/usr/share/nginx/html/static。但是,当我尝试访问静态文件时,f.e.在 localhost:8000/admin,我收到有关缺少 css 文件(base.css、login.css、..)的警告。

【问题讨论】:

  • 你的 Nginx 服务器设置为 listen 80; 它不会在端口 8000 上处理任何请求

标签: django docker nginx


【解决方案1】:

您正在寻找基于错误假设的解决方案,因为您自己并没有出现在材料中。如果您只想拥有一个有效的设置然后稍后理解它,那很好。你不是第一个使用 Docker 进行 Django 开发的人,所以看看周围吧:

what Docker has already done。这不是唯一的方法,当然也不是多个方面的最佳方法。

如果您真的想要基于 Nginx 的设置,那么 Real Python 有一个非常好的示例。

为什么您的设置无法正常工作并且您的修复不是改进的原因:

  • 你使用 http 协议,WSGI 更适合这个
  • 您的解决方案假定静态文件必须由 Django 提供。他们不能。 Nginx 在这方面要好得多,但如果您处于项目的早期阶段,可能会添加大量新的静态文件,那么使用 Nginx 为它们提供服务实际上会有点慢。
  • 所以...您应该阅读virtually anyone seems to skip 的文档。

【讨论】:

  • 嗨@MelvynSopacua,感谢您的回答。我之前已经阅读了所有这三个来源,它们确实有所帮助。我设置的实际目标是永远不会通过 Django 提供静态文件,正如你提到的那样,我做了错误的假设。当前设置通过 Nginx 提供静态反应构建以及来自 Django 的静态文件。
【解决方案2】:

更新: 对于任何想知道的人,我不得不将 docker-compose 文件中的 nginx port 更改为 8000,这样从客户端到 localhost:8000 的请求将由 nginx 而不是服务器直接处理。考虑到这一点,我还将 docker-compose 文件中的服务器端口更改为 expose 以便它只能在内部访问。但是,这也会阻止您访问 django 的管理部分。

这里是 nginx.conf:

user nginx;
worker_processes  1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
  worker_connections 1024;
}
http {
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
  log_format main '$remote_addr - $remote_user [$time_local]'
                  '"$request" $status $body_bytes_sent'
                  '"$http_referer" "$http_user_agent"'
                  '"$http_x_forwarded_for"';
  access_log /var/log/nginx/access.log main;
  upstream server {
    server server:8000;
  }
  server {
    listen 8000 default_server;
    listen [::]:8000 default_server;
    server_name localhost;
    charset utf-8;
    root /usr/share/nginx/html;
    index index.html;
    location / {
      try_files $uri $uri/ @rewrites;
    }
    location @rewrites {
      rewrite ^(.+)$ /index.html last;
    }
    location ^~ /static/ {
      autoindex on;
      alias /usr/share/nginx/html/static/; 
    }
    location ~ ^/api {
      proxy_pass http://server;
    }
    location ~ ^/admin {
      proxy_pass http://server;
    }
  }
}

这里是 docker-compose.yml:

version: "3"
services:
  nginx:
    container_name: nginx
    build:
      context: .
      dockerfile: ./nginx/Dockerfile
    image: nginx
    restart: always
    volumes:
      - ./server/static:/usr/share/nginx/html/static
    ports:
      - 8000:8000
      - 80:8000
    depends_on:
      - server
    command: nginx -g 'daemon off';
  server:
    container_name: server
    build:
      context: ./server
      dockerfile: Dockerfile
    hostname: server
    expose:
      - "8000"
    volumes:
      - ./server:/src/project
    depends_on:
      - "db"
    restart: on-failure
    env_file: .env
    command: >
      bash -c '
      python manage.py makemigrations &&
      python manage.py migrate &&
      gunicorn project.wsgi -b 0.0.0.0:8000'
  db:
    container_name: postgres
    image: postgres:latest
    hostname: postgres
    ports:
      - 5432:5432
    volumes:
      - /var/lib/postgresql/data

【讨论】:

    猜你喜欢
    • 2023-03-05
    • 2019-05-31
    • 2017-11-19
    • 2014-10-05
    • 2013-06-27
    • 2021-12-02
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多