さよなら http://localhost、よろしく https://localhost
現在、株式会社TAIANで婚礼業界向けSaaSの開発に携わっています。プッシュ通知と名刺スキャン機能の検証にあたり、localhost でも HTTPS が必要になりました。
本記事では、その背景と、ローカル・CI 環境で HTTPS を構築する方法を整理します。
なぜ Localhost HTTPS が必要なのか?
1. モダン Web API の要求
現代の Web 開発では、ローカル開発環境で HTTPS を使うことが当たり前になりつつあります。
多くの最新 Web API やブラウザの機能は Secure Context(安全なコンテキスト) を必要とします。
- Service Worker:PWA 機能のコア
- Web Push API:プッシュ通知
- Geolocation API:位置情報
- Camera / Microphone API:カメラとマイク
- Web Authentication API:WebAuthn などの認証 API
これらは HTTPS でなければ動作しません。
2. サードパーティサービス統合
多くの外部サービスが HTTPS のコールバック URL を要求します:
- OAuth 2.0 のリダイレクト URL は HTTPS が必須
- Stripe、PayPal などの webhook が HTTPS を要求
- Google Maps、Mapbox など一部の機能で HTTPS が必要
ローカルでも HTTPS があると実際の運用と同じ挙動を検証できます。
3. 本番環境との一貫性
ローカルで HTTPS を使うことで:
- 混合コンテンツ(Mixed Content)の警告を事前に検出
- Cookie の
Secure属性や HSTS のテスト - SSL 設定の検証
など、本番で起こりうる HTTPS 関連の問題を早期発見できるようになります。
4. ブラウザのセキュリティポリシー
最新のブラウザは HTTP に対して制限を強めています:
- HTTP ページでは一部の API が制限される
- HTTPS ページ中の HTTP リソースはブロックされる
- 自動入力やその他機能が制限されることもある
そのため、HTTPS が前提の環境での開発が望まれます。
Localhost HTTPS の設定方法
利用可能な方法
ローカルで HTTPS を有効にするための一般的な手法:
- mkcert + nginx(推奨):ローカル CA で証明書を生成し、nginx をリバースプロキシとして利用
- 自署名証明書:簡単だが手動で信頼設定が必要
- Cloudflare Tunnel:外部アクセスが必要なケースに有用
ここでは mkcert + nginx の方法をメインで解説します。
手順
1. mkcert をインストールする
macOS
brew install mkcert
Linux(Ubuntu / Debian)
sudo apt install libnss3-tools
wget https://github.com/FiloSottile/mkcert/releases/latest/download/mkcert-v1.4.4-linux-amd64
chmod +x mkcert-v1.4.4-linux-amd64
sudo mv mkcert-v1.4.4-linux-amd64 /usr/local/bin/mkcert
これで mkcert を使えるようになります。
2. SSL 証明書を生成する
自動スクリプトを使う:
bash script/local_setup_https.sh
スクリプトは以下を実行します:
- mkcert のインストール確認
- ローカル CA をシステムに信頼済みとして登録
- 通配符証明書(
*.lvh.meなど)を生成 - 証明書を
~/.ssl/に保存
手動で生成する場合:
mkcert -install
cd ~/.ssl
mkcert -key-file _wildcard.lvh.me+3-key.pem \
-cert-file _wildcard.lvh.me+3.pem \
"*.lvh.me" "lvh.me" localhost 127.0.0.1 ::1
これでローカル HTTPS を扱うための証明書が用意できます。
3. nginx リバースプロキシを設定する
containers/nginx/nginx.conf を以下のように追加します:
upstream rails_app {
server unix:/app/tmp/sockets/puma.sock;
}
server {
listen 3001 ssl;
ssl_certificate /etc/ssl/certs/_wildcard.lvh.me+3.pem;
ssl_certificate_key /etc/ssl/private/_wildcard.lvh.me+3-key.pem;
server_name admin.lvh.me;
location / {
proxy_pass http://rails_app;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
基本的に nginx が HTTPS ターミネーションを行い、バックエンド(Rails など)と通信します。
4. Docker Compose に nginx を追加する
docker-compose.yml:
services:
proxy:
build: containers/nginx
ports:
- 3001:3001
volumes:
- app-tmp:/app/tmp
- ~/.ssl:/etc/ssl/certs:ro
- ~/.ssl:/etc/ssl/private:ro
depends_on:
- app
app:
volumes:
- app-tmp:/app/tmp
nginx コンテナを立ち上げることで HTTPS を経由したアクセスが可能になります。
5. アプリサーバ設定(例: Puma)
Rails アプリの場合:
# config/puma.rb
if Rails.env.development? || Rails.env.test?
bind "unix://#{Rails.root}/tmp/sockets/puma.sock"
else
bind "tcp://0.0.0.0:#{ENV.fetch('PORT', 3000)}"
end
Puma を UNIX ソケットで起動し nginx からプロキシする形にします。
6. hosts ファイルを設定する
以下を /etc/hosts に追加:
127.0.0.1 lvh.me
127.0.0.1 admin.lvh.me
127.0.0.1 tenantA.lvh.me
実際の HTTPS ドメイン名として lvh.me 系を利用できます。
7. サービスを起動する
docker compose build proxy
docker compose up
ブラウザで以下の URL を HTTPS で開けます:
https://admin.lvh.me:3001/adminhttps://tenantA.lvh.me:3001/crm
CI 環境での HTTPS
CI で HTTPS を使う方法も複数あります:
方法 1:自署名証明書を使う(E2E テスト向け)
GitHub Actions などでは自署名証明書を生成:
mkdir -p ~/.ssl
openssl req -x509 -newkey rsa:4096 \
-keyout ~/.ssl/key.pem \
-out ~/.ssl/cert.pem \
-days 365 -nodes \
-subj "/CN=*.lvh.me"
ブラウザのテストコードで証明書を信頼させる設定が必要になります。
方法 2:CI 上で mkcert を使う(推奨)
CI 上でも mkcert をインストールして証明書を生成できます:
wget https://github.com/FiloSottile/mkcert/releases/latest/download/mkcert-v1.4.4-linux-amd64
chmod +x mkcert-v1.4.4-linux-amd64
sudo mv mkcert-v1.4.4-linux-amd64 /usr/local/bin/mkcert
mkcert -install
mkdir -p ~/.ssl
cd ~/.ssl
mkcert -key-file _wildcard.lvh.me+3-key.pem \
-cert-file _wildcard.lvh.me+3.pem \
"*.lvh.me" "lvh.me" localhost
CI でもローカル HTTPS が動作できます。
方法 3:リアルなドメイン + 証明書(PR Preview 用)
PR Preview や外部アクセスが必要な場合、Let’s Encrypt の証明書や fly.io などを使って外部 HTTPS を構築します。
よくある問題と対処
1. 証明書が信頼されない
-
mkcert -installを実行したか確認 - 証明書ファイルのパスが正しいか確認
- ブラウザを再起動して信頼状態を更新
2. nginx が証明書を読み込めない
-
~/.ssl/に正しい証明書ファイルがあるか確認 -
docker-compose.ymlのボリュームマウント設定をチェック - nginx が読み取り可能な権限か確認
3. WebSocket 接続がうまく行かない
Nginx の WebSocket 設定が必要:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
などを追加します。
4. ポート衝突
3001 ポートが別プロセスで使われている場合:
- ポート番号を変更する
- 他のサービスを停止する
などで解決します。
まとめ
ローカルで HTTPS を使うことは、最新 Web API、外部サービス統合、本番環境との一致性、ブラウザのセキュリティ要件などの理由から推奨されます。mkcert + nginx の方法は簡単かつ実用的であり、開発効率と品質向上に役立ちます。
Discussion