使用Nginx,Django,Daphne部署到Docker [英] Deploy to docker with nginx, django, daphne
问题描述
我想将服务部署到Docker.
I want to deploy my service to docker.
我的服务是使用python + django和django-channels开发的
and my service is developed using python+django and 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
├── 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:
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/docker-compose.yml:
myproject/docker-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
myproject/nginx/Dockerfile
FROM nginx
COPY service.conf /etc/nginx/sites-enabled/
myproject/nginx/service.conf
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和daphne很好用.
and i write a command docker-compose up -d
, nginx and daphne work well.
但是当我连接到example.com:80时,我只能看到nginx默认页面.
but when i connected to example.com:80, i just can see nginx default page.
当我连接到example.com:8000时,我只能看到myproject的服务页面. (但看不到静态文件)
and when i connected to example.com:8000, i just can see myproject's service page. (but cannot see static files)
我想链接nginx和daphne服务!我该怎么办?请帮助我.
I want to link nginx and daphne service! what should I do? please help me.
- 当我仅使用nginx + daphne + django而不使用docker进行部署时,我的服务运行良好.
推荐答案
TLDR;
Nginx的配置不正确,但是您的docker-compose也需要进行一些更正:
TLDR;
Nginx is not configured correctly, but also your docker-compose needs some correction:
Nginx网站提供了一些有用的提示,您应该阅读的使用Docker进行部署,其中包括一个非常简单的Dockerfile示例:
The Nginx website has some helpful tips for deploying with Docker that you should read, including a sample, very simple 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的更多帮助,请参阅Docker Compose部分).
which points to some improvements you need to make (see the Docker Compose section for further help with Docker).
请记住我们将在下面进行的部署更新,您还需要更改Nginx配置:
Bearing in mind the updates to deployment that we will make below, you will also need to change your Nginx config:
- 重命名
service.conf
->service.template
- 更改
listen ${NGINX_PORT};
- 更改
server_name ${NGINX_HOST};
- 更改
proxy_pass http://${DAPHNE_HOST}:${DAPHNE_PORT};
- rename
service.conf
->service.template
- change
listen ${NGINX_PORT};
- change
server_name ${NGINX_HOST};
- change
proxy_pass http://${DAPHNE_HOST}:${DAPHNE_PORT};
现在您的Nginx配置正确,您需要正确设置docker compose指令,幸好 Docker Hub Nginx页面具有docker compose的示例:
Now your Nginx configuration is correct, you need to setup the docker compose directives correctly, thankfully, the Docker Hub Nginx page has an example for docker compose:
以下是使用docker-compose.yml的示例:
Here is an example using 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文件可能包含这样的变量引用:
The mysite.template file may then contain variable references like this:
listen ${NGINX_PORT};
来自r00m的 answer
您可以进行所有这些改进,实际上,如果不共享卷,将无法正确提供静态文件.
From r00m's answer
You can make all those improvements, and in fact, without sharing the volumes your static files won't be served correctly.
- 为项目创建图像并重新使用
- 添加卷引用以允许共享静态文件
- 可选:您还应该遵循有关收集静态文件的建议,但是您的项目结构表明您已经这样做了.
最后,我们可以合并这三个改进,以进行以下设置:
Finally, we can merge those three improvements to give us the following setup:
myproject/Dockerfile:
myproject/Dockerfile:
FROM python
ENV PYTHONUNBUFFERED 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? i.e. no link to the DB?
VOLUME ["/opt/myproject/collected_static"]
myproject/docker-compose.yml:
myproject/docker-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
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
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不应连接到您的后端网络(我认为...). /li>
- 您需要考虑是在构建时还是在运行时进行迁移".
- 您是否需要能够轻松更改nginx配置?如果是这样,则应从nginx构建中删除COPY,并从Docker Compose部分中添加volumes指令.
- I'm not sure what you're trying to achieve with your network directives, but it almost certainly doesn't achieve it, for example nginx shouldn't connect into your backend network (I think...).
- You need to consider whether "migrate" should be done at build time or run time.
- Do you need to be able to change your nginx configuration easily? If so, you should remove the COPY from the nginx build and add in the volumes directive from the Docker Compose section.
Final thoughts
这篇关于使用Nginx,Django,Daphne部署到Docker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!