Docker、Nginx和Django如何提供静态文件服务

8
目标: 为生产环境的Django网站部署设置Docker容器集合。
我在这个过程中卡住了,因为通常情况下nginx会直接提供静态文件... 根据我对使用docker的良好架构的理解,您将需要一个用于您的WSGI服务器(可能是Gunicorn)的容器,一个单独的Nginx容器,其中上游服务器配置指向您的Gunicorn容器。Nginx容器可以在多个Gunicorn容器之间进行负载均衡。
但这意味着我必须在Nginx容器中安装我的Django应用程序的静态文件,这似乎是不好的实践,因为它的主要目标实际上是负载均衡。
是否最好拥有三个容器:nginx、gunicorn和一个专用静态服务器(可能是Nginx或Lighthttpd)用于静态文件?
3个回答

3

关于提供静态文件的问题,您的选择取决于应用程序的功能。有一个非常方便的工具叫做 dj-static,它将通过添加非常少的代码来帮助您提供静态文件。

文档相当简单,您只需要按照这些步骤操作即可。


这导致我的设置出现了错误网关(在调整Django应用程序以与dj-static配合工作之前,它是正常工作的)。 - AndrewSmiley
我需要在我的gunicorn docker上提供静态文件的服务。dj-static完美地解决了这个问题。 - anber

3
我从Michael Hampton那里找到了这个答案: “这只在进程在同一主机、虚拟机或容器中时才有效,因为它试图连接到同一台机器。当它们在不同的容器中时,它不起作用。
您需要更改nginx配置,以便使用uwsgi容器的内部IP地址。” 帖子链接 如果您将Nginx放在不同的容器中,绝对是需要牢记的事情,还必须设置nginx.conf,将静态文件目录指向别名,以防止安全问题。
我希望这段代码适用于每个人,花了我几个小时才想出如何组合Gunicorn、Docker和Nginx:
# nginx.conf
  upstream djangoA {
       server $DOCKER_CONTAINER_SERVICE:9000 max_fails=3 fail_timeout=0;
       # In my case looks like: web:9000
  }
Server {
    include mime.types;
    # The port your site will be served on      
    listen 80;
    # the domain name it will serve for
    server_name $YOUR_SERVER_NAME;# substitute your machine's IP address or FQDN
    charset utf-8;
    #Max upload size
    client_max_body_size 512M;   # adjust to taste
    location /site_media {
       alias $DIRECTORY_STATIC_FILES/site_media;#your Django project's media   files have to be inside of the container have nginxs, you can copy them with volumes.
    expires 30d;
    }

    location / {
      try_files $uri @proxy_to_app;
    }

   # Finally, send all non-media requests to the Django server.
   location @proxy_to_app {
     proxy_set_header X-Real-IP $remote_addr;
     proxy_redirect off;
     proxy_set_header Host $host;
     proxy_pass http://djangoA;
   }
}

而对于 docker-compose:

#production.yml
version: '2'

services:
  db:
    extends:
      file: base.yml
      service: db

  nginx:
    image: nginx:latest
  volumes:
      - ./nginx:/etc/nginx/conf.d/
      - ./$STATIC_FILE_ROOT/site_media:/$STATIC_FILE_ROOT/site_media
  ports:
      - "80:80"
    depends_on:
      - web


  web:
    extends:
      file: base.yml
      service: web
    build:
      args:
        - DJANGO_ENV=production
    command: bash -c "python manage.py collectstatic --noinput && chmod 775 -R project/site_media/static && gunicorn project.wsgi:application"
    volumes:
      - ./$DIRECTORY_APP:/$DIRECTORY_APP
    ports:
      - "9000:9000"
    depends_on:
      - db

volumes:
  db_data:
    external: true

0
如果是使用docker和/或kubernetes的django应用程序,请查看whitenoise http://whitenoise.evans.io/en/stable/以提供解决方案。
这是一个直接的建议,但在我找到它的参考之前,我花了很多时间搜索。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接