Docker 如何将 Django + uwsgi/gunicorn + nginx 连接起来?

Docker 如何将 Django + uwsgi/gunicorn + nginx 连接起来?

我无法弄清楚部署使用 uwsgi/gunicorn 的 Django 项目的“正确”方法是什么(我还没有决定使用什么,可能是 uwsgi,因为它的性能更好,有什么建议吗?)和使用 docker 的 nginx。

我看到有些人把所有东西都放在同一个容器中。我不是 docker 专家,但容器应该只做一件事。因此,拥有 Django + nginx 似乎是 2 而不是 1。

现在,我对部署的想法是:

  • 一个包含 Django 和 uwsgi 的容器。在 Dockerfile 的末尾,我运行 uwsgi 脚本。此容器公开端口 8000
  • 一个带有 nginx 的容器,链接到 django one。这会公开端口 80 并将请求代理到 django。

还有其他方法吗?有没有更深入地介绍这种情况的教程。我需要一个可靠的产品,而不仅仅是在我的 PC 上测试一些代码。

答案1

我目前正在按照您想要的方式构建一个 django 应用程序。

我使用 docker-compose 来执行此操作。这是我的 docker-compose.yml

version: '2'
services:
  nginx:
    container_name: nginx-container
    links:
      - uwsgi
    build: ./nginx
    ports:
      - "8888:80"
    volumes_from:
      - uwsgi
  uwsgi:
    container_name: uwsgi-container
    build: ./uwsgi
    expose:
      - "8001"
    volumes:
      - ./code/conf:/opt/conf
      - ./code/app:/opt/app

uWSGI的Dockerfile:

FROM python:3.5
RUN ["pip", "install", "uwsgi"]
CMD ["uwsgi", "--master", "--ini", "/opt/conf/uwsgi.ini"]

nginx 的 Dockerfile:

FROM nginx
RUN ["rm", "/etc/nginx/conf.d/default.conf"]
RUN ["ln", "-s", "/opt/conf/nginx.conf", "/etc/nginx/conf.d/"]
CMD ["nginx", "-g", "daemon off;"]

这是我的目录树:

├── README.md
├── code
│   ├── app
│   └── conf
├── collectstatic.sh
├── docker-compose.yml
├── install.sh
├── migrate.sh
├── nginx
│   └── Dockerfile
├── restart.sh
├── upgrade.sh
├── uwsgi
│   └── Dockerfile

因此,我使用构建我的图像,docker-compose build然后在后台启动新的容器,然后docker-compose up -d我可以执行一些设置任务,例如安装 django、生成密钥或任何您希望让您的容器准备好的任务。

nginx 和 uwsgi 容器使用共享卷来读取配置文件并与文件套接字进行通信。

嗯,不确定这是否是最好的方法,但这是一个正在进行的工作。

答案2

我从中找到了这个答案迈克尔·汉普顿

“这仅当进程位于同一主机、虚拟机或容器中时才有效,因为它尝试连接到同一台机器。当它们位于不同的容器中时,它不起作用。

您需要改变您的 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

答案3

我最终成功为 Django、Gunicorn、Nginx 和 Postgres 构建了 docker-compose,这主要归功于本教程

基本上,您有一个用于 Nginx 的容器、一个用于 Django+Gunicorn 的容器和一个用于 Postgres 的容器(如果您想要多个数据库,则可能有更多容器)。

您也可以将 Django+Gunicorn 拆分为两个容器,但我认为将它们都放在一个容器中更有意义,因为一个 Gunicorn 进程始终运行一个 Django wsgi 应用程序。我认为您不可能让 N 个 Gunicorn 运行 1 个 Django,也不可能让 1 个 Gunicorn 运行 N 个 Django,也不可能让 N 个 Gunicorn 运行 N 个 Django,因此这里没有扩展的可能性,除了扩展 N 个 Gunicorn+Django 容器。

卷用于永久保存数据库的数据(以及可选的 Django 的静态/媒体文件)。

您要求提供教程或其他方法,因此我不会在此处发布我的 docker-compose.yml 内容(因为它还需要 Dockerfile、Nginx conf 文件、Gunicorn conf 文件、数据库环境文件和许多 Python 代码片段,如数据库设置),但我会在有时间时尝试制作一个教程并在编辑/评论中发布链接。

同时,我上面提供的链接是一个很好的起点。

编辑:你现在可以看看这个docker 设置示例以及相关博客文章

相关内容