rails6 + nginx のapiに別なdocker-composeのNext.jsフロントエンドからアクセスしたい

# 環境

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にアクセスしようとした。

```tsx:pages/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://localhost/api/v1/prefs');
  const data = await res.json();
  return {
    results: data,
  };
}

export default IndexPage
```

エラった。
<img width="982" alt="スクリーンショット 2020-06-02 11.21.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131949/518d072e-5693-9dfe-41f4-18e79501ffb7.png">

apiサーバまでリクエストが届いていないようで、そちらにはログが出ない。
そもそもdocker-composeで立ち上げたアプリケーションはそれぞれが別のネットワークになっているので、`localhost`にはapiサーバが存在していない。

こちら[^1]を参考に、フロント側のdocker-composeを編集した。

```yml:docker-compose.yml
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`で調べることができる。
<img width="559" alt="スクリーンショット 2020-06-02 11.40.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131949/eb36075a-2e75-d9ab-a8f4-68af24e31038.png">
NAMEを記載しておく。
過去のたくさんアプリケーションを立ち上げていると、その分のネットワーク名がすべて出るので、該当のものを探す。

記載したらフロントエンドのコンテナに入ってみる。
今回はシェルとして`zsh`を入れているので、フロントエンドのコンテナ（コンテナ名:`react-next`)に入るコマンドは
`docker-compose run --rm react-next /bin/zsh`

コンテナに入ったらフロントエンドの`server`コンテナにアクセスしてみる。
`ping -c4 server`

ちなみに、上記の変更前は`ping`コマンドを使ってもこの状態
<img width="291" alt="スクリーンショット 2020-06-02 12.20.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131949/5ff62b36-b012-584a-811d-55d95eec9f30.png">

変更後はこちら。
<img width="438" alt="スクリーンショット 2020-06-02 12.23.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131949/1245e336-ada9-f60b-3cc2-8aa9fcb4feed.png">

通信はできるようになった。
しかし、エラーは変わらず。

##2. rails6での`host`の追加

通信はできるようになったのに、なぜリクエストは通らないのか。

こちら[^2]を参考に、index.tsxを書き換えた。

```tsx:pages/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`を実行した際に気になる結果が。
<img width="704" alt="スクリーンショット 2020-06-02 12.29.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131949/5707bef9-e1bb-c940-0988-513f49cb6d2c.png">

`server`ホストがブロックされた、とある。
エラーメッセージで検索をしたところ、こちら[^3]を見つけた。

このページ通りにバックエンドのrailsサーバの設定を書き換える。

```rb:config/environments/development.rb
Rails.application.configure do
  # 略

  # 追記
  config.hosts << "server"

  # 略
end
```

変更したらrailsサーバを再起動。
もう一度`curl`コマンド叩いてみる。


<img width="704" alt="スクリーンショット 2020-06-02 12.46.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131949/e6207a6d-3236-8ab7-afe2-d3a3bb615718.png">

お！

ブラウザに急ぐ。

<img width="466" alt="スクリーンショット 2020-06-02 12.48.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131949/6b7fff36-b97e-7e6a-b887-be54b352beff.png">

そこには燦然と輝く『**北海道**』の文字。

無事にapiから都道府県のデータ取得ができました。


[^1]: [docker-compose で別の docker-compose.yml で作ったコンテナとリンクする (ネットワークを繋げる)](https://qiita.com/reneice/items/20e981062b093264cd0a)
[^2]: [【docker-compose】Nuxt.jsとGOでREST APIを構築した手順](https://qiita.com/arthur_foreign/items/3fcacb27464337730631)
[^3]: [Blocked host on Rails 6](https://www.fngtps.com/2019/rails6-blocked-host/)