Dockerfile add shell label

Signed-off-by: Kang Huaishuai <khs1994@khs1994.com>
This commit is contained in:
Kang Huaishuai 2020-09-06 20:16:04 +08:00
parent 5d91c5a39f
commit cbaa24c48f
No known key found for this signature in database
GPG Key ID: 5E515022F565DA09
6 changed files with 131 additions and 0 deletions

View File

@ -233,6 +233,8 @@ module.exports = {
'image/dockerfile/workdir',
'image/dockerfile/user',
'image/dockerfile/healthcheck',
'image/dockerfile/label',
'image/dockerfile/shell',
'image/dockerfile/onbuild',
'image/dockerfile/references',
'image/multistage-builds/',

View File

@ -41,6 +41,8 @@
* [USER 指定当前用户](image/dockerfile/user.md)
* [HEALTHCHECK 健康检查](image/dockerfile/healthcheck.md)
* [ONBUILD 为他人作嫁衣裳](image/dockerfile/onbuild.md)
* [LABEL 为镜像添加元数据](image/dockerfile/label.md)
* [SHELL 指令](image/dockerfile/shell.md)
* [参考文档](image/dockerfile/references.md)
* [Dockerfile 多阶段构建](image/multistage-builds/README.md)
* [实战多阶段构建 Laravel 镜像](image/multistage-builds/laravel.md)

View File

@ -7,3 +7,62 @@
`Dockerfile` 中的 `ARG` 指令是定义参数名称以及定义其默认值该默认值可以在构建命令 `docker build` 中用 `--build-arg <参数名>=<值>` 来覆盖
1.13 之前的版本要求 `--build-arg` 中的参数名必须在 `Dockerfile` 中用 `ARG` 定义过了换句话说就是 `--build-arg` 指定的参数必须在 `Dockerfile` 中使用了如果对应参数没有被使用则会报错退出构建 1.13 开始这种严格的限制被放开不再报错退出而是显示警告信息并继续构建这对于使用 CI 系统用同样的构建流程构建不同的 `Dockerfile` 的时候比较有帮助避免构建命令必须根据每个 Dockerfile 的内容修改
ARG 指令有生效范围如果在 `FROM` 指令之前指定那么只能用于 `FROM` 指令中
```docker
ARG DOCKER_USERNAME=library
FROM ${DOCKER_USERNAME}/alpine
RUN set -x ; echo ${DOCKER_USERNAME}
```
使用上述 Dockerfile 会发现无法输出 `${DOCKER_USERNAME}` 变量的值要想正常输出你必须在 `FROM` 之后再次指定 `ARG`
```docker
# 只在 FROM 中生效
ARG DOCKER_USERNAME=library
FROM ${DOCKER_USERNAME}/alpine
# 要想在 FROM 之后使用必须再次指定
ARG DOCKER_USERNAME=library
RUN set -x ; echo ${DOCKER_USERNAME}
```
对于多阶段构建尤其要注意这个问题
```docker
# 这个变量在每个 FROM 中都生效
ARG DOCKER_USERNAME=library
FROM ${DOCKER_USERNAME}/alpine
RUN set -x ; echo 1
FROM ${DOCKER_USERNAME}/alpine
RUN set -x ; echo 2
```
对于上述 Dockerfile 两个 `FROM` 指令都可以使用 `${DOCKER_USERNAME}`对于在各个阶段中使用的变量都必须在每个阶段分别指定
```docker
ARG DOCKER_USERNAME=library
FROM ${DOCKER_USERNAME}/alpine
# 在FROM 之后使用变量必须在每个阶段分别指定
ARG DOCKER_USERNAME=library
RUN set -x ; echo ${DOCKER_USERNAME}
FROM ${DOCKER_USERNAME}/alpine
# 在FROM 之后使用变量必须在每个阶段分别指定
ARG DOCKER_USERNAME=library
RUN set -x ; echo ${DOCKER_USERNAME}
```

17
image/dockerfile/label.md Normal file
View File

@ -0,0 +1,17 @@
# LABEL 指令
`LABEL` 指令用来给镜像以键值对的形式添加一些元数据metadata
```docker
LABEL <key>=<value> <key>=<value> <key>=<value> ...
```
我们还可以用一些标签来申明镜像的作者文档地址等
```docker
LABEL org.opencontainers.image.authors="yeasy"
LABEL org.opencontainers.image.documentation="https://yeasy.gitbooks.io"
```
具体可以参考 https://github.com/opencontainers/image-spec/blob/master/annotations.md

33
image/dockerfile/shell.md Normal file
View File

@ -0,0 +1,33 @@
# SHELL 指令
格式`SHELL ["executable", "parameters"]`
`SHELL` 指令可以指定 `RUN` `ENTRYPOINT` `CMD` 指令的 shellLinux 中默认为 `["/bin/sh", "-c"]`
```docker
SHELL ["/bin/sh", "-c"]
RUN lll ; ls
SHELL ["/bin/sh", "-cex"]
RUN lll ; ls
```
两个 `RUN` 运行同一命令第二个 `RUN` 运行的命令会打印出每条命令并当遇到错误时退出
`ENTRYPOINT` `CMD` shell 格式指定时`SHELL` 指令所指定的 shell 也会成为这两个指令的 shell
```docker
SHELL ["/bin/sh", "-cex"]
# /bin/sh -cex "nginx"
ENTRYPOINT nginx
```
```docker
SHELL ["/bin/sh", "-cex"]
# /bin/sh -cex "nginx"
CMD nginx
```

View File

@ -16,3 +16,21 @@ RUN echo "hello" > world.txt
之前说过每一个 `RUN` 都是启动一个容器执行命令然后提交存储层文件变更第一层 `RUN cd /app` 的执行仅仅是当前进程的工作目录变更一个内存上的变化而已其结果不会造成任何文件变更而到第二层的时候启动的是一个全新的容器跟第一层的容器更完全没关系自然不可能继承前一层构建过程中的内存变化
因此如果需要改变以后各层的工作目录的位置那么应该使用 `WORKDIR` 指令
```docker
WORKDIR /app
RUN echo "hello" > world.txt
```
如果你的 `WORKDIR` 指令使用的相对路径那么所切换的路径与之前的 `WORKDIR` 有关
```docker
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
```
`pwd` 输出的结果为 `/a/b/c`