Python中使用Docker部署Django应用的最佳实践是什么?
我目前的做法是,构建一个容器运行 django,一个容器运行 nginx,把代码所在文件夹挂载到容器里,但是在这种情况下服务器还是需要安装 python 和 django,感觉和用虚拟环境部署没有区别。
我希望大家的效果是服务器只需要安装 Docker 就行了,然后通过镜像就可以运行整个 django 应用,该怎么做?
Python中使用Docker部署Django应用的最佳实践是什么?
你为啥还需要装 python 和 Django?不是都打包进镜像了吗
我无法理解你的问题。
首先,大部分发行版都是自带 python 的,你不能不装 python, 否则系统基本服务都跑不起来
其次,并不需要在 docker 外面装 django
另外,最好把代码也打包到镜像里
是这样的,我是把源代码文件夹通过 volumes 挂载到容器里,那么在此之前,需要运行 manage.py 的一些命令,如迁移数据库,收集静态文件。那么运行这些命令前又要配置一个完整的 django 环境。而如果将这些动作放到容器里执行的话,我又遇到两个问题:
如何将容器中的数据库挂载到本机?这样保证容器万一挂了数据还在。
由于 django 和 nginx 运行在不同容器,如何让 nginx 容器访问到 django 的容器已获得静态文件?当然思路肯定是 volumes,但是几天来查了很多文档还是不知道该如何设置。
两个问题该如何解决:
如何将容器中的数据库挂载到本机?这样保证容器万一挂了数据还在。
由于 django 和 nginx 运行在不同容器,如何让 nginx 容器访问到 django 的容器已获得静态文件?当然思路肯定是 volumes,但是几天来查了很多文档还是不知道该如何设置。
docker exec 进容器里执行命令,容器间通过 docker network 通信。用 docker-compose 更方便一些,它会自动配置网络。
你可以贴一下你的 Dockerfile
一般的 volume 挂载,如果本机上没有这些文件,而容器里有的话,可以给 Dockerfile 里加个 <a target="_blank" href="http://docker-entrypoint.sh" rel="nofollow noopener">docker-entrypoint.sh</a> 当 ENTRYPOINT,用脚本先判断一下文件是否存在,不存在的话就复制过来,具体例子可以看下 library 里官方怎么做的
至于第二个问题,不同容器间的文件的访问,可以在 docker compose 里指定一个 top-level volumes
1、数据库的 data 目录是 volume 挂载的,不怕容器挂啊。
2、收集静态文件可以容器内执行。也可以本地开发机执行后,git 更新,这样更好,一般是。
3、数据库迁移可以本地测试通过后,fabric 自动执行。
如果在本地服务器上执行就需要在搭建一套完整的 django 环境,我希望的是能在容器中执行。
你说的开发机?不是服务器?
开发还是 virtualenv 好使。部署用 docker。
感觉楼主对 docker 不是很理解。可别在生产上随便用。
docker 不是虚拟机,设置错误会丢数据的。
楼主意思应该是:
docker 1 web(django) : link:db,volume :project
docker 2 nginx : 反代 web,volume:project_static volume :nginx_config
docker 3 db volume :data
django 的一些命令可以通过 docker1 手动执行或启动时自动执行
你需要 docker-compose
可以参考 https://github.com/pydanny/cookiecutter-django 里的 docker 配法
我是 nginx 和 django 放在一个容器里
# docker run -p 80:80 -p 8000:8000 …
# docker exec -it {your container} bash
# python manange.py runserver 0.0.0.0:8000
这样就用 80 端口和 8000 端口区分开 nginx 和 django dev server 的访问路径了
除此以外,就是 Volume 的配置,和 db container link 的配置而已,这些官方文档都有
我就是按照这个库配的,按他的配法遇到的问题就是 nginx 没法反代静态文件
10 楼已经一针见血指出问题,楼主对 docker 理解不足,所以暂时不用急着用 docker,建议:
- 先搞清楚在不用 docker 的情况下如何该部署,架构如何,并自动化,这是后续步骤的前提
- 如果真心想用 docker,先花一些时间进行系统化的学习,看看官方文档、跟着实践等等
- 在项目中,可以先从 demo 环境开始使用 docker,相信你会遇到一些问题,尝试解决之
- 对于 production,不要急着用,除非你已经足够自信
谢谢指出!我确实是刚学 Docker 不久,昨晚根据大家的回答我重新看了一遍 Docker 的 volumes 文档,目前问题基本解决了。虽然不确定是不是好的解决方案。目前 docker-compose.yml 是这样的:
version: '2’
services:
django:
build:
context: .
dockerfile: ./compose/django/Dockerfile
command: /gunicorn.sh
volumes:
- static-file:/app/static
- sqlite3-db:/app/database
nginx:
build: ./compose/nginx
depends_on:
- django
volumes:
- static-file:/home/app/static
ports:
- "0.0.0.0:80:80"
volumes:
static-file: {}
sqlite3-db: {}
我把静态文件和数据库文件均放到一个数据卷容器里,让 django 和 nginx 共享,这样 nginx 可以代理静态文件了,从新构建容器启动容器数据库也还在了。不知道这样的解决方案是否合理?
赞,楼主学习动手能力不错。
看你的 yml,可以改进的地方:
- nginx 可以直接使用 docker 上已有的 image,不需要自己 build ;配置文件以 volume 的方式挂在即可
- 可以试着把 docker-compose 中写死的变量 ENV 化
12 楼给出了一个参考的链接,很不错,建议楼主也看看。
嗯,谢谢,我就是参考这个项目做得。

