環境
Rails 6.0.3
Nginx 1.17.9
Next.js 9.4.4
docker 19.03.8
やりたいこと
バックエンド、フロントエンドをそれぞれ別なdocker-composeで立ち上げて、フロントエンドからバックエンドのapi http://localhost/api/v1/prefs
(都道府県API)を叩く。
解決したこと
- 異なるdocker-compose間の
localhost
による通信 - rails6での
host
の追加
1. 異なるdocker-compose間のlocalhost
による通信
バックエンド・フロントエンドのアプリケーションをそれぞれ立ち上げて、フロント側から簡易的にapiにアクセスしようとした。
import Link from 'next/link'
import Layout from '../components/Layout'
import 'isomorphic-fetch';
function IndexPage({ results }: {results: any}){
return (
<Layout title="Home | Next.js + TypeScript Example">
<h1>Hello Next.js 👋</h1>
{results[0].pref}
<p>
<Link href="/about">
<a>About</a>
</Link>
</p>
</Layout>
)
}
IndexPage.getInitialProps = async ({ req }: {req: any}) => {
const res = await fetch('http://localhost/api/v1/prefs');
const data = await res.json();
return {
results: data,
};
}
export default IndexPage
apiサーバまでリクエストが届いていないようで、そちらにはログが出ない。
そもそもdocker-composeで立ち上げたアプリケーションはそれぞれが別のネットワークになっているので、localhost
にはapiサーバが存在していない。
こちら1を参考に、フロント側のdocker-composeを編集した。
version: '3'
services:
react-next:
build:
context: ./
dockerfile: ./Dockerfile
container_name: react-next
tty: true
volumes:
- ./app:/app
ports:
- '8080:8080'
command: sh -c "yarn run dev"
# 以下追記
networks:
- バックエンドのネットワーク名
networks:
バックエンドのネットワーク名:
external: true
バックエンドのネットワーク名はdocker network ls
で調べることができる。
NAMEを記載しておく。
過去のたくさんアプリケーションを立ち上げていると、その分のネットワーク名がすべて出るので、該当のものを探す。
記載したらフロントエンドのコンテナに入ってみる。
今回はシェルとしてzsh
を入れているので、フロントエンドのコンテナ(コンテナ名:react-next
)に入るコマンドは
docker-compose run --rm react-next /bin/zsh
コンテナに入ったらフロントエンドのserver
コンテナにアクセスしてみる。
ping -c4 server
通信はできるようになった。
しかし、エラーは変わらず。
2. rails6でのhost
の追加
通信はできるようになったのに、なぜリクエストは通らないのか。
こちら2を参考に、index.tsxを書き換えた。
import Link from 'next/link'
import Layout from '../components/Layout'
import 'isomorphic-fetch';
function IndexPage({ results }: {results: any}){
return (
<Layout title="Home | Next.js + TypeScript Example">
<h1>Hello Next.js 👋</h1>
{results[0].pref}
<p>
<Link href="/about">
<a>About</a>
</Link>
</p>
</Layout>
)
}
IndexPage.getInitialProps = async ({ req }: {req: any}) => {
// 以下変更
const res = await fetch('http://server/api/v1/prefs');
const data = await res.json();
return {
results: data,
};
}
export default IndexPage
しかし、変わらず。
なぜなのか。
コンテナに入って、やけくそでcurl http://server/api/v1/prefs
を実行した際に気になる結果が。
server
ホストがブロックされた、とある。
エラーメッセージで検索をしたところ、こちら3を見つけた。
このページ通りにバックエンドのrailsサーバの設定を書き換える。
Rails.application.configure do
# 略
# 追記
config.hosts << "server"
# 略
end
変更したらrailsサーバを再起動。
もう一度curl
コマンド叩いてみる。
お!
ブラウザに急ぐ。
そこには燦然と輝く『北海道』の文字。
無事にapiから都道府県のデータ取得ができました。