コンテナの起動時にプロセスを開始する
開発コンテナで作業しているとき、コンテナが起動するたびにコマンドを実行したり、何かを開始したりしたい場合があります。これを行う最も簡単な方法は、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 プロパティも設定されていないことを確認してください。