在容器啟動時啟動一個程序
當您在開發容器中工作時,您可能希望在每次容器啟動時執行一個命令或啟動一些東西。最簡單的方法是使用 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 時,預設的入口點和命令將被覆蓋。首先,使用 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 屬性。