そこで、Go Webサーバーをデプロイするためにdocker composeファイルに取り組んでいます。私のサーバーはmongoを使用しているため、データボリュームコンテナーとmongoサービスをdocker composeに追加しました。次に、Goプロジェクトをビルドして最終的に実行するためにDockerfileを作成しました。
ただし、実行する必要がある別の手順があります。プロジェクトをコンパイルしたら、次のコマンドを実行する必要があります:./my-project -setup
これにより、必要な情報がデータベースに追加され、その情報が一度だけ追加する必要がありますになります。ただし、mongoは既に起動している必要があるため、この手順を(ビルドプロセスで)Dockerfileに追加することはできません。
それで、どうすればこれを達成できますか?サーバーを再起動してからdocker-compose up
を再度実行しても、このコマンドを再度実行したくないのです。
私は実際にデータボリュームコンテナについてすべてを理解していないため、Dockerの理解が不足していると思います(ボリュームをマウントするコンテナは単にstoppedコンテナですか? ?)。また、サーバーを再起動してからdocker-compose up
を実行すると、どのコマンドが実行されますか?与えられたCMDで停止したのと同じコンテナーを起動するだけですか?
いずれにせよ、ここに私のdocker-compose.ymlがあります:
version: '2'
services:
mongodata:
image: mongo:latest
volumes:
- /data/db
command: --break-mongo
mongo:
image: mongo:latest
volumes_from:
- mongodata
ports:
- "28001:27017"
command: --smallfiles --rest --auth
my_project:
build: .
ports:
- "6060:8080"
depends_on:
- mongo
- mongodata
links:
- mongo
そして、ここに私のプロジェクトイメージをビルドするためのDockerfileがあります:
FROM golang
ADD . /go/src/my_project
RUN cd /go/src/my_project && go get
RUN go install my_project
RUN my_project -setup
ENTRYPOINT /go/bin/my_project
EXPOSE 8080
コンテナにentrypoint-scriptを追加することをお勧めします。このエントリポイントスクリプトでは、データベースが初期化されているかどうかを確認できます。初期化されていない場合は、必要な手順を実行します。
あなたの質問で気づいたように、サービス/コンテナが開始される順序は当然とみなされるべきではないので、アプリケーションコンテナが開始される可能性がありますbeforeデータベースコンテナ、それでスクリプトはそれを取り入れるべきですアカウント。
例として、公式のWordPressイメージをご覧ください。このイメージは、entrypoint-scriptでデータベースの1回限りの初期化を実行します。スクリプトは、データベースへの接続を試行します。データベースに接続できません(まだ))、初期化が必要かどうかを確認します; https://github.com/docker-library/wordpress/blob/df190dc9c5752fd09317d836bd2bdcd09ee379a5/Apache/docker-entrypoint.sh#L146-L171
[〜#〜] note [〜#〜]
ボリュームをアタッチするための「データ専用コンテナー」を作成しました。 Docker 1.9以降、dockerにはボリュームの命名を含むボリューム管理があります。このため、「データ専用」コンテナを使用する必要はなくなりました。
作成ファイルからデータ専用コンテナーを削除し、mongoサービスを次のように変更できます。
mongo:
image: mongo:latest
volumes:
- mongodata:/data/db
ports:
- "28001:27017"
command: --smallfiles --rest --auth
これにより、mongodata
という名前の新しいボリュームが存在しない場合は作成されるか、その名前の既存のボリュームが再利用されます。 docker volume ls
を使用してすべてのボリュームをリストし、不要になった場合はdocker volume rm <some-volume>
でボリュームを削除できます
ONBUILD
命令 を使用してみてください:
ONBUILD
命令は、イメージが別のビルドのベースとして使用されるときに、後で実行されるトリガー命令をイメージに追加します。トリガーは、ダウンストリームFROM
のDockerfile
命令の直後に挿入されたかのように、ダウンストリームビルドのコンテキストで実行されます。
任意のビルド命令をトリガーとして登録できます。
これは、他のイメージをビルドするためのベースとして使用されるイメージをビルドする場合に便利です。たとえば、ユーザー固有の構成でカスタマイズできるアプリケーションビルド環境やデーモンです。
たとえば、イメージが再利用可能なPythonアプリケーションビルダーの場合、特定のディレクトリにアプリケーションソースコードを追加する必要があり、ビルドスクリプトの呼び出しが必要になる場合がありますafterそれ。ADD
とRUN
を呼び出すことはできません、まだアプリケーションソースにアクセスできないためですコードを作成し、アプリケーションのビルドごとに異なります。アプリケーション開発者にボイラープレートDockerfile
を提供するだけでコピーしてアプリケーションに貼り付けることができますが、それは非効率的でエラーが発生しやすく、更新が難しいためですアプリケーション固有のコード。
解決策は、ONBUILD
を使用して、次のビルド段階で後で実行する事前指示を登録することです。
仕組みは次のとおりです。
ONBUILD
命令が検出されると、ビルダーは作成中のイメージのメタデータにトリガーを追加します。それ以外の場合、命令は現在のビルドに影響しません。OnBuild
の下に保存されます。それらはdocker inspect
コマンドで検査できます。FROM
命令を使用して、新しいビルドのベースとして使用できます。 FROM
命令の処理の一環として、ダウンストリームビルダーはONBUILD
トリガーを探し、それらが登録されたのと同じ順序で実行します。トリガーのいずれかが失敗すると、FROM
命令が中止され、ビルドが失敗します。すべてのトリガーが成功すると、FROM
命令が完了し、ビルドは通常どおり続行されます。アプリケーションを機能させるには、初期状態が必要です。それはあなたがすべきことを意味します:
現在のデータベースの状態をチェックするプログラムを作成できます(ここではbashスクリプトを使用しますが、他のすべての言語プログラムでもかまいません)。
RUN if $(./check.sh); then my_project -setup; fi
私の場合、スクリプトが0(成功終了ステータス)を返すと、setup
コマンドが呼び出されます。