Dockerfile

发布时间 2023-08-11 16:43:07作者: 江南烟雨行舟

Dockerfile 是用来构建 Docker 镜像的构建文件,是由一系列命令和参数构成的脚本。

FROM

在 Dockerfile 中只能有一个 FROM 指令,用于指定基础镜像。FROM 指令是 Dockerfile 中的第一个指令,用于构建镜像的起点。

如果你想要在一个 Dockerfile 中使用多个基础镜像,可以考虑使用多阶段构建,每个阶段可以使用不同的基础镜像,最后只需要将构建结果复制到最终的镜像中。

FROM [--platform=<platform>] <image> [AS <name>]
FROM [--platform=<platform>] <image> [:<tag>] [AS <name>]
  1. AS <name> 指定构建阶段名,COPY --from= 会使用到这个阶段名。
  2. tag 是可选的,默认使用一个 latest 标签。
  3. --platform 指定镜像可以在哪个硬件架构下使用:
    • linux/amd64:Linux x86-64(64位)架构,也称为常见的桌面和服务器处理器架构。
    • linux/arm/v6:ARMv6 架构,通常用于较旧的 Raspberry Pi 设备。
    • linux/arm/v7:ARMv7 架构,广泛用于许多嵌入式设备和较早的 Raspberry Pi 设备。
    • linux/arm64:ARMv8 架构,也称为 64 位 ARM 或 ARM64,用于较新的 Raspberry Pi 设备和其他 ARM 64 位架构设备。
    • linux/386:Linux x86(32位)架构,适用于较旧的 32 位 x86 处理器。
    • linux/ppc64le:IBM Power 架构的 64 位低功耗版本,用于 PowerPC 平台。
    • linux/s390x:IBM System z 平台的 64 位版本。

以下是一个多阶段构建的示例 Dockerfile:

# 第一个阶段,使用基础镜像 A
FROM base-image-a AS stage1
# 构建过程...

# 第二个阶段,使用基础镜像 B
FROM base-image-b AS stage2
# 构建过程...

# 最终阶段,使用基础镜像 C
FROM base-image-c AS final-stage
# 将第一个阶段和第二个阶段的构建结果复制到最终阶段
COPY --from=stage1 /path/to/artifacts /path/in/final-stage
COPY --from=stage2 /path/to/artifacts /path/in/final-stage
# 最终构建步骤...

ARG

定义构建参数,构建参数是在构建镜像时可以传递给 Docker 构建引擎的值。它们类似于环境变量,但只在构建过程中可用,不会包含在最终的镜像中。

# 定义构建参数及其默认值
ARG VERSION=latest

# 使用构建参数在构建过程中执行命令
RUN echo "Building version: $VERSION"

# 通过 --build-arg 覆盖构建参数的值
# docker build --build-arg VERSION=1.0

ARG 构建参数不能直接在 CMD 中使用。

ENV

在镜像中设置环境变量,这些变量在容器运行时可以提供给应用程序使用。

# 设置环境变量
ENV APP_VERSION=1.0
ENV DEBUG_MODE=true

# 在构建过程中使用环境变量
RUN echo "Building version: $APP_VERSION"

# 在容器运行时使用环境变量
CMD echo "Running in debug mode: $DEBUG_MODE"

可以通过两种方式覆盖 ENV 指令中设置的环境变量的值:

  1. 在构建时使用 --build-arg 参数覆盖构建参数的默认值。例如 docker build --build-arg APP_VERSION=2.0
  2. 在运行容器时使用 -e 参数或 --env 参数来设置环境变量的值。例如 docker run -e DEBUG_MODE=false image-name

需要注意的是,ENV 指令设置的环境变量会持久存在于镜像中,并且可以被继承。

EXPOSE

指定容器要暴露的端口,暴露给其他容器或主机。其他容器或主机可以与容器内的应用程序或服务进行通信。

# 暴露容器将要监听的端口
EXPOSE 8080

要将容器的暴露的端口映射到主机上的端口,需要在运行容器时使用 -p-P 参数,将主机的端口与容器的端口进行映射。例如:

$ docker run -p 8080:8080 image-name

COPY

用于将本地文件或目录复制到镜像中。

COPY [--from=<name>] [--chown=<user>:<group>] [--chmod=<perms>] <src>... <dest>
COPY [--from=<name>] [--chown=<user>:<group>] [--chmod=<perms>] ["<src>",... "<dest>"]
  • --chown=<用户>:<组>:文件复制到镜像中后,会设置为对应的所有者和组。例如 --chown=root:root 将文件的所有者和组设置为 root。
  • --from=<阶段名>:从其它阶段中复制到当前镜像。

以下是一些 COPY 指令的示例:

# 将单个文件复制到镜像中
COPY app.jar /app/

# 将整个目录复制到镜像中
COPY src/ /app/src/

# 复制多个文件到镜像中
COPY file1.txt file2.txt /app/

# 使用通配符复制多个文件到镜像中
COPY *.txt /app/

拷贝主机文件,文件要放到构建镜像时指定的路径下,拷贝另一个镜像中的文件,必须是绝对路径。

RUN

在构建镜像的时候执行 Shell 命令:

RUN set -eux; \
    apt-get update; \
    apt-get install -y \
        package1 \
        package2; \
    rm -rf /var/lib/apt/lists/*

推荐使用 curl 下载

USER

镜像当中也可以有多个用户,通过 USER 切换到指定用户。

USER <用户名>
USER <UID>[:<GID>]
  • <UID>:指定在容器中运行时使用的用户 ID。
  • <GID>:(可选)指定在容器中运行时使用的组 ID。

WORKDIR

用于设置容器中的工作目录,可以是相对路径或绝对路径,后续的 RUN、CMD、ENTRYPOINT、COPY 和 ADD 等指令都将在该工作目录下执行。

WORKDIR <工作目录路径>

ENTRYPOINT

指定,容器运行后要执行的命令:

  • 指定的是可执行程序,就相当于把容器当作了一个可执行的应用程序,例如:nginx。

  • 指定的是脚本,用来对容器设置环境变量、权限、就做定制化配置,例如 docker-entrypoint.sh,这个脚本是约定好的一个脚本名字,也可以使用其它名字。

ENTRYPOINT ["可执行程序", "参数1", "参数2", ...]

可以在 run 命令的最后追加新的参数:

$ docker run image-name arg1 arg2

可以使用 --entrypoint 选项覆盖 ENTRYPOINT 指定的命令:

$ docker run --entrypoint /bin/sh image-name

CMD

就是为容器提供默认值的。

CMD ["executable","param1","param2"]
# 作为 ENTRYPOINT 的默认参数
# 追加新的参数后,就不会使用默认参数。
CMD ["param1","param2"]

构建镜像

使用 docker build 命令构建镜像的基本语法如下:

docker build [OPTIONS] PATH

#例如
#sudo docker build --no-cache -f rocketmq-dockerfile -t testrocketmq:1 .

sudo docker run -e MODE=standalone -p 8848:8848  -p 9848:9848 -d nacos/nacos-server:v2.2.2-slim


JAVA_HOME=/opt/java/openjdk

sudo docker build --no-cache -f Dockerfile -t testrocketmq:1 .
sudo docker run -d --name testrocketmq -p 8080:8087 -p 9876:9876 -p 10909:10909 -p 10911:10911 -p 10912:10912 --net=host --storage-opt size=40G testrocketmq:1
sudo docker stop testrocketmq
sudo docker rm testrocketmq
sudo docker image rm testrocketmq:1
sudo docker system prune --force

sudo docker image ls
sudo docker ps -a
sudo docker logs 

其中,常用的选项包括:

  • -t, --tag:为镜像指定一个标签,格式为 <repository>:<tag>
  • -f, --file:指定要使用的 Dockerfile 路径和文件名。
  • --build-arg:设置构建过程中使用的构建参数。

PATH 参数指定 Dockerfile 所在的目录路径。在构建过程中,Docker 将自动查找并解析该目录中的 Dockerfile 文件。

调整容器大小

/etc/docker/daemon.json 文件中添加以下内容:

{
  "storage-driver": "devicemapper",
  "storage-opts": [
    "dm.basesize=100G"
  ]
}

在创建容器时:

docker run --storage-opt size=100MB <image-name>

参考资料

https://docs.docker.com/engine/reference/builder/