摘要
通过近2年的开发、部署经验,记录基于Django 的web项目,如何做容器化部署,以及如何做支持集群的分布式部署。主要讲述前端静态文件的部署,用户文件的存储,错误的收集,日志的记录,以及如何进行项目配置。
难点
如果仅仅是基于容器运行,那么其容器化的过程是相对简单的,甚至不需要对开发习惯和过程做约束:
Dockerfile 打包
docker run 运行且映射磁盘和端口
nginx 端口转发、静态文件映射
但如果我们需要考虑,将项目以集群的方式,进行分布式部署,那么就有一些不太好处理的地方。
存储
django 项目默认存储是存储在磁盘路径中的。
例如static
和media
的设置。这里主要特指前端静态文件,以及用户在使用过程中存储的文件。
从docker 容器的特性不难理解:我们不能够将用户文件存储在容器内。
一个很好的方式是,使用Django 自带的storage功能,比如已经存在的miniostorage。
只需要简单修改setting中的配置,而不需要修改视图(如果已经按照规范进行开发)。
当然,静态文件也是一个需要考虑的点。
一方面,可以另起Dockerfile,通过多阶段构建,将静态文件collection 出来后,通过nginx 部署,同时nginx 设定转发指向Django web。
另一方面,可以在静态文件处也用对象存储,例如miniostorage,他能够自动将静态文件上传至对象储存,然后浏览器访问时,将直接指向对象存储的主机和端口。这个时候,再加nginx转发也是可以的。

日志
以docker 的service 为例。日志支持多种驱动,大团队自然有多种分布式日志方案进行收集。
但作为小团队,我们该如何使用呢?
最为基本的设置,可以将日志的驱动设置为json-file,然后设置文件的大小限制。这样可以作为简单的日志收集和查看方式,但是时效性,准确性,都不太好。
所以有一种取巧的方式,使用python 的logging 模块下的httphandler 或者tcphandler,然后另起web + 队列,将日志存档。
这样的设置,就把所有python 的logging的日志全部发送出去了,不再和本地磁盘挂钩。缺点也很明显:对项目习惯,或者已有项目,需要做一定的改变。

注:更为通用,且对项目习惯和开发影响小的方式,是基于docker 日志驱动的分布式日志解决方案。但目前仅一个人的python 后端开发团队,使用起来成本比较高。
错误
服务端的部署,自然存在着难以捕获错误的特点,分布式部署模式更困难。
哨兵——sentry 是一个很不错的工具。在django 的setting中配置合适,就基本设置成功。
效果可以如下,甚至可以直接对接gitlab:


项目配置
常见的配置方式包括ini,yaml等方式。
如果采用上述两种方式,那么service 运行时必须采用文件(磁盘文件或者配置文件)映射。
但如果只是单独一个容器运行,指定文件又太麻烦。所以,较为推荐的方式是,使用环境变量设置。
项目中通过load .env
文件更新环境变量,从环境变量获取配置。
单容器运行就直接通过docker 设置环境变量,如果是service 运行,则直接映射一个配置文件到.env
中去。





