「任意のドメインに接続したリクエストをローカル環境で起動しているWebアプリケーションへプロキシする」というnginxを、Docker環境に構築する方法について紹介します。
なお、http://localhost:3001
にアクセスするとWebアプリケーションへ接続できる前提で説明をします。
今回は例としてhttp://web.local.example-dev.com
でローカル環境のWebアプリケーションに接続することをゴールとします。
目次
下準備
ローカル環境の/etc/hostsを編集する
localhost
は127.0.0.1
を指すホスト名です。
任意のドメインでローカル環境を参照するには/etc/hosts
で127.0.0.1
にドメインをマッピングします。
# 以下を追加する
127.0.0.1 web.local.example-dev.com
WebアプリをRailsで実装している場合: ドメインによるアクセスをアプリケーション側で許可する
Rails 6以降1、DNSリバインディング攻撃からの保護のためデフォルトでは.localhost
、0.0.0.0
、::
からのアクセスのみ許可されています。
ですので、設定ファイルにconfig.hosts << "web.local.example-dev.com;"
やconfig.hosts.clear
を追加してweb.local.example-dev.com;
でコンテナにアクセスできるように設定する必要があります。
設定をしないと[ActionDispatch::HostAuthorization::DefaultResponseApp] Blocked host: web.local.example-dev.com;
というエラーが発生します。
詳細解説はlocalhost以外のホスト名でローカル環境のRailsに接続する方法で紹介しています。
docker-compose.ymlの作成
nginxコンテナを起動するdocker-compose.yml
を作成します。
docker-compose.yml
version: '3'
services:
nginx:
image: nginx:1.21
ports:
- '80:80'
command: [nginx-debug, '-g', 'daemon off;']
volumes:
- ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
volumes
で指定した設定ファイルについて補足説明をします。
nginxの設定ファイルは/etc/nginx/nginx.conf
です。設定ファイルにはinclude /etc/nginx/conf.d/*.conf;
という記述があり、/etc/nginx/conf.d/
配下の.conf
という拡張子の設定が読み込まれます。
今回はnginxの/etc/nginx/conf.d/
ディレクトリとローカルディレクトリをバインドマウントさせて設定ファイルを配置します。
nginxの設定ファイルの修正
nginxの設定ファイルは以下のようになります。
nginx/conf.d/default.conf
server {
listen 80;
### web.local.example-dev.comのリクエストを受け取る
server_name web.local.example-dev.com;
### "/"にアクセスがあったときの処理
location / {
### リクエストヘッダに$hostをセット
# $host: Hostリクエストヘッダがあればそのサーバ名、なければプライマリサーバ名(server_name)
proxy_set_header Host $host;
### ローカル環境(host.docker.internal)の3001番ポートへプロキシする
proxy_pass http://host.docker.internal:3001;
}
}
上記の設定ファイルではserver_name
ディレクティブを利用してserver
ブロックが処理するリクエストの対象をweb.local.example-dev.com
としています。そして、host.docker.internal
を利用してコンテナからローカル環境へリクエストをプロキシします。
host.docker.internal
はDocker Desktopで提供されている、コンテナからローカル環境を参照する際のホスト名です。
利用方法
Webアプリケーションと並行して今回作成したnginxコンテナをdocker-compose up
で起動させます。
一緒に起動することで、独自ドメインのリクエストがnginxを経由してWebアプリケーションに到達します。
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!