コンテナ起動時にプロセスを開始する
開発コンテナで作業している場合、コンテナが起動するたびにコマンドを実行したり、何かを起動したりしたいことがあります。最も簡単な方法は、devcontainer.json
のpostStartCommand
プロパティを使用することです。たとえば、コンテナに接続するたびにyarn install
を実行して依存関係を最新の状態に保ちたい場合は、次のように追加できます。
"postStartCommand": "yarn install"
ビデオ: コンテナ作成時に npm install を実行する
他のケースでは、プロセスを起動して実行し続けたい場合があります。これは、nohup
を使用し、&
を使用してプロセスをバックグラウンドに置くことで実現できます。例:
"postStartCommand": "nohup bash -c 'your-command-here &'"
ビデオ: コンテナ起動時に 'npm start' を実行する
Linuxに詳しい方は、systemd
と呼ばれるものによって管理されるバックグラウンドサービスを起動および停止するためにsystemctl
コマンドを使用できると期待するかもしれません。残念ながら、systemd
はオーバーヘッドが大きく、その結果としてコンテナでは一般的に使用されません。
多くの場合、代わりに使用できるコマンドがあります(例:sshd
)。また、Debian/Ubuntuでは、/etc/init.d
の下に直接実行できるスクリプトがよくあります。
"postStartCommand": "/etc/init.d/ssh start"
これらのシステムには、インストールされているものに基づいてsystemctl
または/etc/init.d
スクリプトを使用するservice
コマンドも含まれています。
"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プロパティの両方が設定されていないことを確認してください。