1. 概述

Docker 是一个用于在隔离环境中打包应用程序的有用工具。它简化了在多个平台上部署应用程序的过程。docker run 命令用于从 Docker 映像启动新的容器。默认情况下,docker run 命令仅在容器内执行单个命令。然而,在某些情况下,我们可能需要在一个 docker run 命令中运行多个命令。

在这篇教程中,我们将讨论如何在 Docker 容器启动时运行多个命令。

2. 使用 docker run 命令

为了在 docker run 命令中执行多个命令,我们可以使用 && 运算符将命令串联在一起。&& 运算符首先执行第一个命令,如果成功,则执行第二个命令。

但是,为了避免在主机 shell 中运行第二个命令,我们需要使用 sh 命令的 -c 选项来同时执行多个命令。

让我们使用 sh -c 来运行 whoamidate 命令:

$ docker run centos:latest sh -c "whoami && date"
root
Sun Dec 18 10:10:12 UTC 2022

这会在一个运行命令中执行 whoamidate 命令。我们也可以使用 sh -c-; 运算符来运行多个命令。此外,让我们使用 -w 选项来指定命令在 Docker 容器中执行的默认工作目录:

$ docker run -w /home centos:latest sh -c "whoami ; pwd"
root
/home

在这里,我们可以看到 whoamipwd 命令都执行了,但这次 /home 是 Docker 容器执行这些命令的默认工作目录。

3. 在 Dockerfile 中使用 CMD/ENTRYPOINT

除了在运行命令中执行多个命令之外,我们还可以在 DockerfileCMD/ENTRYPOINT 部分中指定多个命令。DockerfileCMDENTRYPOINT 定义了容器启动时默认执行的命令。

如果我们在 ENTRYPOINTCMD 部分添加了多个命令,Docker 将按顺序执行它们。

让我们看看 Dockerfile 如何在 ENTRYPOINT 部分指定多个命令:

FROM centos 
ENTRYPOINT ["sh", "-c", "whoami && date"]

为了运行容器,我们首先需要构建镜像:

$ docker build -f Dockerfile -t baeldung_run .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : ENTRYPOINT ["sh", "-c", "whoami && date"]
 ---> Running in dd027b5ba1e9
Removing intermediate container dd027b5ba1e9
 ---> a43dfa09d48b
Successfully built a43dfa09d48b
Successfully tagged baeldung_run:latest

让我们使用上述 baeldung_run:latest 镜像运行一个容器:

$ docker run -itd --name baeldung_run baeldung_run 
b2a8ff012797d6110fd73dfffbf3c39e081f111dc50aac5d9d62fa73845b8a59

现在,我们可以通过查看 baeldung_run 容器的日志文件来验证命令的执行情况:

$ docker logs -f baeldung_run
root
Sun Dec 18 10:13:44 UTC 2022

从上面的输出可以看出,两个命令都成功执行。

我们还可以使用 CMD 指令运行多个命令。让我们看看包含 CMD 指令的 Dockerfile

FROM centos 
CMD ["sh", "-c", "whoami && date"]

再次,我们需要先创建 Docker 镜像,然后运行一个容器。在容器日志中,我们会看到与 ENTRYPOINT 指令生成相同输出。

需要注意的是,CMDENTRYPOINT 指令不能互换使用。它们各自服务于不同的目的。但是,在 ENTRYPOINTCMD 中运行多个命令遵循相同的语法。

4. 总结

在这篇文章中,我们讨论了如何在运行的 Docker 容器中执行多个命令。

首先,我们学习了使用 docker run 命令执行多个命令的方法。之后,我们探讨了在 DockerfileENTRYPOINT/CMD 指令中执行相同操作的方法。