容器启动时启动进程
当您在开发容器中工作时,您可能希望在每次容器启动时执行命令或启动某些内容。最简单的方法是使用 devcontainer.json
中的 postStartCommand
属性。例如,如果您希望每次连接到容器时都运行 yarn install
以保持依赖项为最新,您可以添加以下内容
"postStartCommand": "yarn install"
视频:在创建容器时运行 npm install
在其他情况下,您可能希望启动一个进程并使其保持运行状态。这可以通过使用 nohup
并使用 &
将进程放入后台来完成。例如
"postStartCommand": "nohup bash -c 'your-command-here &'"
视频:在容器启动时运行 'npm start'
熟悉 Linux 的用户可能希望能够使用 systemctl
命令来启动和停止由名为 systemd
的东西管理的后台服务。不幸的是,systemd
有开销,因此通常不用于容器中。
在许多情况下,您可以运行一个替代命令(例如,sshd
)。在 Debian/Ubuntu 上,通常在 /etc/init.d
下有可以直接运行的脚本。
"postStartCommand": "/etc/init.d/ssh start"
这些系统还包含一个 service
命令,该命令将根据安装的内容使用 systemctl
或 /etc/init.d
脚本。
"postStartCommand": "service ssh start"
视频:在容器中启动 SSH 服务
改为将启动命令添加到 Docker 镜像中
虽然 postStartCommand
很方便,并且允许您在源代码树中执行命令,但您也可以改为使用自定义 ENTRYPOINT 或 CMD 将这些步骤添加到 Dockerfile 中。
当在 devcontainer.json
中引用 Dockerfile 时,默认的 entrypoint 和 command 会被覆盖。首先,使用 overrideCommand
属性禁用此行为。
"overrideCommand": false
overrideCommand
属性默认为 true
,因为许多镜像在未指定命令时会立即退出。相反,我们需要在 Dockerfile 中处理这个问题。
接下来,考虑以下 Dockerfile
FROM mcr.microsoft.com/devcontainers/base:1-ubuntu
COPY docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT [ "/docker-entrypoint.sh" ]
CMD [ "sleep", "infinity" ]
此处的 CMD
确保容器默认保持运行状态。将启动步骤保留在 ENTRYPOINT
中允许您在使用 docker run
运行镜像或使用 Docker Compose 时安全地覆盖命令。这将解析为以下内容
/docker-entrypoint.sh sleep infinity
接下来,创建一个 docker-entrypoint.sh
脚本
#!/usr/bin/env bash
echo "Hello from our entrypoint!"
exec "$@"
您在此文件中执行的任何操作都将在每次容器启动时触发。但是,务必包含最后的 exec "$@"
行,因为这将导致示例中的命令 sleep infinity
被触发。
最后,如果您正在使用 Docker Compose,请确保没有为您的容器设置 entrypoint 和 command 属性。