Mac用にDnsmasqでローカル開発用のドメイン(*.test)を設定する
こんにちは、ナカエです。 本日はローカルの開発環境整備に関わる記事です。
/etc/hostsの設定が手間
複数のプロジェクトを進めている場合、ローカル開発環境では myapp.test や myapp.localなどの個別の開発用ドメインを割り当てて開発していることが多いと思います。 基本的にこの名前解決を/etc/hostsファイルで設定していたのですが、 Macの管理権限がない場合に自力で設定できないのが気になるようになってきました。
プロジェクトごとの開発用ドメインの名前解決の設定をなくし、環境構築を管理者の手を借りずに行いたいと思い、名前解決の設定方法を模索することにしました。 残念ながら、/etc/hostsではドメイン名にワイルドカードは使えないため、他の手段を用いることにします。
Dnsmasqを利用する
Dnsmasqは軽量なDNSのフォワーダとDHCPサーバの機能を提供するソフトウェアです。 小さいネットワーク向けのDNSとして利用する想定で開発されています。
DnsmasqはLaravelのMac用のミニマルな開発環境であるLaravel Valetでも利用されています。Valetの場合は*.testドメインを名前解決してローカルのnginxにリクエストが送られるようになっています。
設定手順
確認環境
- macOS Mojave 10.14.6
- Homebrew 2.2.1
*.testドメインをローカルループバックアドレスとして解決するように設定します。
# HomebrewでDnsmasqをインストール
brew install dnsmasq
# Dnsmasq設定
# *.testドメインをローカルループバックアドレスとして解決する
echo 'address=/.test/::1' >> $(brew --prefix)/etc/dnsmasq.conf
echo 'address=/.test/127.0.0.1' >> $(brew --prefix)/etc/dnsmasq.conf
# MacのDNS設定
# *.testドメインの名前解決をローカルのDnsmasqに任せる
sudo mkdir -v /etc/resolver
sudo bash -c 'echo "nameserver ::1" >> /etc/resolver/test'
sudo bash -c 'echo "nameserver 127.0.0.1" >> /etc/resolver/test'
# Dnsmasqの自動起動設定+起動
sudo brew services start dnsmasq
# 名前解決ができることを確認
ping test.test
ping6 test.test
設定自体にはsudoが必要ですが、一度設定してしまえば変更せずに一般ユーザの権限でも使えるはずです。
Dnsmasqの操作
# Dnsmasqの再起動(設定ファイルの再読込のために必要)
sudo brew services restart dnsmasq
# Dnsmasqを停止+自動起動無効化
sudo brew services stop dnsmasq
はまりポイント
権限不足でDnsmasqが起動していなかった
最初は、Dnsmasqの自動起動設定のコマンドをsudoなしで実行していました。
Homebrewの出力は
$ brew services start dnsmasq
==> Successfully started `dnsmasq` (label: homebrew.mxcl.dnsmasq)
と出るにも関わらず、実は裏で失敗していたのです。 エラーはMacの ユーティリティ -> コンソール を起動すれば確認可能です。
dnsmasq でプロセスを絞り込むと、
failed to create listening socket for 127.0.0.1 : Permission denied
などと出ています。どうやら通常のユーザで起動したため、53番ポートでリッスンするための権限がなかったようです。この場合は
brew services stop dnsmasq
として一度現在のユーザでの自動起動を無効化し、sudoをつけて起動し直す必要があります。
権限不足の他、53番ポートをすでに他のアプリケーションが利用している場合も同様に起動に失敗するため、注意が必要です。
.localだと動かない
弊社では開発用のドメインとして*.localを設定することがよくありました。このドメインはMacのBonjourがLAN内の機器の自動検出に利用しているため、上記のように設定してもアドレスが解決できません。Dnsmasqを使うなら避けたほうが無難でしょう。
/etc/hostsで.localのドメインを設定していた場合は、.testを利用するほうがお勧めです。