Dockerfile add shell label
Signed-off-by: Kang Huaishuai <khs1994@khs1994.com>pull/464/head
parent
5d91c5a39f
commit
cbaa24c48f
|
@ -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/',
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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}
|
||||
```
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1,33 @@
|
|||
# SHELL 指令
|
||||
|
||||
格式:`SHELL ["executable", "parameters"]`
|
||||
|
||||
`SHELL` 指令可以指定 `RUN` `ENTRYPOINT` `CMD` 指令的 shell,Linux 中默认为 `["/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
|
||||
```
|
|
@ -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`。
|
||||
|
|
Loading…
Reference in New Issue