Goal: The set of docker containers for a production django website deployment.
目标:生产django网站部署的一组docker容器。
My hang up in this process is that usually nginx directly serves the static files... Based on my understanding of a good architecture using docker, you would have a container for your wsgi server (probably gunicorn), a separate nginx container with an upstream server configuration pointing to your gunicorn container. The nginx container can load balance between multiple gunicorn containers.
我在这个过程中挂断的是,通常nginx直接提供静态文件......基于我对使用docker的良好架构的理解,你将有一个容器用于你的wsgi服务器(可能是gunicorn),一个单独的nginx容器和一个上游服务器配置指向你的gunicorn容器。 nginx容器可以在多个gunicorn容器之间进行负载平衡。
But what this implies is that I have to install my django app's static files in the nginx container, which seems like bad practice since it's primary goal is really load balancing
但这意味着我必须在nginx容器中安装我的django应用程序的静态文件,这似乎是不好的做法,因为它的主要目标是真正的负载平衡
Is it better to have three containers: nginx, gunicorn, and a dedicated static server (possibly nginx or lighthttpd) for static files?
有三个容器更好:nginx,gunicorn和静态文件的专用静态服务器(可能是nginx或lighthttpd)?
2 个解决方案
#1
3
With reference to serving static files, your options depend on the functionality of your application. There's a very nifty tool called dj-static
which will help you serve static files by adding very minimal code.
参考提供静态文件,您的选项取决于您的应用程序的功能。有一个非常漂亮的工具叫做dj-static,它可以通过添加非常少的代码来帮助你提供静态文件。
The documentation is fairly simple and all you have to do is follow these steps.
文档非常简单,您只需按照以下步骤操作即可。
#2
3
I found this answer from Michael Hampton: "This only works if the processes are in the same host, VM or container, because it tries to make a connection to the same machine. When they are in different containers, it does not work.
我从Michael Hampton找到了这个答案:“这只有在进程位于同一主机,VM或容器中时才有效,因为它尝试连接到同一台机器。当它们位于不同的容器中时,它不起作用。
You need to alter your nginx configuration so that it uses the internal IP address of the uwsgi container." Link from the post
您需要更改您的nginx配置,以便它使用uwsgi容器的内部IP地址。“从帖子链接
And definitely is something you have to keep in mind if you will have Nginx in a different container, also you have to set the nginx.conf, pointing your statics file directory as alias preventing a security issue.
如果你将Nginx放在另一个容器中,你必须记住这一点,你必须设置nginx.conf,将你的静态文件目录指向别名以防止出现安全问题。
I hope this code work for everybody, it took me a couple of ours to figure about how to compose Gunicorn, docker, and Nginx:
我希望这段代码适合所有人,我花了几个时间来思考如何编写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;
}
}
And for the docker-compose:
对于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
#1
3
With reference to serving static files, your options depend on the functionality of your application. There's a very nifty tool called dj-static
which will help you serve static files by adding very minimal code.
参考提供静态文件,您的选项取决于您的应用程序的功能。有一个非常漂亮的工具叫做dj-static,它可以通过添加非常少的代码来帮助你提供静态文件。
The documentation is fairly simple and all you have to do is follow these steps.
文档非常简单,您只需按照以下步骤操作即可。
#2
3
I found this answer from Michael Hampton: "This only works if the processes are in the same host, VM or container, because it tries to make a connection to the same machine. When they are in different containers, it does not work.
我从Michael Hampton找到了这个答案:“这只有在进程位于同一主机,VM或容器中时才有效,因为它尝试连接到同一台机器。当它们位于不同的容器中时,它不起作用。
You need to alter your nginx configuration so that it uses the internal IP address of the uwsgi container." Link from the post
您需要更改您的nginx配置,以便它使用uwsgi容器的内部IP地址。“从帖子链接
And definitely is something you have to keep in mind if you will have Nginx in a different container, also you have to set the nginx.conf, pointing your statics file directory as alias preventing a security issue.
如果你将Nginx放在另一个容器中,你必须记住这一点,你必须设置nginx.conf,将你的静态文件目录指向别名以防止出现安全问题。
I hope this code work for everybody, it took me a couple of ours to figure about how to compose Gunicorn, docker, and Nginx:
我希望这段代码适合所有人,我花了几个时间来思考如何编写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;
}
}
And for the docker-compose:
对于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