前言

对于一个较大的项目(Jdk8+py37+Mysql+es),如果仅仅使用一个容器做部署,安装过程可能会极其复杂,并且并不利于后期各模块的更新,为了方便他人,也为了快速生成镜像部署,对于多服务的项目,我采用了Dock-compose技术生成多容器,并进行编排,第一次做,耗时3天成功,有不少经验分享于此,便于以后快速部署环境!
1. Mysql
强烈不建议自己先生成一个干净的centos,然后进到容器里面安装Mysql,这个过程谁试过谁知道,很耗时间并且不易成功!
一开始我已经调通了Springboot和es在一个容器,本想着装一个Mysql就基本结束了,谁料这将会是一个大坑!!
最终的Mysql方案,直接采用Dockerhub官方镜像,
这里补充几点,对于Mysql,一般需要初始化sql,可以改动docker-entrypoint.sh文件,并替换进容器里,该文件内容修改地方如下,这里我只是一个空库空表:
那么这个文件如何得到?可以先启动这个容器,然后用cp命令考出来,
1 | docker cp d5200819a46d:/usr/local/bin/docker-entrypoint.sh . |
启动Docker-compose.yaml中的单个容器,如只启动Mysql:
1 | docker-compose up -d mysql |
2.es & Jdk8
2.1 es
这两个相对容易一点,只需要配好jdk8环境即可,如果都放一个容器里面容易出内存问题,且不方便看两个服务的日志,并不利于调试,故拆成两个容器最好!
es:本地的整个es文件夹放进容器内即可,这里我先用dockerfile配好了一个含有jdk8及es文件夹的容器,然后commit成一个新的镜像es:vcoustom,再丢进docker-compose进行编排:
这里的解释一下为何把9201对宿主机进行了映射,为了方便调试,在localhost:9201下看到es的数据结构页面。
es文件夹内的端口配置,elasticsearch.yml
tcp端口配置(与Java通信):
es启动的报错:
这里的cluster.routing.allocation.disk.threshold_enabled一定要配,否则容易报空间不足的问题
如果es启动报内存不足问题,修改config/jvm.options,将1g改小到512m解决问题,减小启动内存的消耗
es容器采用dockerfile生成镜像:
2.2 Springboot项目
很简单,只需要配好jdk8环境即可,这里需要注意一下工作路径,也就是执行最终启动命令的位置,否则jar包启动时不会扫描当前jar包所在目录下的文件
该Springboot项目只需jdk9环境。所以和前面的es写的dockerfile类似,只改COPY内容即可
python模块
该模块在整个Springboot项目中承担了一个django接口,所以也不难配置,只需拉取一个python37镜像,简单配置
这里我采用了另一种docker-compose的写法,就是直接在yaml里面写好镜像的build方法,CMD在dockerfile里面已经写了,那么docker-compose.yaml内就不用写了
小结
这里的几个容器我分别采用了三种方式写docker-compose,殊途同归,但是自己去体会,他的目的以及侧重点还是不一样的!
如果我们需要将整个目录发给别人去部署,那么就尽量不要用save命令将自己写的镜像保存成tar 给别人导入,而是尽可能的发给别人少量的文件,让别人能够从docker-hub拉取,如这里的python和mysql镜像,这两个容器内部的原始镜像都是从官方拉取的,那么就不需要自己save了!

save方法解释一下:就是将自己配好的镜像save成一个tar包,发给别人,别人通过load命令导入到他电脑的docker镜像库中:
1 | docker save frontier2:vpopo -o xxx.tar |
这里再解释一下RUN和CMD命令,对于一个镜像的生成,RUN执行于生成镜像的过程中(比如安装相应的系统环境),CMD命令执行于启动该镜像后系统初始化要执行的命令(比如某个服务的启动)
Docker-compose.yaml
1 | version: '3' |
高频Docker命令
基本
1 | docker images #查看本机镜像 |
将容器提交为镜像
1 | docker commit -a "popo" -m "popo" b83f55190bf3 frontier2:vpopo |
解释一下commit,当我们将一个配好的容器提交为一个镜像时,无论你是否开启端口 服务,它保存的是一个静态的系统关机状态,相当于它只保存了这个容器的环境(包括文件改动等),并不意味着你打开这个镜像,他就已经开好了服务,这里要清晰!这也是之前一直困扰了我的问题,通过实践解决了!
这里还有一个高级的奇淫技巧,如果启动容器忘记了挂载,可以中途拷贝容器内的文件出来到本机目录下:
1 | docker cp d5200819a46d:/usr/local/bin/docker-entrypoint.sh . |
docker-compose
1 |
|
多个容器间通信
这里走了很多弯路。其实很简单,如果都是容器与容器通信的话,host直接改为docker-compose.yaml中各个services的名字即可,比如frontier_prediction这个Springboot项目要访问mysql容器的3306端口,只需改项目中的host为:mysql即可,而不是localhost






