【Rails】Cannot render console from <IPアドレス>! の対処法【Docker】

## はじめに
　本記事は、プログラミング初学者が学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## `Cannot render console from <IPアドレス>!` の対処法
### 状況
DockerのRails環境で開発をしていたところ、以下のようにログに`Cannot render console from 172.19.0.1! Allowed networks: 127.0.0.0/127.255.255.255, ::1`と出力されました。

```:ターミナル
Started GET "/food_enquetes/new" for 172.19.0.1 at 2022-04-02 11:12:06 +0900
Cannot render console from 172.19.0.1! Allowed networks: 127.0.0.0/127.255.255.255, ::1
  ActiveRecord::SchemaMigration Pluck (20.8ms)  SELECT `schema_migrations`.`version` FROM `schema_migrations` ORDER BY `schema_migrations`.`version` ASC
Processing by FoodEnquetesController#new as HTML
  Rendering layout layouts/application.html.erb
  Rendering food_enquetes/new.html.erb within layouts/application
  Rendered concerns/_form_name_mail_age.html.erb (Duration: 12.3ms | Allocations: 1721)
  Rendered concerns/_form_score_request.html.erb (Duration: 1.7ms | Allocations: 471)
  Rendered food_enquetes/_form.html.erb (Duration: 24.0ms | Allocations: 4864)
  Rendered food_enquetes/new.html.erb within layouts/application (Duration: 34.6ms | Allocations: 16057)
  Rendered layout layouts/application.html.erb (Duration: 368.4ms | Allocations: 49799)
Completed 200 OK in 468ms (Views: 377.3ms | ActiveRecord: 23.4ms | Allocations: 62150)
```

### 対処法
`config/environments/development.rb`に`config.web_console.allowed_ips = '0.0.0.0/0'`を追記することで解消しました。
```config/environments/development.rb
Rails.application.configure do
 :
  config.web_console.allowed_ips = '0.0.0.0/0'
 :
end
```

```:ターミナル
tarted POST "/food_enquetes" for 172.20.0.1 at 2022-04-02 11:31:45 +0900
Processing by FoodEnquetesController#create as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]", "food_enquete"=>{"name"=>"", "mail"=>"", "age"=>"", "food_id"=>"0", "request"=>"", "present_id"=>"0"}, "commit"=>"登録する"}
  TRANSACTION (0.7ms)  BEGIN
  ↳ app/controllers/food_enquetes_controller.rb:25:in `create'
  FoodEnquete Exists? (6.0ms)  SELECT 1 AS one FROM `food_enquetes` WHERE `food_enquetes`.`mail` = '' LIMIT 1
  ↳ app/controllers/food_enquetes_controller.rb:25:in `create'
  TRANSACTION (0.8ms)  ROLLBACK
  ↳ app/controllers/food_enquetes_controller.rb:25:in `create'
  Rendering layout layouts/application.html.erb
  Rendering food_enquetes/new.html.erb within layouts/application
  Rendered concerns/_form_name_mail_age.html.erb (Duration: 3.0ms | Allocations: 3484)
  Rendered concerns/_form_score_request.html.erb (Duration: 0.2ms | Allocations: 235)
  Rendered food_enquetes/_form.html.erb (Duration: 8.9ms | Allocations: 8013)
  Rendered food_enquetes/new.html.erb within layouts/application (Duration: 9.7ms | Allocations: 8197)
  Rendered layout layouts/application.html.erb (Duration: 28.7ms | Allocations: 10308)
Completed 422 Unprocessable Entity in 50ms (Views: 30.0ms | ActiveRecord: 7.6ms | Allocations: 16462)
```


### `config.web_console.whitelisted_ips`は非推奨
`config.web_console.whitelisted_ips`という記述を追記すると記載されている記事がありましたが、`config.web_console.whitelisted_ips`は非推奨になったようで、こちらを使用すると以下のように代わりに`config.web_console.allowed_ips`を使用するよう促すメッセージが出力されます。

```:ターミナル
DEPRECATION WARNING: The config.web_console.whitelisted_ips is deprecated and will be ignored in future release of web_console. 
Please use config.web_console.allowed_ips instead. (called from <top (required)> at /myapp/config/environment.rb:5)
```

###  `'0.0.0.0/0'`の部分に具体的なIPアドレスを指定する
`config.web_console.allowed_ips = '0.0.0.0/0'`の`'0.0.0.0/0'`の部分に`'172.22.0.1'`等の具体的なIPアドレスを指定しても`docker compose down`→`docker compose up`をするたびにIPアドレスが変更されるので`Cannot render console from <IPアドレス>!`が出力され続けます。

IPアドレスが変更されることは以下のようにして確認することができます。

```:ターミナル
$ docker compose up -d

$ docker network ls
NETWORK ID     NAME                    DRIVER    SCOPE
eggoreaijgea   bridge                  bridge    local
ecgahgrojaa9   host                    host      local
1gagjaerigje   none                    null      local
7fhauhffefea   <アプリ名>_default        bridge    local

$ docker network inspect <アプリ名>_default 
[
    {
        "Name": "<アプリ名>_default",
        "Id": "gaogjraoijfeoiajreghefjajgweoiq3483o34qjfjaofjfoeqjfiowjefoqejg",
        "Created": "2022-04-02T12:22:48.326832678Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.20.0.0/16",
                    "Gateway": "172.20.0.1"
                }
            ]
        },

    <以下略>

$ docker compose down

$ docker compose up -d

$ docker network inspect <アプリ名>_default 
[
    {
        "Name": "<アプリ名>_default",
        "Id": "geajgioajfoiejagoerwhjgerijgoagoiejrgoiejraoijfer349jfaohuhtfty",
        "Created": "2022-04-02T12:29:27.940566709Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.21.0.0/16",
                    "Gateway": "172.21.0.1"
                }
            ]
        },

    <以下略>

```

`"Subnet": "172.20.0.0/16",`
`"Gateway": "172.20.0.1"`
が
`"Subnet": "172.21.0.0/16",`
`"Gateway": "172.21.0.1"`
に変わっています。

`Cannot render console from <IPアドレス>!`の`<IPアドレス>`の部分は`"Gateway"`のIPアドレスです。
そのため、`"Gateway"`のIPアドレスを`config.web_console.allowed_ips = '0.0.0.0/0'`の`'0.0.0.0/0'`の部分に指定する必要があるのですが、上記のようにIPアドレスが変更されるため、具体的なIPアドレスを指定すると`Cannot render console from <IPアドレス>!`が出力され続けてしまうということです。

具体的なIPアドレスを指定したい場合には、docker-compose.ymlを以下のように修正し、subnetを指定する必要があります。

```docker-compose.yml
version: '${COMPOSE_VER}'
# 以下追記=============================
networks:
  my_network: #　任意のネットワーク名を記述
    ipam:
      driver: default
      config:
        - subnet: 172.22.0.0/16 # subnetの指定
        # gatewayの指定は version3 以降ではできないようです。
# 追記ここまで=============================   
services:
  db:
    platform: linux/x86_64
    build: ./docker/db
    command: --default-authentication-plugin=mysql_native_password && bash -c "chmod +x /docker-entrypoint-initdb.d/00_grant.sh"
    healthcheck:
      test: mysqladmin ping -h db -u$${MYSQL_USER} -p$${MYSQL_PASSWORD}
      interval: 1s
    restart: on-failure
    volumes:
      - mysql_data:/var/lib/mysql
      - type: bind
        source: ${MY_CNF_PATH}
        target: /etc/mysql/conf.d/my.cnf
      - type: bind
        source: ${INITDB_PATH}
        target: /docker-entrypoint-initdb.d
    env_file:
      - ${DB_ENV_FILE_PATH}
    ports:
      - "${DB_PORT}:3306"
# 以下追記=============================
    networks:
      my_network:
# 追記ここまで===========================
  api:
    build:
      context: .
      dockerfile: ./docker/api/Dockerfile
    command: bash -c "mkdir -p ./tmp/sockets && bundle exec puma -C config/puma.rb"
    restart: on-failure
    volumes:
      - .:/myapp
      - public-data:/myapp/public
      - tmp-data:/myapp/tmp
    environment:
      RAILS_ENV: ${APP_ENV}
    ports:
      - "${API_PORT}:3000"
    depends_on:
      db:
        condition: service_healthy
# 以下追記=============================
    networks:
      my_network:
# 追記ここまで===========================
  web:
    build: ./docker/web
    volumes:
      - public-data:/myapp/public
      - tmp-data:/myapp/tmp
    ports:
      - 80:80
    depends_on:
      - api
# 以下追記=============================
    networks:
      my_network:
# 追記ここまで===========================
volumes:
  mysql_data:
  public-data:
    driver_opts:
      type: none
      device: ${PWD}/public
      o: bind
  tmp-data:
     driver_opts:
      type: none
      device: ${PWD}/tmp
      o: bind

```

上記のように変更してから`docker compose up -d`し直すと`<アプリ名>_<設定したネットワーク名>`という名前のネットワークが作成されます。

```:ターミナル
$ docker compose up -d

$ docker network ls
NETWORK ID     NAME                       DRIVER    SCOPE
fejaofiewjai   bridge                     bridge    local
fiajfoewjffa   host                       host      local
1giraejgioga   none                       null      local
75gajogiergg   <アプリ名>_my_network        bridge    local

$ docker network inspect <アプリ名>_my_network
[
    {
        "Name": "<アプリ名>_my_network",
        "Id": "75gajogierggagoejgeaoijewoaijgeajgeiojgaeoijegrojaegorjaeiogjriogj",
        "Created": "2022-04-02T12:42:56.00268272Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.22.0.0/16"
                }
            ]
        },

      <以下略>
```

`"Subnet": "172.22.0.0/16"`とdocker-compose.ymlで指定したものになっています。
IPアドレスが変更されないことを確認するために`docker compose down`して再度`docker compose up -d`します。

```:ターミナル
$ docker compose down

$ docker compose up -d

$ docker network inspect <アプリ名>_my_network
[
    {
        "Name": "<アプリ名>_my_network",
        "Id": "75gajogierggagoejgeaoijewoaijgeajgeiojgaeoijegrojaegorjaeiogjriogj",
        "Created": "2022-04-02T12:48:21.00268272Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.22.0.0/16"
                }
            ]
        },

      <以下略>
```

`"Subnet": "172.22.0.0/16"`と表示されており、変更されていないことが確認できました。

`config/environments/development.rb`に`config.web_console.allowed_ips`を追記します。
IPアドレスの部分には上記の例の場合には`172.22.0.1`を指定します。

```config/environments/development.rb
Rails.application.configure do
 :
  config.web_console.allowed_ips = '172.22.0.1'
 :
end
```

これで`Cannot render console from <IPアドレス>!`は出力されなくなりました。

```:ターミナル
Started POST "/food_enquetes" for 172.22.0.1 at 2022-04-02 12:53:27 +0900
Processing by FoodEnquetesController#create as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]", "food_enquete"=>{"name"=>"", "mail"=>"", "age"=>"", "food_id"=>"0", "request"=>"", "present_id"=>"0"}, "commit"=>"登録する"}
  TRANSACTION (1.2ms)  BEGIN
  ↳ app/controllers/food_enquetes_controller.rb:25:in `create'
  FoodEnquete Exists? (6.9ms)  SELECT 1 AS one FROM `food_enquetes` WHERE `food_enquetes`.`mail` = '' LIMIT 1
  ↳ app/controllers/food_enquetes_controller.rb:25:in `create'
  TRANSACTION (0.9ms)  ROLLBACK
  ↳ app/controllers/food_enquetes_controller.rb:25:in `create'
  Rendering layout layouts/application.html.erb
  Rendering food_enquetes/new.html.erb within layouts/application
  Rendered concerns/_form_name_mail_age.html.erb (Duration: 3.0ms | Allocations: 3484)
  Rendered concerns/_form_score_request.html.erb (Duration: 0.2ms | Allocations: 235)
  Rendered food_enquetes/_form.html.erb (Duration: 8.7ms | Allocations: 8014)
  Rendered food_enquetes/new.html.erb within layouts/application (Duration: 9.7ms | Allocations: 8198)
  Rendered layout layouts/application.html.erb (Duration: 29.0ms | Allocations: 10308)
Completed 422 Unprocessable Entity in 54ms (Views: 30.8ms | ActiveRecord: 8.9ms | Allocations: 16467)
```