Dockerfile之WORKDIR

本文将介绍Dockerfile的WORKDIR指令,该指令用来切换当前工作目录。

使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。

WORKDIR指令的格式为:

WORKDIR <工作目录路径>

一些初学者常犯的错误是把 Dockerfile 等同于 Shell 脚本来书写,这种错误的理解还可能会导致出现下面这样的错误:

# Dockerfile中的一层
RUN cd /app

# Dockerfile中的另一层
RUN echo "hello" > world.txt

如果将这个 Dockerfile 进行构建镜像运行后,会发现找不到 /app/world.txt 文件,或者其内容不是 hello。原因其实很简单,在 Shell 中,连续两行是同一个进程执行环境,因此前一个命令修改的内存状态,会直接影响后一个命令;而在 Dockerfile 中,这两行 RUN 命令的执行环境根本不同,是两个完全不同的容器。这就是对 Dockerfile 构建分层存储的概念不了解所导致的错误。

每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。第一层 RUN cd /app 的执行仅仅是当前进程的工作目录变更,一个内存上的变化而已,其结果不会造成任何文件变更。而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。

因此如果需要改变以后各层的工作目录的位置,那么应该使用 WORKDIR 指令。

实例:下面是 Docker hub 上面 redis 的 Dockerfile 文件的部分内容。

FROM debian:buster-slim

# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
# 创建 redis 组和 redis 用户
RUN groupadd -r redis && useradd -r -g redis redis

# 省略了其他...

# 创建 /data 目录
RUN mkdir /data && chown redis:redis /data

# 设置 /data 目录为容器数据卷目录
VOLUME /data

# 将当前工作目录切换到 /data 目录
# 如果你进入到 redis 容器,当前目录就是 /data 目录
WORKDIR /data

COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]

# 暴露端口
EXPOSE 6379

# 启动 redis 服务
CMD ["redis-server"]
我们一定要给自己提出这样的任务:第一,学习,第二是学习,第三还是学习。 —— 列宁
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号