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

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

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

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

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

Q&A

解決済

1回答

2664閲覧

二つのdocker-compose.yml同士でAPI通信を行いたい。

jun3030

総合スコア16

docker-compose

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

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

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

0グッド

0クリップ

投稿2020/09/04 15:37

前提・実現したいこと

docker-compose.ymlで立ち上げたアプリが二つあります。この二つのアプリ間でAPI通信を行いたいです。

###困っている事
それぞれのアプリをdocker-compose upで立ち上げlocalhost:3000localhost:4000でブラウザに表示出来るようになっています。そして片方のアプリで新規ユーザーを作成するとAPIを通してそのデータがもう一つのアプリで反映されるようになっています。

問題はユーザー作成時にjson parseエラーが出ることです。原因はdocker-composeで立ち上げたアプリ同士はネットワークが独立しており通信出来ないまではわかっているのですが、composeファイルの記述の仕方が分からない事です。

色々調べて試したのですが、どこがおかしいのか指摘して頂けないでしょうか?汗

お忙しい中申し訳ありません。。

###エラー内容

JSON::ParserError in StoreManagers::RegistrationsController#create

###詳しい情報

以下はディレクトリの構造です

root ┣ app1 ┃ ┝ docker-compose.yml ┃ ┗ Dockerfile ┃ ┣ app2 ┃ ┝ docker-compose.yml ┃ ┗ Dockerfile ┃ ┃

app1app2はどちらもコンテナの構成は同じで、一つのアプリにappdbwebとそれぞれの3つのコンテナから構成されています。

該当のソースコード

app1

1docker-compose.yml 2 3version: '3' 4services: 5 app: 6 build: 7 context: . 8 env_file: 9 - ./environments/db.env 10 command: bundle exec puma -C config/puma.rb 11 volumes: 12 - .:/new_reserve_app 13 - public-data:/new_reserve_app/public 14 - tmp-data:/new_reserve_app/tmp 15 - log-data:/new_reserve_app/log 16 depends_on: 17 - db 18 db: 19 image: mysql:5.7 20 environment: 21 MYSQL_ROOT_PASSWORD: password 22 MYSQL_DATABASE: root 23 volumes: 24 - db-data:/var/lib/mysql 25 web: 26 build: 27 context: containers/nginx 28 volumes: 29 - public-data:/new_reserve_app/public 30 - tmp-data:/new_reserve_app/tmp 31 ports: 32 - 3000:80 33 depends_on: 34 - app 35 tty: true 36 stdin_open: true 37 networks: 38 - smart_yoyaku_portal_site_default 39networks: 40 smart_yoyaku_portal_site_default: 41 external: true

app2

1docker-compose.yml 2 3version: '3' 4services: 5 app: 6 build: 7 context: . 8 env_file: 9 - ./environments/db.env 10 command: bundle exec puma -C config/puma.rb 11 volumes: 12 - .:/webapp 13 - public-data:/webapp/public 14 - tmp-data:/webapp/tmp 15 - log-data:/webapp/log 16 depends_on: 17 - db 18 db: 19 image: mysql:5.7 20 env_file: 21 - ./environments/db.env 22 volumes: 23 - db-data:/var/lib/mysql 24 web: 25 build: 26 context: containers/nginx 27 volumes: 28 - public-data:/webapp/public 29 - tmp-data:/webapp/tmp 30 ports: 31 - 4000:80 32 depends_on: 33 - app 34 tty: true 35 stdin_open: true 36 networks: 37 - new_reserve_app_default 38networks: 39 new_reserve_app_default: 40 external: true 41

Dockerfileは共通です

Dockerfile FROM ruby:2.6.5 # リポジトリを更新し依存モジュールをインストール RUN apt-get update -qq && \ apt-get install -y build-essential \ nodejs # yarnパッケージ管理ツールインストール RUN apt-get update && apt-get install -y curl apt-transport-https wget && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && apt-get install -y yarn # Node.jsをインストール RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - && \ apt-get install -y nodejs # ルート直下にwebappという名前で作業ディレクトリを作成(コンテナ内のアプリケーションディレクトリ) RUN mkdir /webapp WORKDIR /webapp # ホストのGemfileとGemfile.lockをコンテナにコピー ADD Gemfile /webapp/Gemfile ADD Gemfile.lock /webapp/Gemfile.lock # bundle installの実行 RUN gem install bundler:2.1.4 RUN bundle install # ホストのアプリケーションディレクトリ内をすべてコンテナにコピー ADD . /webapp # puma.sockを配置するディレクトリを作成 RUN mkdir -p tmp/sockets

試したこと

######その1
docker-compose upした時に自動で作成されるnetwork情報を確認しdocker network lsコマンドで確認し、docker-compose.ymlwebの欄にnetwork:として書き込んだ。
そもそもwebの欄に書き込むので合っているのか分からない。

NETWORK ID NAME DRIVER SCOPE 432ad7870bfb bridge bridge local 47b4c16713f8 host host local a8f34f823a4e new_reserve_app_default bridge local c027fb39190d none null local d834ad97970d smart_yoyaku_portal_site_default bridge local

######その2
共通のnetworkをdocker network createで作成。そのnetworkをそれぞれのdocker-compose.ymlに書き込み、pingコマンドで通信できているか確かめた。
pingで通信は出来ていたがjson parseエラーが返ってきた。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

それぞれの docker-compose.yml を確認すると、
別の既存の network に web サービスを接続する設定となっています:

yaml

1 web: 2# ---略--- 3 networks: 4 - smart_yoyaku_portal_site_default 5networks: 6 smart_yoyaku_portal_site_default: 7 external: true

yaml

1 web: 2# ---略--- 3 networks: 4 - new_reserve_app_default 5networks: 6 new_reserve_app_default: 7 external: true

参考: Use a pre-existing network | Networking in Compose | Docker Documentation

また、それぞれの appdbnetworks の設定がないため、
それぞれの docker-compose up 時に作成された default ネットワークに
サービスが接続した状態となります

アプリケーション|サービス|network
---|---
app1|app|app1_default
app1|db|app1_default
app1|web|smart_yoyaku_portal_site_default
app2|app|app2_default
app2|db|app2_default
app2|web|new_reserve_app_default

サービス同士の直接の接続は同じ network に属するサービス同士でしか接続ができません

参考: Specify custom networks | Networking in Compose | Docker Documentation

解決策

例えば、それぞれのディレクトリーに
結合テスト用の docker-compose.integration.yml を作成します
以下の例は、app1 を先に起動する場合です

app1 側:

yaml

1version: '3' 2services: 3 web: 4 networks: 5 default: 6 public: 7 aliases: 8 - api 9networks: 10 public:

app2 側:

yaml

1version: '3' 2services: 3 web: 4 networks: 5 default: 6 app1_public: 7 aliases: 8 - front 9networks: 10 app1_public: 11 external: true

そして、結合テストのためにサービスを起動するときは
どちらのアプリケーションでも次のコマンドを実行します:

console

1docker-compose -f docker-compose.yml -f docker-compose.integration.yml up

このようにすると、
それぞれのアプリケーションの web サービスだけは、
alias で定義した別名を使い、お互いの web サービスにアクセスができます:

アプリケーション|サービス|network
---|---
app1|app|app1_default
app1|db|app1_default
app1|web|app1_default, app1_public
app2|app|app2_default
app2|db|app2_default
app2|web|app2_default, app1_public

参考: Compose file version 3 reference | Docker Documentation

JSON::ParserError について

ping 等でネットワーク要因との切り分けを行った後、
次の方法のいずれかで詳細を確認すると良いかもしれません

  • stacktrace を確認
  • アプリケーションの API アクセス処理の前後にログを追加
  • API アクセスのためのライブラリーのログ出力レベルの変更
  • デバッグツールによる API レスポンスの確認

投稿2020/09/04 17:09

編集2020/09/06 12:24
y_shinoda

総合スコア3272

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

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

bsdfan

2020/09/05 22:49

同一のサービス名で、同じネットワークに入れても大丈夫でしょうか?
y_shinoda

2020/09/06 05:27

回答を修正しました コメントをいただいて調べてみたところ、 alias なしだと、同一サービス名では自分自身にアクセスしてしまうようで 要件を満たしていませんでした alias を使うことで、自分自身ではなく相手のサービスにアクセスできることを確認しました
jun3030

2020/09/06 12:18

回答ありがとうございます! 助言して頂いた通りに新たに docker-compose.intergration.ymlを作成しました。ディレクトリの構成としては現在このようになっています。 作成後、docker-compose -f docker-compose.yml -f docer-compose.intergration.yml up とコマンドを入力しましたが ERROR: .FileNotFoundError: [Errno 2] No such file or directory: './docer-compose.intergration.yml' とエラーが出ます。 ディレクトリの位置などが間違っているのでしょうか?汗 root ┣ app1 ┃ ┝ docker-compose.yml ┃ ┝ docker-compose.intergration.yml ┃ ┗ Dockerfile ┃ ┣ app2 ┃ ┝ docker-compose.yml ┃ ┝ docker-compose.intergration.yml ┃ ┗ Dockerfile ┃ ┃
y_shinoda

2020/09/06 12:27

失礼しました、typo していましたので回答を修正しました ×: docer-compose.intergration.yml ×: docker-compose.intergration.yml ◯: docker-compose.integration.yml 作成したファイル名とコマンドで指定しているファイル名が同一であることを確認お願いします
jun3030

2020/09/06 13:48

すみません。初歩的なミスをしていました汗 コマンドを訂正して打ち直したら無事に起動できました! その後2つのアプリを起動→コンテナに入る→pingコマンドでアクセスできるか確認しようとしたのですが、繋がっていないようでした。 よく確認するとdocker-compose.integration.ymlファイルのnetworkの指定先がそれぞれpublicとapp_publicで違うようなのですが、同じネットワーク名を書かなくておkなのでしょうか? 過去にdocker network createコマンドでネットワークを作成し、そのネットワーク名を各docker-composeファイルに書き込んだらpingで通信が通ったのですが、それではダメなのでしょうか? 質問沢山してしまい申し訳ありません汗
y_shinoda

2020/09/06 14:03

ping の際、"web" ではなく alias で指定している "api" または "front" で確認してみるといかがでしょうか? こちらの検証では到達が確認できました root@580291ddfd55:/# ping api PING api (192.168.192.2): 56 data bytes 64 bytes from 192.168.192.2: icmp_seq=0 ttl=64 time=0.155 ms ネットワークは Docker Compose で作成されると、 ネットワーク名にはディレクトリー名がプレフィックスとして追加されます もし app1 のディレクトリー名が実際は異なっている場合は app2 の方のネットワーク名のプレフィックスを実際のディレクトリー名に合わせてください 先に docker コマンドでネットワークを作る方法でも うまくやればおそらく実現可能と思われます なるべく Docker Compose を使った方が管理が煩雑にならないだろうということで できる限り Docker Compose を利用して回答しました
jun3030

2020/09/10 06:27

お忙しい中回答ありがとうございました! あれからdocker-composeでnetworkを設定する方法を試したのですが、うまくいかずコマンドでとりあえずnetworkを作成しpingコマンドで確認しました。 お忙しい中回答してくださりありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問