文章目录
前言
上一步探索中,笔者千辛万苦得到了自己亲手制作的基础镜像。可以通过 docker run 命令生成一个初始容器——但运行之后也只是得到一个初始化的“服务器”,其中没有运行什么应用。
然而,我们使用 docker 的意图,是为了在容器中运行我们希望的应用。
另外,,
即本次探索的内容:从基础镜像到目标镜像。
笔者按自己现有理解,制作了以下的简单图示。
上图中:
- “容器”与“镜像”即docker技术所定义的容器与镜像;
- “容器文件”与“镜像文件”都是保存于宿主环境磁盘上的文件;
- 红色X表示删除
- 每一箭头及其附带的单词代表 docker 技术所定义的一项操作指令,从源端获得目标端。例如,从镜像导出镜像文件,使用 docker save 指令,反之使用 docker load。
定义
结合上述图片,笔者尝试解释一下自己认为的目标镜像、目标容器:
目标容器
笔者认为的目标容器,是指在启动后,部署的应用即处于运行状态的容器。那么,此容器之内应当已经存放了运行应用所需的一切文件、以及做好了所有相关配置。
目标镜像
笔者认为的目标镜像,是能够用来直接构建上述目标容器的镜像。
构建方式
按笔者理解,得到目标镜像的方式可以有两种:一是先在某个容器中完成部署、得到目标容器之后,通过commit指令导出;二是使用Dockerfile文件制作。
commit 方式
笔者在首次部署应用时,需要在运行环境中进行一定的调试,并没有在起始即完全知晓,完成部署所需要的每一个动作——例如创建用户、创建路径、配置权限、安装软件包等。
对于这种过程中需要调试的目标镜像构建过程,笔者选择使用 commit 方式,即:
step 0 启动初始容器
从基础镜像 image 0 先(通过 docker run指令)创建一个初始的容器 container 0 并启动。
docker run image:tag /bin/bash
step 1 登陆初始容器,准备操作
先通过dpcker ps -a 指令查看已经出于Up状态的初始容器;
docker ps -a
通过 docker attach 指令,伪终端形式登陆容器
docker attach container-id
step 2 : 调试部署
在运行着的 container 0 中,完成调试和部署,得到一个能够成功运行应用的容器环境
step 3 : 得到目标镜像
确定已经完成部署、容器环境可用后,通过 docker commit 指令操作容器,得到目标镜像:
docker commit container new-image-id:new-tag
验证
现在可以使用 docker images 指令查看镜像是否存在了。
笔者通过 commit 方式得到的镜像,因为过程中有调试步骤,可能包含了一些并不必要的内容,使得其SIZE偏大。
Dockerfile 方式
思路
Dockerfile 方式是指,使用 docker build 命令,从指定的某个镜像开始,执行一个名为“Dockerfile”的文件内指定的一系列命令,最终得到目标镜像。
当完全确定部署所需的每一步骤时,可以选择Dockerfile方式来构建目标镜像。构建过程只会执行 Dockerfile 文件内指定的动作,而不会有其它动作,确保导出的目标镜像完全匹配自己的配置要求。
注意事项
Dockerfile 是一个特定格式的文件;每一行用一个命令关键字为起始,阐述本行指定的信息、或要进行的动作。详细内容可以参考其它教程,这里笔者不多献丑,只补充自己认为要注意的几条。
Dockerfile文件
- 文件名的首字母必须是大写;
- 建议为每个待创建的目标镜像单独创建一个工作路径,将Dockerfile放置于此路径下;否则在构建时还要手动指定 Dockerfile 的具体位置;
- Dockerfile 文件的第一条指令一定要用 FROM,即最开始指定构建所用的基础镜像
- 构建过程严格按照书写内容的顺序,正序执行;那么,按不同顺序排列ADD、COPY、USER、RUN等指令,得到的目标镜像可能是不同的。
COPY/ADD 复制文件
- Dockerfile 允许使用者通过COPY 或 ADD 指令,向目标镜像中的指定位置写入文件。这里能被写入的文件,必须放在docker build 执行时所在路径之下;笔者也建议将要复制到目标镜像中的所有文件都放在统一创建的工作路径下,统一管理。
- 如果在Dockerfile中先用 WORKDIR 指定了工作路径,那么COPY或ADD指令复制的起始目标位置都在工作路径下;为了避免路径错误,笔者都是用绝对路径进行书写。
- COPY 或 ADD 指令复制到镜像中的文件或路径,所有者都是root;为了让这些文件的所有者更改,需要在COPY或ADD指令后使用 --chown=USERNAME:GROUPNAME 。
- 要安装运行Docker-CE、而非docker,才能让上述 --chown 指令生效;否则会报“Unknown flag:chown”的错误。
RUN 构建过程执行动作
- 构建过程中需要执行的动作,用RUN指令执行
- 在使用USER指定用户前,RUN指令以 root 用户执行;指定之后由指定用户身份执行
建议的内容顺序
以下是笔者自己编写的Dockerfile,构建了一个示例可用的目标镜像;目标镜像可以实例出一个容器,在容器中用nodejs 运行一个简单的应用。供参考。
# 基础镜像
FROM centos7-min:7.6.1810
#维护人
MAINTAINER xxx
#创建用户组及用户;这里是以root用户执行
RUN groupadd appgroup
RUN useradd -d /home/app -g appgroup app
# 复制程序;这里执行用户为 root
COPY --chown=app:appgroup Sample/ /home/app/Sample/
COPY --chown=app:appgroup node/ /home/app/node/
# 创建一个软链接;这里执行用户仍为 root
RUN ln -s /home/app/node/bin/node /usr/bin/node
# 指定工作用户
USER app
# 指定工作目录 设置为 app 用户的路径
WORKDIR /home/app/node/bin/
# 暴露端口
EXPOSE 53801 53802
# 容器启动后要执行的指令
CMD node /home/app/Sample/server/Server.js > /home/app/Sample/log/dx.log