web-dev-qa-db-ja.com

docker-compose upの後にスクリプトを実行する方法は?

Docker(-compose)を使用して、開発プロセスをより簡単/保守可能にしようとしています。ボリュームを使用したくありません(可能な場合)。 「docker-compose up -d」を実行した後にimport.shが実行されないのはなぜですか?

次のファイルがあります。

docker-compose.yml
  mysql
  ---- import.sh
  ---- db.sql
  ---- Dockerfile

docker-compose.ymlにあります:

version: '2'

services:
  database:
    image: mysql
    build:
      context: ./mysql/
      dockerfile: Dockerfile
    container_name: mysqltest
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: 123456

/ mysql/Dockerfileにあります:

ADD import.sh /tmp/import.sh
ADD db.sql /tmp/db.sql
RUN /tmp/import.sh

/ mysql/db.sqlにあります:

CREATE DATABASE test1;
CREATE DATABASE test2;
CREATE DATABASE test3;
17
p0rter

DockerfileでENTRYPOINTまたはCMDを使用して、コンテナーの起動時にコマンドを実行できます。それらの違いは、ENTRYPOINTはコンテナが起動されるたびに実行されるのに対し、CMDはコマンドラインオプションに置き換えられる可能性があることです。実行するコマンドがXであると仮定します

docker run my-image Y

ENTRYPOINT XがDockerfileにあった場合はXを実行し、CMD XがDockerfileにあった場合はYを実行します。

ただし、2つの注意事項があります。

  1. コマンドは、コンテナが起動されるたびに実行されます。
  2. コマンドが終了すると、コンテナはシャットダウンされます。

したがって、一般的な解決策は、docker-entrypointスクリプトを使用することです。環境を開始する新しいコンテナで実行されているかどうかをチェックし、その後コンテナの実際のプログラムを実行します。 公式のmysql Dockerfileとエントリポイント を見てアイデアをつかんでください。

エントリポイントスクリプトの例は次のようになります。

$ cat docker_entrypoint.sh                                                                                                                                          
if [ ! -f .initialized ]; then                                                                                                                                                                                    
    echo "Initializing container"                                                                                                                                                                                 
    # run initializing commands                                                                                                                                                                                   
    touch .initialized                                                                                                                                                                                            
fi                                                                                                                                                                                                                

exec "$@"

まず、.initializedというファイルがあるかどうかを確認します。存在しない場合、コンテナ環境を初期化するためにいくつかのコマンドが実行されます。その後、touch .initializedは空のファイルとして.initializedを作成します。したがって、後続のコンテナの起動では、初期化コマンドが再度実行されることはありません。次に、実際のサービスを開始します。 execでこれを行うと、シェルプロセスがサービスのプロセスに置き換えられます。したがって、Dockerはサービスが終了するまでコンテナを実行し続けます。 "$@"には「コンテナ/イメージコマンド」が含まれます。これはDockerfileのCMD Xで設定され、既に上で指摘したように、コマンドでオーバーライドされます。 exec "$@"を使用すると、コンテナ内のさまざまなプログラムを検査用に起動できます。 bash、およびDockerfileのCMDステートメントで指定されているように、デフォルトでサービスを開始します。

20
fzgregor