質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

Webサーバー

Webサーバーとは、HTTPリクエストに応じて、クライアントに情報を提供するシステムです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

解決済

2回答

4222閲覧

docker-compose.ymlでdepends_onを使わないで依存関係が生まれている理由を知りたい。

Kchan_01

総合スコア110

docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

Webサーバー

Webサーバーとは、HTTPリクエストに応じて、クライアントに情報を提供するシステムです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

0クリップ

投稿2020/06/17 02:54

編集2020/06/17 03:00

最強のLaravel開発環境をDockerを使って構築する【新編集版】 - Qiita

こちらの記事に従って、開発環境をしているDockerを学びたての初心者です。

以下のdocker-compose.ymlを読んでいて疑問に思った点があったので質問させてください。

docker

1version: "3.8" 2volumes: 3 db-store: 4 php-fpm-socket: 5services: 6 app: 7 build: ./docker/php 8 volumes: 9 - php-fpm-socket:/var/run/php-fpm 10 - ../backend:/work/backend 11 - ./docker/php/bash/.bash_history:/root/.bash_history 12 - ./docker/php/bash/psysh:/root/.config/psysh 13 14 web: 15 build: ./docker/nginx 16 ports: 17 - 80:80 18 volumes: 19 - php-fpm-socket:/var/run/php-fpm 20 - ../backend:/work/backend 21 22 db: 23 build: ./docker/mysql 24 volumes: 25 - db-store:/var/lib/mysql 26 ports: 27 - 3306:3306

docker-laravel/docker-compose.yml at master · ucan-lab/docker-laravel

app,web,dbと依存関係が記載されていないのに、エラーが起きずに動く理由が知りたいです。
私の理解ではwebはappに依存関係があると思うのですが、このdocker-compose.ymlにはdepends_onが使われていません。

どうやって接続をコントロールしているのでしょうか。

よろしくおねがいします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

depends_onはコンテナの作成順序を決めるだけのもので質問者さんが想像するようなコンテナ間の依存関係を定義するものではありません。
depends_onが指定されていない場合、コンテナは~~記載された上から順番に作成されます。~~同時に作成されます。

また、冒頭に説明したようにコンテナの作成順を決めるだけなので、コンテナ中のプログラムやサービスの起動完了を待つわけではありません。ここに最も注意が必要です。

本件でwebappに対して依存する要素はpho-fpm用のドメインソケットが作成されるディレクトリの共有部分- php-fpm-socket:/var/run/php-fpmのみで、app側が先にマウントしないといけませんが、これはコンテナ作成時にボリュームの共有化が完了するためコンテナ作成後の中身の処理が速かろうが遅延していようが関係ないので大丈夫になっています。

要するに、本件に限って言えば接続や中身のサービスをコントロールする必要が(たまたま)なかっただけです。

追記

docker-compose upだけで運用するなら全然問題ないのですが、docker-compose up [service-name]のように引数にサービス名をつけてupするような場合、起動サービスのdepends_onで記載されたサービスが先にビルドされます。無関係のサービスはビルドされません。このような場合では依存関係の記載が有効でしょう。
でもサービス名つけてupするような用事はほとんどないような・・・

追記2

本文も修正しましたが、depends_onが指定されていない場合、それぞれのコンテナは同時に作成が開始されます。
コンテナ作成開始時に、docker内部DNSにサービス名でアドレスが引けるよう登録されるようです。
bsdfanさんのコメント通り、nginx起動時にconfファイルを読み込み転送先ホストの名前解決を行うようです(相手ホストとの通信は発生せず、名前解決のみ?)それまでにDNSに相手ホスト情報が登録されていなければエラーとなりますが、コンテナが同時に起動されていれば十分間に合うようです。
意図的に逆向きにdepends_onを記載していない限りは実質大丈夫だと思われます。

投稿2020/06/17 04:35

編集2020/06/18 04:40
hope_mucci

総合スコア4447

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kchan_01

2020/06/17 06:46 編集

ご回答ありがとうございます。 以下のコードは別のdocker-compose.ymlです。 以下ではTCP通信を行うため、nginxのphpに対する依存関係が生まれる。 TCP通信ではビルド直後に最初に通信が行われる?ためdepends_onを使用している。という理解で良いでしょうか。 質問に上げたファイルはphp-fpm-socket:/var/run/php-fpmを共通部分としてUNIXドメインソケットを使用しており、 > コンテナ作成時にボリュームの共有化が完了するため ビルドの順番が関係ない。ということでしょうか。 ```docker-compose.yml version: '3' services: nginx: build: context: ./docker/nginx depends_on: - php ports: - 80:80 volumes: - ./src:/src php: container_name: laravel-app build: context: ./docker/phpfpm environment: DB_HOST: mysql volumes: - ./src:/src mysql: container_name: laravel-mysql restart: always image: mysql:5.7 volumes: - ./docker/mysql:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_USER=tsunagu - MYSQL_PASSWORD=password - MYSQL_DATABASE=tsunagu ports: - 3306:3306 ```
hope_mucci

2020/06/17 07:25

この場合、php<->nginx間のTCP通信はユーザーがwebサーバ(の*.php)にアクセスしたときにはじめて発生するので、php側のコンテナが先に作成されていないとマズイということはありません。 つまりこの場合でもdepends_onの記述は特に意味はありません。 >ビルドの順番が関係ない。ということでしょうか。 というわけではありません。質問本文のほうはphp側が先でないとまずいと思います(たぶん) php側のほうが先に書かれているからビルド順も先というだけで。 ただ、私も今気づいたのですがdocker-composeで個別にサービスを立ち上げるようなことがある場合、depends_onを記載しているとそのサービスを先に立ち上げるようになるようです。 詳しくは以下公式ドキュメントで。 http://docs.docker.jp/compose/compose-file.html#compose-file-depends-on
Kchan_01

2020/06/17 08:01

公式ドキュメントのリンクもありがとうございます。 > この場合、php<->nginx間のTCP通信はユーザーがwebサーバ(の*.php)にアクセスしたときにはじめて発生する そうなんですね。depends_onの記述にはいつも違和感があったので、すっきりしました。 確かに単体で存在できないものを依存関係なしに定義しているのは見方によっては危険かもしれないです。webアプリケーション全体というより、db周りとかでは、depends_onは役に立つ部分も考えられますね。 お付き合いいただき、ありがとうございます。
bsdfan

2020/06/17 11:24

nginxの場合、転送先のコンテナが先に起動していないとconfファイルでホスト名が解決できずに落ちる場合がありますので、depends_onは必要です。(それか動的に名前解決するようにするか)
Kchan_01

2020/06/18 01:56 編集

@bsdfan さん ご回答ありがとうございます。 今回、default.confファイルで location ~ .php$ { fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } として、UNIXドメインソケットでつなぐように定義しているので回避措置しなくてよい。 docker-laravel/default.conf at master · ucan-lab/docker-laravel https://github.com/ucan-lab/docker-laravel/blob/master/infrastructure/docker/nginx/default.conf 以下のファイルのようにfastcgi_pass php:9000;と指定している場合は、一度、サーバ間で通信が行われ、それが失敗すると落ちる可能性があるので、depends_onは必要。ってことですか? [tsunagu/default.conf at master · yoshikawa/tsunagu](https://github.com/yoshikawa/tsunagu/blob/master/docker/nginx/etc/nginx/conf.d/default.conf) > php<->nginx間のTCP通信はユーザーがwebサーバ(の*.php)にアクセスしたときにはじめて発生する というのは間違いで、設定によっては(むしろ、設定しないと)、コンテナ起動時にサーバー通信が起きる。という理解で良いでしょうか。
bsdfan

2020/06/18 02:21

TCPの場合、confファイルを読む段階で、転送先のホスト名をIPアドレスに解決できずにhost not foundでエラーになります。(通信が発生する以前の問題です) docker-composeでは、サービス名をホスト名として指定できますが、コンテナが起動していないとDNSで名前がひけません。 (UNIXソケットの場合も、ソケットファイルがないとエラーになりそうですが、そのあたり自信ないです。)
hope_mucci

2020/06/18 04:52

bsdfanさんのコメント通り、php側コンテナ作成前の段階でnginxを起動したとき、conf読み込み時に名前解決が発生してエラーとなることを確認しました。(depends_onを逆にして検証) nginxとphpでコンテナ作成順やdepends_onをいろいろ変更して起動実験をしてみた結果、depends_onをつけずに同時にコンテナを作成すると名前解決エラーは発生しませんでした。DNS参照時までにphp側コンテナ作成開始していれば良いようです。 万全を期すならdepends_on指定しておいたほうが良いと考えます。が、そこまで神経質にならなくてもいいのかも。
hope_mucci

2020/06/18 05:27

UNIXソケット利用ケース(質問本文のケース)で、webとappの依存関係を逆(app側にdepends_on: -web)にしたりwebだけ単体で起動してみましたが、特にエラーは発生しませんでした。.sockファイルは起動時になくても良いようです。
guest

0

webはappに依存関係があると思うのですが

アプリケーションとして依存関係はないので個別に起動できます。

機能が動作するときには依存関係(連携)が必要です
webがphpを処理するときにはphp-fpmが動いていなければならない。
phpがDBを参照するときはmysqlが動いていなければならない。

投稿2020/06/17 04:30

yukky1201

総合スコア2751

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問