1. 使用Commit构建镜像
使用 docker commit 命令虽然可以比较直观的帮助理解镜像分层存储的概念,使用 docker commit 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为 黑箱镜像
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
$ docker commit \
--author "Tao Wang <twang2218@gmail.com>" \ //作者
--message "修改了默认网页" \ //msg
webserver \ //from
nginx:v2 //名字
sha256:07e33465974800ce65751acc279adc6ed2dc5ed4e0838f8b86f0c87aa1795214// 指定的镜像
2. 使用Dockerfile定制镜像
Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。 Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是不得超过 127 层
scratch 这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。
FROM nginx //指定基础镜像
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
// RUN :执行命令行命令
1.shell RUN <命令>,就像直接在命令行中输入的命令一样。
2.RUN ["可执行文件", "参数1", "参数2"],这更像是函数调用中的格式
每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
COPY指令将从构建上下文目录中《源路径》的文件/目录复制到新的一层
的镜像内的《目标路径》位置。
COPY package.json /usr/src/app/
源路径也可以是通配符
COPY hom* /mydir/ | COPY hom?.txt /mydir/
在使用该指令的时候还可以加上
--chown=<user>:<group> 选项来改变文件的所属用户及所属组。
COPY --chown=55:mygroup files* /mydir/
ADD 更高级的复制文件 和COPY一致,但是增加一些功能
1.自动解压缩(只有明确需要解压缩的时候使用ADD,其他都是用COPY)
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
CMD 容器启动命令
shell 格式:CMD <命令>
CMD echo $HOME
exec 格式:CMD ["可执行文件", "参数1", "参数2"...]
CMD [ "sh", "-c", "echo $HOME" ]
参数列表格式:CMD ["参数1", "参数2"...]。
CMD 指令就是用于指定默认的容器主进程的启动命令的。
在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。
Docker 不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,
需要指定所运行的程序及参数。
ENTRYPOINT 入口点
ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。
当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,
不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,
换句话说实际执行时,将变为:<ENTRYPOINT> "<CMD>"
docker run myip -i
跟在镜像名后面的是 command,运行时会替换 CMD 的默认值
ENV 设置环境变量
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
ENV VERSION=1.0 DEBUG=on \
NAME="Happy Feet"
ARG 构建参数
ARG <参数名>[=<默认值>]
构建参数和 ENV 的效果一样,都是设置环境变量。
所不同的是,ARG 所设置的构建环境的环境变量,
在将来容器运行时是不会存在这些环境变量的。
但是不要因此就使用 ARG 保存密码之类的信息
,因为 docker history 还是可以看到所有值的。
VOLUME 定义匿名卷
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
容器运行时保持容器储存层不发生写操作,对于数据库类需要保存动态数据的
应用,应该将数据文件挂载在卷中。
VOLUME /data
docker run -d -v mydata:/data xxxx
在这行命令中,就使用了 mydata
这个命名卷挂载到了 /data 这个位置,替代了 Dockerfile 中定义的匿名卷的挂载配置
EXPOSE 声明端口
EXPOSE <端口1> [<端口2>...]
声明运行容器提供服务端口,只是声明,运行容器时不会开启这个服务的端口。
docker run -p 时,会自动映射到expose的端口
WORKDIR 指定工作目录
WORKDIR <工作目录路径>
如果不存在,则会新建
因此如果需要改变以后各层的工作目录的位置,那么应该使用 WORKDIR 指令。
USER 指定当前用户
USER <用户名>[:<用户组>]
User和workdir相似,都是改变环境装填并影响以后的层。
wordDIR是改变工作目录,USER则是改变之后层执RUN,CMD,ENTYYPOINT这类命令的身份。
切换指定用户必须存在
HEALTHCHECK 健康检查
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
--interval=<间隔>:两次健康检查的间隔,默认为 30 秒;
--timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
--retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次。
##2.1 运行dockerFile
docker build [选项] <上下文路径/URL/->
// 从git仓库直接构建
docker build https://github.com/twang2218/gitlab-ce-zh.git#:11.1
// 从给定给的压缩包构建
docker build http://server/context.tar.gz
// 从输入流中构建
docker build - < Dockerfile | cat Dockerfile | docker build -
// 从标准输入中读取上下文压缩包进行构建
docker build - < context.tar.gz
2.2 镜像构建上下文(Context)
当构建的时候,用户会指定构建镜像上下文的路径,docker build 命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎。这样 Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件。
../package.json /app 或者 COPY /opt/xxxx /app 无法工作的原因,因为这些路径已经超出了上下文的范围,Docker 引擎无法获得这些位置的文件。如果真的需要那些文件,应该将它们复制到上下文目录中去。