十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
今天小编给大家分享一下Docker中怎么部署Django应用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
创新互联成立与2013年,是专业互联网技术服务公司,拥有项目做网站、网站制作网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元高青做网站,已为上家服务,为高青各地企业和个人服务,联系电话:13518219792
一、网络架构
我用visio大概画了一下我的网络架构图:
我构建的容器:
nginx容器;
web server容器
redis容器
memcached容器
MySQL容器
如果把所有应用都部署到一个应用中,可能会更简单,但不同容器之间就稍微复杂点。首先你要考虑好容器之间的依赖关系,比如nginx要依赖web服务器,如果web服务器不正常工作,那nginx就不能正常工作;web服务器要依赖于数据库等等;其次,要设置好容器间的数据共享问题。比如对于web应用的静态资源,怎么让nginx实现反向代理。
带着这些疑问,开始部署。
二、环境:
准备docker的环境。
ubuntu 16.04 (主机环境)
docker 17.06.0
docker-compose 1.14.0
compose file 版本: version 3
对于docker的作用和介绍可参考官网:docker service。
要注意你的docker版本以及composefile版本,因为不同的版本,语法可能略有不同。我之前在配置共享数据卷的时候就遇到过坑,比如在version 3中删掉了volumes_from,我还不知道有版本差异,所以怎么配置都不对。更详细的请看官网:
1、工程结构
├── blog │ ├── account │ ├── blog │ ├── dailyblog │ ├── dockerfile │ ├── gunicorn.conf │ ├── manage.py │ ├── media │ ├── requirements.txt │ ├── start.sh │ └── static ├── docker-compose.yml └── nginx ├── dockerfile └── nginx.conf
blog是我的django应用,内有dockfile文件;nginx文件里也有一个dockfile。blog和nginx分别是一个service,我们通过docker-compose.yml文件的配置来创建镜像和容器。也就是说你必须要做几件事:
在每个服务(应用)下编写dockerfile;
在docker-compose.yml文件中配置相关的服务;
执行docker-compose命令 build和up
2、django应用的配置(blog包):
1)dockfile
from ubuntu:16.04 #更新软件源,必须要执行,否则可能会出错。-y就是要跳过提示直接安装。 run apt-get -y update run apt-get install -y python-dev python-pip run apt-get install -y python-setuptools #mysql-python必须得先安装这个库 run apt-get install -y libmysqlclient-dev run mkdir /blog #设置工作目录 workdir /blog #将当前目录加入到工作目录中 add . /blog #install any needed pacakges in requirements.txt,你要把所有需要安装的python模块加到这文件中。 run pip install -r requirements.txt #对外暴露端口 expose 80 8080 8000 5000 #设置环境变量 env spider=/blog
我的基础镜像选择了ubuntu,是因为我觉得我可能更习惯一些。
2)启动脚本 start.sh
#!/bin/bash #命令只执行最后一个,所以用 && python manage.py collectstatic --noinput && python manage.py migrate && gunicorn blog.wsgi:application -c gunicorn.conf
在你初次部署时,你要收集各个app的static目录到工程static目录中,同时要创建数据库。上面的3个命令通过 && 拼接,相当于一个命令。
此外,django应用选择gunicorn做web服务器,gunicorn的配置文件如下:
workers=4 bind=['0.0.0.0:8000'] proc_name='blog' pidfile='/tmp/blog.pid' worker_class='gevent' max_requests=6000
gunicorn中host选择 0.0.0.0:8000。
3、nginx配置(nginx目录)
1)dockfile
from nginx #对外暴露端口 expose 80 8000 run rm /etc/nginx/conf.d/default.conf add nginx.conf /etc/nginx/conf.d/ run mkdir -p /usr/share/nginx/html/static run mkdir -p /usr/share/nginx/html/media
nginx的基础镜像选择docker仓库中的基础镜像nginx即可,同时要把自己的配置文件添加到相关目录中。这里有一点要注意,就是我自己曾经在主机配置nginx的时候,一般/etc/nginx/nginx.conf会从 /etc/nginx/conf.d,和/etc/nginx/site-enabled/两个文件目录寻找conf文件,我之前都是添加到/etc/nginx/site-enabled/,这次也是这么做的,但是我配置运行之后,nginx没有正常工作,我进入nginx容器看了一下,想看看为啥我的配置没有加载,打开/etc/nginx/nginx.conf一看,果然,它只include了/etc/nginx/conf.d中的conf文件。bingo!改了我的配置文件,ok。
后面创建的static和media是为了web应用的静态文件存储。
2)nginx.conf
server { listen 80; server_name localhost; charset utf-8; error_log /tmp/nginx_error.log; access_log /tmp/nginx_access.log; location /media { alias /usr/share/nginx/html/media; } location /static { alias /usr/share/nginx/html/static; } location / { proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for; proxy_set_header host $http_host; proxy_redirect off; proxy_pass http://web:8000; } }
关于nginx配置,要注意以下两点,是非常重要的:
location
静态文件配置,nginx指定的静态文件原目录是在/usr/share/nginx/html/,而该目录下的静态文件是从web容器中通过volumes同步的。所以,等下docker-compose是非常非常重要的。
proxy_pass
这和你直接在主机上配置是不一样的,host不能写成具体的ip,要写服务名,这里要写web service的name,web是在docker-compose中定义的web应用的service名称。后面要写docker-compose的配置。
4、docker-compose.yml配置
version: "3" services: db: image: mysql environment: mysql_database: app_blog mysql_root_password: admin volumes: - /srv/db:/var/lib/mysql restart: always redis: image: redis restart: always memcached: image: memcached restart: always web: build: ./blog ports: - "8000:8000" volumes: - ./blog:/blog - /tmp/logs:/tmp command: bash start.sh links: - redis - memcached - db depends_on: - db restart: always nginx: build: ./nginx ports: - "80:80" volumes: - ./blog/static:/usr/share/nginx/html/static:ro - ./blog/media:/usr/share/nginx/html/media:ro links: - web depends_on: - web restart: always
这个文件是非常重要的!!!
定义了5个服务:
db。 mysql数据库;
redis。 缓存,NoSql数据库;
memcached。 缓存;
web。 web应用;
nginx。 反向代理。
服务名称对于容器间的沟通是非常重要的。我们这里一个一个说。
1)db
配置的几个方面:
基础镜像从docker仓库中获得(配置image);
配置了环境变量,创建一个数据库(该数据库名为app_blog,django在执行migrate操作时会用);
volumes。数据卷,为了实现备份用的,/srv/db,是主机目录,/var/lib/mysql是mysql容器内目录;
restart 默认是no,意思是在任何情况都不会重启;如果设成always,就是如果stop了,就会重启;
root用户的密码;你在django应用的settings.py里也要写成响应的配置,具体如下:
databases = { 'default': { 'engine': 'django.db.backends.mysql', 'name': 'app_blog', 'user': 'root', 'password':'admin', 'port':3306, 'host':'db', } }
2)redis,memcached
这两个就一起说了,因为不需要重新配置,直接用仓库中的镜像即可。
3)web应用
配置的几个方面:
build。 根据dockerfile重新build一个镜像;
ports。 格式为host:container。相当于一个nat转换,设置内部的端口向外转发的端口;
volumes。同样是设置数据文件备份,也可以说成是同步,web容器的工作目录/blog备份到主机上的目录;
links. 创建和其他容器中的service的链接,指定服务名字即可。有了这个连接,服务之间就可以通过service名字通信了,在前面nginx配置中的proxy_pass就用了web服务;
depends_on. 它有两层含义,一是在启动服务的时候,会先启动db,然后再启动web;二是如果执行ocker-compose up web也会创建和启动db.
4)nginx
build。 根据dockerfile重新build一个镜像;
ports。 格式为host:container。相当于一个nat转换,设置内部的端口向外转发的端口; http默认端口
links. 上面已经介绍了;
depends_on. 上面也介绍了;
volumes。 这个我认为是最重要的,重点说一下。
关于如何实现nginx容器和web容器间的数据共享,即静态文件共享的问题,真是把我困扰住了。我先是按照官网配置,在顶级配置了volumes,在服务下配置type,source,之类的,但一直没成功(如果有配成功的,拿出来分享下哈);后来网上搜了一堆资料,容器间共享他们都用了volumes_from,这在version3中已经取消了,退回旧版本还不行。上周五真是烦得我头疼啊。后来看了一篇文章,才突然开窍,我本应该早点想到啊。逻辑是这样的:
首先,我在web应用中就已经设置volumes数据的备份,即将容器中的文件同步到主机上,然后主机就可以充当这个中间者,nginx容器再从主机上同步静态文件。这就相当于celery中,生产者将任务消息写到消息中间件中,然后消费者从中间件中取消息来消息,而这里面web应用就类似生产者,nginx是消费者。
这样问题就迎刃而解了!!!
到目前为止,所有部署相关的配置都已经写完了。
首先执行:
docker-compose build
然后执行:
docker-compose up -d
题外话:我是在周六晚上11点跑的第一个build命令,执行各种镜像下载,软件源更新,get资源比较慢,我太困了,就睡觉了。晚上睡觉做梦感觉都是docker,然后不到6点我就起了,到了客厅看电脑build已经成功。我就开始执行up命令,当我打开浏览器,输入localhost,然后成功返回结果的那一刻,甭提多有成就感啦!!!
随意几个知识点:
docker删除所有容器:
docker rm docker ps -a -q
最重要的是后面的 -q选项,表示只显示id。
删除none镜像:
docker rmi docker images -f "dangling=true" -q
更新。dockerfile要加上apt-get update,否则后面的命令不能正常执行;
command命令只执行最后一个,在脚本中写了三个命令,但最后只执行最后一个。后来把三个命令用 && 拼接起来。
docker镜像内的文件互相拷贝
1、将本地文件拷贝到docker 镜像内
docker cp /users/howey/documents/apache-maven-3.5.2/ 749056ea1637:/opt docker cp 本地路径 容器id或name:容器目录
2、将docker内文件拷贝到本地文件夹内
docker cp 749056ea1637:/users/howey/documents/apache-maven-3.5.2 /opt/ docker cp 容器id:本地路径 镜像路径
以上就是“Docker中怎么部署Django应用”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注创新互联行业资讯频道。