docker-compose.yml
ファイルがあることを
docker-compose.yml
ます。
これを行うことが必要になる理由はいくつかあります。
- 巨大システムの低接続コンポーネントの開発 実際、各プロジェクトは個別の独立したアプリケーションになることができます
- テストのために個々のコンポーネントを接続します。 独自のリンクおよび相互作用ロジックを使用して、
mock
サービスとテストを別々のコンテナーに配置 - それにもかかわらず、ドッカー環境で「生きている」プロジェクトシステムの外部
内容
問題
実際、
N
ファイルを1つにまとめて、完全なアプリケーションとして起動することが主な問題になりました。 既存のファイルを1つずつ単純にマージするだけでは許可されなかった二次的な問題になったもの
- コンテナ名が構成ツリー全体の更新と競合しています
- ホストポート転送の競合
- サービスプロパティのオーバーライド
- 相対パス解像度
- 冗長または重複サービスの削除
解決策
したがって、心を費やして、数日間休みを取り、単純な
python
プリプロセッサを書くようになりました。これは、
docker-compose
ファイルを結合するすべての
その結果、全体として小さな(600行のコード) スクリプトを取得し、かつて私の前にあった問題を完全に解決しました。
ただし、ボーナスとして、上記で特定した問題に加えて、スクリプトは別の興味深い問題の解決に役立ちました。 つまり、小さな推論の後、1つの
docker-compose
ファイルでアプリケーションの複数のインスタンスを同時に実行することができました。
使用例
このソリューションをすばやく使用できるようにするいくつかの手順
設置
パックされた
python
モジュールであるバイナリファイルをダウンロードする必要があります
設置
sudo wget https://github.com/paunin/docker-compose-mixer/blob/master/dist/dc-mixer?raw=true -O /usr/local/bin/dc-mixer sudo chmod +x /usr/local/bin/dc-mixer
構成
docker-compose-mixer.yml
ファイルの内容は、本質的に2つ以上のプロジェクトがどのように一緒に開始されるかを記述する小さな設定です。
2つのプロジェクト
project A
と
project B
、2つの
docker-compose.yml
ファイルがあるとします。
システムの異なるバージョンであるプロジェクトは、一連のサービスを備えたアプリケーションです:
java-application, redis, rabbitmq, mail
、
project A
(新しいバージョン)には
mysql
サービスも含まれます。
投影する
$ cat ../proj_a/docker-compose.yml sources: build: images/sources volumes: - .:/var/application.host application: build: images/java dockerfile: application.yml dns: - 8.8.8.8 - 9.9.9.9 hostname: application.host working_dir: /var/application.host cgroup_parent: m-executor-abcd links: - redis:redis - rabbitmq - mail - mysql:db volumes_from: - sources command: "/start.sh" env_file: - ./env_files/application.env - ./env_files/rabbit.env environment: - DB_DRIVER: mysql - DB_PORT: 3306 ports: - "80:80" #http - "1098:1098" #jmx external_links: - redis_1 - project_db_1:mysql extra_hosts: - "somehost:162.242.195.82" labels: com.example.description: "Accounting webapp" com.example.department: "Finance" redis: labels: - "com.example.description=Accounting webapp" - "com.example.department=Finance" extends: file: ../redis.yml service: redisbase expose: ports: - "6379:6379" - "127.0.0.1:6370:6370" log_driver: "syslog" log_opt: syslog-address: "tcp://192.168.0.42:123" net: "bridge" rabbitmq: build: images/rabbitmq ports: - "15672:15672" volumes_from: - sources command: /start.sh env_file: - ./env_files/rabbit.env mail: build: images/mail hostname: mail domainname: application.host expose: - 25 - 143 ports: - "25:25" - "143:143" volumes: - ./images/mail/spamassassin:/tmp/spamassassin/ - ./images/mail/postfix:/tmp/postfix/ - ./images/mail/mail:/tmp/mail/ mysql: build: images/mysql ports: - 3602
プロジェクトB
$ cat ./proj_b/docker-compose.yml sources: build: images/sources volumes: - .:/var/application.host application: build: images/java dockerfile: application.yml dns: - 8.8.8.8 - 9.9.9.9 hostname: application.host working_dir: /var/application.host cgroup_parent: m-executor-abcd links: - redis:redis - rabbitmq - mail volumes_from: - sources command: "/start.sh" env_file: - ./env_files/application.env - ./env_files/rabbit.env environment: - VARIABLE: value ports: - "80:80" #http - "1098:1098" #jmx external_links: - redis_1 - project_db_1:mysql extra_hosts: - "somehost:162.242.195.82" labels: com.example.description: "Accounting webapp" com.example.department: "Finance" redis: labels: - "com.example.description=Accounting webapp" - "com.example.department=Finance" extends: file: ../redis.yml service: redisbase expose: ports: - "6379:6379" - "127.0.0.1:6370:6373" log_driver: "syslog" log_opt: syslog-address: "tcp://192.168.0.42:123" net: "bridge" rabbitmq: build: images/rabbitmq ports: - "15672:15672" volumes_from: - sources command: /start.sh env_file: - ./env_files/rabbit.env mail: build: images/mail hostname: mail domainname: application.host expose: - 25 - 143 ports: - "25:25" - "143:143" volumes: - ./images/mail/spamassassin:/tmp/spamassassin/ - ./images/mail/postfix:/tmp/postfix/ - ./images/mail/mail:/tmp/mail/
基本的なタスクは、1つの
rabbitmq
サービスのみを使用して2つの環境を1つに結合することです。 さらに、新しい
pgsql
サービスを作成し、それを最初のプロジェクトに接続する必要があります(mysqlを置き換える)
ファイルを結合するための構成は、ファイル
./docker-compose-mixer.yml
にある必要があります(オプション
-i, --input-file
は
-i, --input-file
別の名前を指定できます)
docker-compose-mixer.yml
$ cat ./docker-compose-mixer.yml includes: proja: ../proj_a/docker-compose.yml projb: ./proj_b/docker-compose.yml ignores: - projbrabbitmq overrides: projbapplication: links: - projaredis:redis - projarabbitmq:rabbitmq - projamail:mail projaapplication: links: - projaredis:redis - projarabbitmq:rabbitmq - projamail:mail - pgsql:db environment: - DB_DRIVER: pgsql - DB_PORT: 5432 master_services: pgsql: image: pgsql:latest expose: - 5432 ports: 5432:5432
打ち上げ
`
dc-mixer -v
コマンドは、プリプロセッサを言語モードで起動し、結果をファイルに保存します。 起動オプションは、動作を制御するのに役立ちます。
起動オプション
$ dc-mixer --help Compile docker-compose from several docker-compose.yml files Usage: dc-mixer [options] Options: -h, --help Print help information -i, --input-file Input file (default `docker-compose-mixer.yml` in current directory) -o, --output-file Output file (default `docker-compose.yml` in current directory) -h, --help Print help information -v, --verbose Enable verbose mode For more information read documentation: https://github.com/paunin/docker-compose-mixer
結果
デフォルトでは、ファイルのマージ結果は
./docker-compose.yml
ファイルに保存されます。 (オプション
-o, --output-file
は、ファイルに別の名前を指定できます)
スクリプトの結果
$ dc-mixer -v -o docker-compose.yml DEBUG:root:Start compiling compose file... DEBUG:root:Input file: /Users/paunin/Sites/dc-mixer.local/examples/example2/proj/docker-compose-mixer.yml; output file: docker-compose.yml DEBUG:root:Mixer config is below: {'overrides': {'projbapplication': {'links': ['projaredis:redis', 'projarabbitmq:rabbitmq', 'projamail:mail']}, 'projaapplication': {'environment': {'DB_DRIVER': 'pgsql', 'DB_PORT': 5432}, 'links': ['projaredis:redis', 'projarabbitmq:rabbitmq', 'projamail:mail', 'pgsql:db']}}, 'master_services': {'pgsql': {'image': 'pgsql:latest', 'expose': [5432], 'ports': '5432:5432'}}, 'ignores': ['projbrabbitmq'], 'includes': {'projb': './proj_b/docker-compose.yml', 'proja': '../proj_a/docker-compose.yml'}} DEBUG:root:Creating scope for file: /Users/paunin/Sites/dc-mixer.local/examples/example2/proj/proj_b/docker-compose.yml and prefix: projb DEBUG:root:Creating scope for file: /Users/paunin/Sites/dc-mixer.local/examples/example2/proj_a/docker-compose.yml and prefix: proja DEBUG:root:Resolving services names DEBUG:root:Resolving services paths with DEBUG:root:Resolving services ports DEBUG:root:Redefined ports: {'projaapplication': {80: 81, 1098: 1099}, 'projaredis': {6370: 6371, 6379: 6380}, 'projamail': {25: 26, 143: 144}} DEBUG:root:Result scope is: {'projasources': {'build': '../proj_a/images/sources', 'volumes': ['./../proj_a:/var/application.host']}, 'projaredis': {'log_opt': {'syslog-address': 'tcp://192.168.0.42:123'}, 'log_driver': 'syslog', 'expose': None, 'labels': ['com.example.description=Accounting webapp', 'com.example.department=Finance'], 'extends': {'service': 'redisbase', 'file': '../redis.yml'}, 'net': 'bridge', 'ports': ['6380:6379', '127.0.0.1:6371:6370']}, 'projbmail': {'domainname': 'application.host', 'expose': [25, 143], 'hostname': 'mail', 'build': 'proj_b/images/mail', 'volumes': ['./proj_b/images/mail/spamassassin:/tmp/spamassassin/', './proj_b/images/mail/postfix:/tmp/postfix/', './proj_b/images/mail/mail:/tmp/mail/'], 'ports': ['25:25', '143:143']}, 'projamail': {'domainname': 'application.host', 'expose': [25, 143], 'hostname': 'mail', 'build': '../proj_a/images/mail', 'volumes': ['./../proj_a/images/mail/spamassassin:/tmp/spamassassin/', './../proj_a/images/mail/postfix:/tmp/postfix/', './../proj_a/images/mail/mail:/tmp/mail/'], 'ports': ['26:25', '144:143']}, 'pgsql': {'image': 'pgsql:latest', 'expose': [5432], 'ports': '5432:5432'}, 'projbapplication': {'hostname': 'application.host', 'links': ['projaredis:redis', 'projarabbitmq:rabbitmq', 'projamail:mail'], 'cgroup_parent': 'm-executor-abcd', 'labels': {'com.example.description': 'Accounting webapp', 'com.example.department': 'Finance'}, 'extra_hosts': ['somehost:162.242.195.82'], 'environment': [{'VARIABLE': 'value'}], 'working_dir': '/var/application.host', 'command': '/start.sh', 'build': 'proj_b/images/java', 'dns': ['8.8.8.8', '9.9.9.9'], 'volumes_from': ['projbsources'], 'env_file': ['proj_b/env_files/application.env', 'proj_b/env_files/rabbit.env'], 'dockerfile': 'application.yml', 'ports': ['80:80', '1098:1098'], 'external_links': ['redis_1', 'project_db_1:mysql']}, 'projaapplication': {'hostname': 'application.host', 'links': ['projaredis:redis', 'projarabbitmq:rabbitmq', 'projamail:mail', 'pgsql:db'], 'cgroup_parent': 'm-executor-abcd', 'labels': {'com.example.description': 'Accounting webapp', 'com.example.department': 'Finance'}, 'extra_hosts': ['somehost:162.242.195.82'], 'environment': {'DB_DRIVER': 'pgsql', 'DB_PORT': 5432}, 'working_dir': '/var/application.host', 'command': '/start.sh', 'build': '../proj_a/images/java', 'dns': ['8.8.8.8', '9.9.9.9'], 'volumes_from': ['projasources'], 'env_file': ['../proj_a/env_files/application.env', '../proj_a/env_files/rabbit.env'], 'dockerfile': 'application.yml', 'ports': ['81:80', '1099:1098'], 'external_links': ['redis_1', 'project_db_1:mysql']}, 'projamysql': {'build': '../proj_a/images/mysql', 'ports': []}, 'projarabbitmq': {'volumes_from': ['projasources'], 'env_file': ['../proj_a/env_files/rabbit.env'], 'command': '/start.sh', 'build': '../proj_a/images/rabbitmq', 'ports': ['15672:15672']}, 'projbredis': {'log_opt': {'syslog-address': 'tcp://192.168.0.42:123'}, 'log_driver': 'syslog', 'expose': None, 'labels': ['com.example.description=Accounting webapp', 'com.example.department=Finance'], 'extends': {'service': 'redisbase', 'file': 'redis.yml'}, 'net': 'bridge', 'ports': ['6379:6379', '127.0.0.1:6370:6373']}, 'projbsources': {'build': 'proj_b/images/sources', 'volumes': ['./proj_b:/var/application.host']}} DEBUG:root:Save result scope in the file "docker-compose.yml"
結果のdocker-compose.yml
pgsql: expose: - 5432 image: "pgsql:latest" ports: "5432:5432" projaapplication: build: ../proj_a/images/java cgroup_parent: m-executor-abcd command: /start.sh dns: - "8.8.8.8" - "9.9.9.9" dockerfile: application.yml env_file: - ../proj_a/env_files/application.env - ../proj_a/env_files/rabbit.env environment: DB_DRIVER: pgsql DB_PORT: 5432 external_links: - redis_1 - "project_db_1:mysql" extra_hosts: - "somehost:162.242.195.82" hostname: application.host labels: com.example.department: Finance com.example.description: "Accounting webapp" links: - "projaredis:redis" - "projarabbitmq:rabbitmq" - "projamail:mail" - "pgsql:db" ports: - "81:80" - "1099:1098" volumes_from: - projasources working_dir: /var/application.host projamail: build: ../proj_a/images/mail domainname: application.host expose: - 25 - 143 hostname: mail ports: - "26:25" - "144:143" volumes: - "./../proj_a/images/mail/spamassassin:/tmp/spamassassin/" - "./../proj_a/images/mail/postfix:/tmp/postfix/" - "./../proj_a/images/mail/mail:/tmp/mail/" projamysql: build: ../proj_a/images/mysql ports: [] projarabbitmq: build: ../proj_a/images/rabbitmq command: /start.sh env_file: - ../proj_a/env_files/rabbit.env ports: - "15672:15672" volumes_from: - projasources projaredis: expose: ~ extends: file: ../redis.yml service: redisbase labels: - "com.example.description=Accounting webapp" - com.example.department=Finance log_driver: syslog log_opt: syslog-address: "tcp://192.168.0.42:123" net: bridge ports: - "6380:6379" - "127.0.0.1:6371:6370" projasources: build: ../proj_a/images/sources volumes: - "./../proj_a:/var/application.host" projbapplication: build: proj_b/images/java cgroup_parent: m-executor-abcd command: /start.sh dns: - "8.8.8.8" - "9.9.9.9" dockerfile: application.yml env_file: - proj_b/env_files/application.env - proj_b/env_files/rabbit.env environment: - VARIABLE: value external_links: - redis_1 - "project_db_1:mysql" extra_hosts: - "somehost:162.242.195.82" hostname: application.host labels: com.example.department: Finance com.example.description: "Accounting webapp" links: - "projaredis:redis" - "projarabbitmq:rabbitmq" - "projamail:mail" ports: - "80:80" - "1098:1098" volumes_from: - projbsources working_dir: /var/application.host projbmail: build: proj_b/images/mail domainname: application.host expose: - 25 - 143 hostname: mail ports: - "25:25" - "143:143" volumes: - "./proj_b/images/mail/spamassassin:/tmp/spamassassin/" - "./proj_b/images/mail/postfix:/tmp/postfix/" - "./proj_b/images/mail/mail:/tmp/mail/" projbredis: expose: ~ extends: file: redis.yml service: redisbase labels: - "com.example.description=Accounting webapp" - com.example.department=Finance log_driver: syslog log_opt: syslog-address: "tcp://192.168.0.42:123" net: bridge ports: - "6379:6379" - "127.0.0.1:6370:6373" projbsources: build: proj_b/images/sources volumes: - "./proj_b:/var/application.host"
自動的に変更されたポートに関する情報を表示するデバッガー `
DEBUG:root:Redefined ports
の出力セクションに注目したいと思います。
サンプルのソースはこちらにあります。
資源
- Githubプロジェクト: github.com/paunin/docker-compose-mixer
- Docker-compose構文: docs.docker.com/compose/compose-file