[Docker系列]手动创建一个自己的docker镜像

1,315 阅读6分钟

本文适合对docker有一定了解的童鞋观看~ 看完springboot和docker的视频后,又去补充了一些知识,写一篇博客记录学习~

一、镜像是什么

  里面包含了一个运行程序以及支持该程序运行的环境。例如,一个需要java环境运行的程序,制作该程序的镜像就要把这个程序的jar包和java环境合在一起放在镜像中。

二、镜像的作用

  镜像的作用就来源于它包含了程序本身及其运行环境的特点,由此只要团队中的成员获取了该镜像就不必再配置环境并且能够统一环境从而运行程序。 具体来说是:

  • 对于开发人员: 统一开发环境;
  • 对于测试运维人员:可以使用镜像放在容器中运行进行测试、运维工作。

三、Dockerfile是什么

  Dockerfile是由一系列命令和参数构成的脚本文件,这些命令应用于基础(原始)镜像并最终创建一个新的自定义的镜像。

给出一个范例并加以解释:

FROM java:8
VOLUME /docker/dataOfSpringbootDocker
ADD springboot-docker-0.0.1-SNAPSHOT.jar springboot-docker.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","springboot-docker.jar"]

其中springboot-docker-0.0.1-SNAPSHOT.jar是一个用springboot开发的一个简单的web工程的jar包。

  • 要创建的新镜像基于java:8的镜像。
  • 创建的镜像在运行时会将镜像运行时产生的数据映射到宿主机的一个自定义文件夹下,这边我设置的映射文件夹是/docker/dataOfSpringbootDocker。
  • 将本地的jar包加入到容器内的指定路径。容器内的指定路径不用事先创建。本脚本中的ADD命令就是做这个的,将该Dockerfile文件所在目录下的springboot-docker-0.0.1-SNAPSHOT.jar文件加入到容器中,并命名为springboot-docker.jar。
  • ENTRYPOINT指令(还有一个与之类似的CMD指令)在Dockerfile中定义,但是在构建镜像的时候并不会被执行,只有在执行docker run命令启动容器时才会起作用。它的作用是在为该镜像创建容器时,执行这条命令:java -Djava.security.egd=file:/dev/./urandom -jar springboot-docker.jar这条语句如果去掉-Djava.security.egd=file:/dev/./urandom这个参数估计就会很熟悉了,就是一个执行jar包的命令,加这个参数只是为了加快启动程序的速度,这里就不讲了(因为我也不咋地懂)。 由这四条命令便能组成一个Dockerfile文件供后面的构建过程。

四、Dockerfile中的命令

除了上面范例中的四个命令,其实用于编写Dockerfile脚本文件的命令还有很多。下面只列出几个常用的。剩下的放在链接中,供大家自行查阅。

column1column2column3
FROM定义了使用哪个基础镜像,定制的镜像都是基于FROM的镜像content3
VOLUME用于持久化目录, 定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷( 在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。)。避免重要的数据,因容器重启而丢失,这是非常致命的,避免容器不断变大。
COPY复制指令,从上下文目录中复制文件或者目录到容器里。COPY <源路径> <目标路径> <目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
ADD与COPY类似,但额外支持tar类型文件自动解压以及访问网络资源。网络压缩资源不会被解压。
RUN镜像操作指令注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。
详情请看Docker菜鸟教程

五、实际去操作——制作镜像

1.准备好Dockerfile

将写好的额Dockerfile放在服务器的指定目录下,例如我放在了/docker/springboot-docker下。

2.准备好需要运行的jar包

我使用的jar包是一个简单的springboot开发的web工程。 springboot-docker-0.0.1-SNAPSHOT.jar放在存放Dockerfile的目录下,当然也可以不放在一起,不过放在一起会很方便,后面会解释。 ps:如果你使用的是linux服务器,且用的软件是Xshell不是Mobaxterm这种界面化特别好的,那么在上传文件软件的时候可能要好好研究一番,尤其是上传文件用户的权限问题。但也不难。

3.构建镜像的命令

++在Dockerfile所在目录下执行下面的命令++

docker build -t springboot:haonan .

解释:构造一个名字为springboot,标签为haonan的镜像,用-t来指定。 注意:千万别丢了那个 “ . ” “ . ”是上下文路径,docker在构建镜像时,要找到存在于宿主机的所需文件,寻找的路径就是上下文路径。当未说明上述命令的最后一个参数时,那么默认的上下文路径就是Dockerfile所在位置。 注意:上下文路径下(如本例中的springboot-docker)不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。 解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。

4.执行过程

制作镜像的过程如下 先是拉取那个Java镜像,可以看到有下载的过程吗,java镜像也会保存在本机上,如果本地已经有了java:8的镜像,就不用下载了,直接打包进我们的镜像中了。然后执行剩下的三行命令(当然ENTRYPOINT是不执行的)。 使用docker images便能看到两个镜像文件了。结果 以后这个镜像中是含有java环境的,别人也能运行,至于本地那个java的镜像是因为拉取得时候保存下来得。

六、创建容器运行该镜像

docker run -p 8081:8081 -d springboot:haonan --name springboot

-p命令是使docker容器的的8081端口映射到服务器的8081端口,写8081的原因是(web工程中设置的访问的端口就是8081),如果是一个普通的镜像文件,不写映射端口也行,使用-P会随机映射。注意有镜像标签要加上标签号。 ps:如果启动之后 docker ps 中没有显示这个容器 说明镜像过程中有一步错误了,回过头再检查一遍把(记得删除没用的镜像和容器)! 可以在浏览器上访问该工程: 到此一个简单的镜像就创建运行完成了。迈出了艰难的第一步了。总结一下整个过程:拿到jar包,写好Dockerfile放到同一路径下,在这个目录下构建镜像文件,运行镜像文件。欧克!