用nginx,django,daphne部署到docker

我想将我的服务部署到docker

而我的服务是使用python + django和django-channels开发的

── myproject ├── myproject │ ├── settings.py │ ├── urls.py │ ├── asgi.py │ ├── ... ├── collected_static │ ├── js │ ├── css │ ├── ... ├── nginx │ ├── Dockerfile │ ├── service.conf ├── requirements.txt ├── manage.py ├── Dockerfile └── docker-compose.yml

myproject / Dockerfile:

 FROM python ENV PYTHONUNBURRERED 1 RUN mkdir -p /opt/myproject WORKDIR /opt/myproject ADD . /opt/myproject RUN pip install -r requirements.txt RUN python manage.py migrate 

MyProject的/泊坞窗,compose.yml:

 version: '2' services: nginx: build: ./nginx networks: - front - back ports: - "80:80" depends_on: - daphne redis: image: redis networks: - "back" ports: - "6379:6379" worker: build: . working_dir: /opt/myproject command: bash -c "python manage.py runworker" environment: - REDIS_HOST=redis networks: - front - back depends_on: - redis links: - redis daphne: build: . working_dir: /opt/myproject command: bash -c "daphne -b 0.0.0.0 -p 8000 myproject.asgi:channel_layer" ports: - "8000:8000" environment: - REDIS_HOST=redis networks: - front - back depends_on: - redis links: - redis networks: front: back: 

的myproject / nginx的/ Dockerfile

 FROM nginx COPY service.conf /etc/nginx/sites-enabled/ 

的myproject / nginx的/ service.conf

 server { listen 80; server_name example.com #i just want to hide domain name.. charset utf-8; client_max_body_size 20M; location /static/ { alias /opt/myproject/collected_static/; } location / { proxy_pass http://0.0.0.0:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; } } 

我写了一个命令docker-compose up -d ,Nginx和达芙妮工作良好。

但是当我连接到example.com:80,我只能看到nginx的默认页面。

当我连接到example.com:8000时,我只能看到我的项目的服务页面。 (但不能看到静态文件)

我想链接nginx和daphne服务! 我该怎么办? 请帮帮我。

  • 当我只用nginx + daphne + django部署没有docker的时候,我的服务运行良好。

你错误地配置了NGINX。 试试proxy_pass http://127.0.0.1:8000;

至于静态文件,这是因为你还没有使容器可用的文件。 我会建议进行以下修改:

MyProject的/ Dockerfile:

 [...] ADD . /opt/myproject VOLUME ["/opt/myproject/collected_static"] [..] # may I also suggest automatic static file collection? RUN python manage.py collectstatic --noinput 

MyProject的/泊坞窗,compose.yml:

 [...] build: ./nginx volumes_from: - "worker" # or daphne 

我也会考虑添加image选项,以达芙妮和工人服务。 这将标记图像,并允许重复使用它,因此它将只被建立一次(而不是两次)。

 myproject: build: . image: "myproject:latest" [..] worker: image: "myproject:latest" [..] daphne: image: "myproject:latest" 

TLDR;

Nginx配置不正确,但是你的docker-compose需要一些修正:

Nginx的

Nginx网站提供了一些Docker部署的有用提示,你应该阅读,包括一个简单的Dockerfile示例:

 FROM nginx RUN rm /etc/nginx/conf.d/default.conf RUN rm /etc/nginx/conf.d/example_ssl.conf COPY content /usr/share/nginx/html COPY conf /etc/nginx 

这指向您需要做的一些改进(请参阅Docker Compose部分以获得有关Docker的进一步帮助)。

考虑到我们将在下面进行部署的更新,您还需要更改您的Nginx配置:

  • 重命名service.conf – > service.template
  • 改变listen ${NGINX_PORT};
  • 更改server_name ${NGINX_HOST};
  • 更改proxy_pass http://${DAPHNE_HOST}:${DAPHNE_PORT};

Docker撰写

现在你的Nginx配置是正确的,你需要正确设置docker compose指令,谢天谢地, Docker Hub Nginx页面有一个docker compose的例子:

这里是一个使用docker-compose.yml的例子:

 web: image: nginx volumes: - ./mysite.template:/etc/nginx/conf.d/mysite.template ports: - "8080:80" environment: - NGINX_HOST=foobar.com - NGINX_PORT=80 command: /bin/bash -c "envsubst < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" 

然后mysite.template文件可能包含这样的变量引用:

 listen ${NGINX_PORT}; 

从r00m的答案

您可以进行所有这些改进,实际上,在不共享卷的情况下,您的静态文件将无法正确提供。

  • 为项目创建一个图像并重新使用它
  • 添加卷引用以允许共享静态文件
  • 可选的:你也应该遵循关于收集静态文件的建议,但是你的项目结构表明你已经做到了。

把它一起

最后,我们可以合并这三个改进,给我们以下的设置:

MyProject的/ Dockerfile:

 FROM python ENV PYTHONUNBURRERED 1 RUN mkdir -p /opt/myproject WORKDIR /opt/myproject ADD . /opt/myproject RUN pip install -r requirements.txt RUN python manage.py migrate # Can this be done during build? ie no link to the DB? VOLUME ["/opt/myproject/collected_static"] 

MyProject的/泊坞窗,compose.yml:

 version: '2' services: nginx: build: ./nginx networks: - front - back ports: - "80:80" volumes_from: - "daphne" environment: - NGINX_HOST=example.com - NGINX_PORT=80 - DAPHNE_HOST=daphne - DAPHEN_PORT=8000 depends_on: - daphne links: - daphne command: /bin/bash -c "envsubst < /etc/nginx/conf.d/service.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" redis: image: redis networks: - "back" ports: - "6379:6379" daphne: build: . image: "myproject:latest" working_dir: /opt/myproject command: bash -c "daphne -b 0.0.0.0 -p 8000 myproject.asgi:channel_layer" ports: - "8000:8000" environment: - REDIS_HOST=redis networks: - front - back depends_on: - redis links: - redis worker: image: "myproject:latest" working_dir: /opt/myproject command: bash -c "python manage.py runworker" environment: - REDIS_HOST=redis networks: - front - back depends_on: - redis links: - redis networks: front: back: 

的myproject / nginx的/ Dockerfile

 FROM nginx RUN rm /etc/nginx/conf.d/default.conf RUN rm /etc/nginx/conf.d/example_ssl.conf COPY service.template /etc/nginx/conf.d 

的myproject / nginx的/ service.template

 server { listen ${NGINX_PORT}; server_name ${NGINX_HOST} charset utf-8; client_max_body_size 20M; location /static/ { alias /opt/myproject/collected_static/; } location / { proxy_pass http://${DAPHNE_HOST}:${DAPHNE_PORT}; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; } } 

最后的想法

  • 我不确定你想用你的网络指令来达到什么目的,但是它几乎肯定无法实现它,例如nginx不应该连接到你的后端网络(我想…)。
  • 您需要考虑是否应该在构建时或运行时进行“迁移”。
  • 你需要能够轻松地改变你的nginx配置吗? 如果是这样,您应该从nginx构建中删除COPY,并从Docker Compose部分添加volumes指令。