介绍
今天在使用 docker 部署 web 项目的时候遇到一个很诡异的问题,再此记录下这次解决问题的过程,梳理一下思路。首先这个项目主要由 nginx + gunicorn + Django 来部署的,其中 gunicorn 用来启动 Django,并且绑定 socket 文件,nginx 监听端口并反向代理到后端 socket。至于为什么没有直接使用 gunicorn 监听某个端口,而是选择绑定某个 socket 文件原因如下:
- gunicorn, Django 不处理静态文件,由 nginx 来处理静态资源,那我我只能通过反向代理的方式使得 nginx 可以正确的处理静态资源(原因:nginx 和 gunicorn 不能同时绑定同一个端口),这一下占了我的俩个端口。
- socket 传输的效率明显高于网络端口之间的传输效率。一个是网络层面,一个直接文件系统层面,快慢立马看出来。
具体配置如图示:
使用 gunicorn 启动命令如下:
gunicorn --bind=unix:/tmp/mail.sock --workers=4 -u root -g root --log-file error.log wsgi:application
这其中需要注意的几点:
- gunicorn 命令必须指定用户,用户组,因为我们在 docker 里面 root 用户,所以必须指定,我一开始就没有指定,所以报错。
- --bind 参数一定不要忘了 unix:前缀,我看很多人经常忘了添加这个协议前缀,所以就会报错。
- 记住在启动面前一定不要事先创建/tmp/mail.sock这个文件,然后还傻乎乎的赋予该文件777权限,结果你懂的,试一试就知道。
坑来了
一切看上去都挺好,由于我一直在 docker 内部操作,一切看上去完事了,准备 commit,提交镜像了。结果到另一台机器pull镜像镜像启动应用,报错了: