各位 docker 大佬,我最近使用 docker 有一个问题想不明白,就是开发环境和生产环境的问题。
我先将自己对 docker 的认识描述一下,以 python web 开发为例:
一、docker 最主要的使用场景是生产环境应用部署,在这个使用场景中,步骤如下:
docker pull
下来之后运行。这里的 dockerfile 里面,将工程目录 copy 进入 docker 镜像里,如下:
FROM kennethreitz/pipenv
LABEL maintainer="[email protected]"
COPY . /app
WORKDIR /app
ENV FLASK_APP=run.py
ENV FLASK_DEBUG=1
ENTRYPOINT [ "./boot.sh" ]
二、docker 也可以作为开发环境的一个工具使用,类似于 vagrant。(这一点其实是我疑惑的,大家用 docker 作为开发环境的多吗?) 在这个使用产经中,我使用 docker 的 volume 将本地工程目录,映射到 docker 容器内部,然后运行 docker 容器,映射端口供主机使用。
现在我的问题是:
先谢过大家了!
1
wfd0807 2018-02-01 13:24:39 +08:00
v2 可以帮顶吗?
|
2
owenliang 2018-02-01 13:32:33 +08:00
开发可以 vagrant,线上需要 paas 平台,例如 marathon,k8s
|
3
HypoChen 2018-02-01 13:33:44 +08:00
1. 流程没问题,但可以更好,比如使用编排工具部署
2. 流程没问题,pycharm 也可以通过改配置实现类似操作,但是感觉有点繁琐,个人观点是开发怎么便捷怎么来 3. 参考 CICD |
4
brickyang 2018-02-01 14:06:22 +08:00 1
从描述中没看出你的「开发环境」和「生产环境」有什么不同。是不是你对 Docker 的理解有哪里卡住了?
Docker 本身只是一个运行环境而已。至于把文件 COPY 进去还是 Volume 映射进去都是一样的。主要的区别只是映射进去的文件会保存在本地硬盘里,COPY 进去的文件与容器生死与共。 像你描述的这两种情况,也可以反过来用: 生产环境:代码文件放在服务器,启动 Docker 时用 -v 映射进去。 开发环境:启动 Docker 后在 container 中 git clone,开发完后 push 到 GitHub。 ---------------------------------------------- 我个人的实践经验是,在生产环境,会把 log 映射出来,因为容器里的文件不会保存,外部的日志工具也不能直接读取。 在开发环境,会用 Docker 启动数据库,日常需要的开发环境就在本地安装,没必要每次都启动 Docker,也不方便。 ---------------------------------------------- Docker 的部署应该属于 CI/CD 的一部分,CI 跑完测试后自动构建打包并把 image push 到指定 registry,直接用就好了。非开源项目我喜欢用 GitLab.com ,提供了全套的免费工具。 |
5
Vogan 2018-02-01 14:12:36 +08:00
线上,要考虑容器挂了或僵死等问题,通常会部署多个节点,和快速拉起功能;
日志等,要拿出来,不然很容易撑死; 可以不做映射处理,直接将代码一起打包,做到对母鸡最小化影响。 |
6
tomczhen 2018-02-01 14:50:23 +08:00 2
开发环境的需求是统一开发运行环境,生产环境的需求是统一交付。
对于开发来说,重点是“运行环境”,对于生产来说,在环境的基础上还需要加上开发交付的代码。不管是虚拟机还是 Docker,都可以提供一个统一的运行环境。 环境的统一可以使用约定基础镜像来实现( FROM IMAGE ),实际开发中需不需要使用 Docker 容器远程 Debug,取决与实际需求,个人是觉得再提交代码之前开发本地用 Docker 运行测试代码即可( VOLUME ),倒是没必要追求必须在容器中完成开发过程。 开发交付时还是交付代码,利用 CI 平台进行 Docker 镜像构建(代码包含在镜像中),部署到生产环境时则是部署镜像,根据实际情况可能还需要对配置进行管理,之前参加的交流会看,有使用环境变量传入容器的,也有挂载配置文件的,也有不同环境不同镜像的。 另外也不觉得只要上 Docker 就得直接上 K8S,根据业务规模和需求 Docker Swarm 也可以考虑的,甚至仅仅单机靠编排文件( Docker Compose )也是可行的。当然,本着面向工资的原则尽量还是上 K8S。 对于开发来讲,Docker 实践中需要注意的一个是日志处理,另一个就是环境配置了,日志已经有人说了,补充一下的是 Docker 的日志还是有挺多诟病的地方,根据解决方案不同,代码上也可能需要做一些处理。Docker 官方的推荐实践是通过 stdout 和 stderr 输出,然后使用 logdriver 配置容器日志输出和格式。环境配置官方推荐的方式是使用环境变量作为配置,这需要在代码中获取环境变量,当然,实际怎么做是不断妥协的结果,并不是一定要如此。 |
7
tomczhen 2018-02-01 14:54:42 +08:00 1
忘记说了,没有 CI 平台也是可以的,但这时开发要交付的不是代码,而是 Docker 镜像。
|
8
whileFalse 2018-02-01 17:20:14 +08:00
我司本地开发不用 docker。
线上有多套环境,都是 docker。 |
9
Les1ie 2018-02-01 17:33:48 +08:00
看来我用法不正确了,我都是把 dockerfile 和 compose 文件放到服务器上去自己构建的
|
10
feverzsj 2018-02-01 17:58:35 +08:00
你的开发环境和 docker 一样就可以啦,image 一般都是上传到自己的 registry,其实 docker 上开发很适合用 c/c++之类的原生语言,直接用 ldd 复制依赖就可以啦,你用的是什么系统都没关系
|
11
hujianxin OP |
12
hujianxin OP 感谢各位的认真回复,非常感谢。
我刚开始正式使用 docker 不久,很多地方不太理解。 看过很多教程,都说 copy for production,volume for development,而我纠结在,如何将两者很好的结合。 其实,这个问题很简单,我想复杂了,我把我的理解和解决方案说一下,大家可能大呼:原来你说的是这个 easy 问题啊(囧 1. copy for production,因为交付部署的时候,肯定是要将代码成果(代码、或者二进制)放到镜像里面,在服务器上直接 pull 镜像,运行就 ok,所以,生产环境,需要在 dockerfile 里面把代码 copy 到镜像里面,构建,然后部署。 2. volume for development,因为在很多时候,开发过程中,需要快速的查看结果,并且与生产环境保持一致。如果想与生产环境保持一致,用 docker 作为开发环境是必须的。在开发 flask 或者别的应用的时候,我们修改一个代码,flask 会快速的 hot reload,然后刷新页面就可以看到改动。如果我们每次都 build 新的镜像,然后删除容器,运行镜像,这样就失去了 hotload 的便捷性,而且非常繁琐。这个时候,我们直接将本地开发目录通过 volume 映射到容器内,然后在容器内运行 flask,就 ok 了。 3. 如何将这两者完美的融合呢,其实很简单,保持第一条(生产环境的步骤)不变,在本地运行镜像的时候,直接将当前开发目录映射到容器里面就行了,我们对容器的任何修改,如果不 commit,则不会保存。(这个第三点是我最纠结的,结果自己用手试了一遍,发现,原来如此简单,纸上得来终觉浅呀!) 最后,附上一个 博客链接,我通过这篇文章找到思路的: https://medium.com/@McMenemy/godorp-docker-compose-for-development-and-production-e37fe0a58d61 |
13
tomczhen 2018-02-01 19:23:30 +08:00
@Les1ie 如果公司没有提供容器化的基础,把 Docker Compose 当成一键部署脚本用也是不错的做法,至少比来路不明的脚本安全多了。
|
14
brickyang 2018-02-01 20:48:31 +08:00 via iPhone
@hujianxin 我打这么多字算白说了。
明确说了 COPY 和 Volume 只是两种(可以互换的)方式,需要什么用什么,没有什么环境用什么的“标准动作”。 Docker 只是个环境而已。保持环境一致只是说避免部署在不同环境出现不可知错误。这是它的作用,而不是对使用方法的限制或要求。 你过于纠结在“怎么用”这种形式的东西上了。 |
15
hujianxin OP @brickyang 我认为这不是两种可以互换的形式啊,就比如,应用 hot load 的问题,用 copy 就没法解决吧
|
16
brickyang 2018-02-01 23:43:13 +08:00
@hujianxin
首先,“可互换”主要针对你所谓的“ copy for production, volume for development ”的说法。我是向你强调这两种方式只是两种不同用法,并不是什么 for 什么。 其次,我没用过 flask,但仅就你的描述而言,进入 container 直接改文件后重启服务也是一样的,并不需要“每次都 build 新的镜像,然后删除容器,运行镜像”。 最后,并不存在“如果想与生产环境保持一致,用 docker 作为开发环境是必须的”。 给我的感觉,你一直在努力总结出一套“操作规范”来,而对概念的理解是模糊的。如果说的不对,也请包涵。 |
18
singer 2018-02-02 09:34:10 +08:00 via iPhone
docker-compose 用用,开发的时候代码之类,日志之类的,配置文件之类的都挂出来。
这里注意配置文件。 线上部署,维护开发与线上环境一样。可以在线上用 COPY 把配置文件弄进去。 |