这可能是一个微不足道的问题,但阅读ARG和ENV的文档并不能让我明白.
我正在构建一个PHP-FPM容器,我希望能够启用/禁用一些用户需求扩展.
如果可以在Dockerfile中通过添加条件并在构建命令上传递标志来完成,那将是很好的,但是不支持AFAIK.
在我的情况下,我个人的方法是在容器启动时运行一个小脚本,如下所示:
#!/bin/sh
set -e
RESTART="false"
# This script will be placed in /config/init/ and run when container starts.
if [ "$INSTALL_XDEBUG" == "true" ]; then
printf "\nInstalling Xdebug ...\n"
yum install -y php71-php-pecl-xdebug
RESTART="true"
fi
...
if [ "$RESTART" == "true" ]; then
printf "\nRestarting php-fpm ...\n"
supervisorctl restart php-fpm
fi
exec "$@"
Run Code Online (Sandbox Code Playgroud)
这是我的Dockerfile样子:
FROM reynierpm/centos7-supervisor
ENV TERM=xterm \
PATH="/root/.composer/vendor/bin:${PATH}" \
INSTALL_COMPOSER="false" \
COMPOSER_ALLOW_SUPERUSER=1 \
COMPOSER_ALLOW_XDEBUG=1 \
COMPOSER_DISABLE_XDEBUG_WARN=1 \
COMPOSER_HOME="/root/.composer" \ …Run Code Online (Sandbox Code Playgroud) 从 Docker v1.10 开始,随着内容可寻址存储的引入,Docker 彻底改变了图像数据在磁盘上的处理方式。我知道现在图层和图像是分开的。层只是成为没有图像概念的文件和目录的集合,可以在图像之间自由共享。请参阅更新和具有更好解释的博客。
在docker push和期间docker pull,通过标准输出可以看到层被传输,尽管生成的 SHA 哈希在目的地完全重新生成。
使用ubuntu:14.04base本地构建的镜像,当我使用该docker history命令时,我可以看到构建过程中使用的一系列中间镜像,以及它们贡献的磁盘空间使用情况。
root@ruifeng-VirtualBox:/var/lib/docker/aufs/diff# docker history image_size
IMAGE CREATED CREATED BY SIZE COMMENT
9ae1f372d83c 11 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin/ 0 B
aaf66e9fa85b 11 weeks ago /bin/sh -c chown -R martian /home/martian 6.299 MB
9568768134c1 11 weeks ago /bin/sh -c rm -rf /home/martian/potatoes 0 B
2f40f3f58306 11 weeks ago /bin/sh -c mv /home/martian/water_tanks /home 6.289 …Run Code Online (Sandbox Code Playgroud) 我已经搜索site:stackoverflow.com dockerfile: ENV, RUN - layers or images并阅读过Docker EXPOSE 会创建新层吗?什么是 Docker 镜像“层”?。
在阅读文档编写 Dockerfile 的最佳实践并尝试理解这一部分时:
每个 ENV 行都会创建一个新的中间层,就像 RUN 命令一样。这意味着即使您在未来的层中取消设置环境变量,它仍然保留在该层中并且可以转储其值。
我想起了上面那部分:
在旧版本的 Docker 中,最大限度地减少映像中的层数以确保它们的性能非常重要。添加了以下功能来减少此限制:
只有 RUN、COPY、ADD 指令才能创建层。其他指令创建临时中间映像,并且不会增加构建的大小。
我已阅读如何在 dockerfile 中取消设置“ENV”?。并重新编写了文档页面上给出的示例,它确实证明ENV没有未设置:
$ docker build -t alpine:envtest -<<HITHERE
> FROM alpine
> ENV ADMIN_USER="mark"
> RUN unset ADMIN_USER
> HITHERE
Sending build context to Docker daemon 3.072kB
Step 1/3 : FROM alpine
latest: Pulling from library/alpine …Run Code Online (Sandbox Code Playgroud) 我一直在阅读文档编写 Dockerfiles 的最佳实践。我遇到了小错误(恕我直言),在进一步阅读后,其含义很清楚:
在 RUN 语句中单独使用 apt-get update 会导致缓存问题并且随后的 apt-get install 指令失败。
我想知道为什么失败。后来他们解释了“失败”的含义:
由于 apt-get 更新未运行,因此您的构建可能会获得过时版本的 curl 和 nginx 包。
但是,对于以下内容,我仍然无法理解“如果不是,则缓存无效。”的含义:
从已经在缓存中的父映像开始,下一条指令与从该基本映像派生的所有子映像进行比较,以查看其中一个是否是使用完全相同的指令构建的。如果不是,则缓存无效。
这部分在 SO 的一些答案中提到,例如Docker 如何知道在构建期间何时使用缓存,何时不使用?总的来说,缓存失效的概念对我来说很清楚,我已经阅读了以下内容:
Docker镜像缓存失效什么时候发生? Docker 使用哪种算法来使缓存失效?
但是“如果不是”是什么意思?起初我确定这句话的意思是如果没有找到这样的图像。那将是矫枉过正 - 使缓存无效,这可能稍后对其他构建有用。事实上,如果我在下面尝试时没有找到图像,它不会失效:
$ docker build -t alpine:test1 - <<HITTT
> FROM apline
> RUN echo "test1"
> RUN echo "test1-2"
> HITTT
Sending build context to Docker daemon 3.072kB
Step 1/3 : FROM apline
pull access denied for apline, repository does not exist or …Run Code Online (Sandbox Code Playgroud) 如果 docker 文件中有 RUN 命令,那么它确实会创建一些中间映像。我的问题是这样的中间图像是否占用了您的硬盘驱动器的任何内存?如果是的话,docker build --rm应该够了吧?