🤨
ローカル環境をHTTPSにする
動機
Sign in with Slackを使おうとしたが、独自ドメインかつSSL化されていないURLは許可されなかった。。。
例:
http://localhost:3000 => こいつだめ
https://example.com => こいつok
どうにかローカルでSlack認証を実現したいと試案した結果ローカル環境をssl x 独自ドメイン化することにした
やり方
今回は新たにリバースプロキシを建て、それを独自ドメイン化 & SSL化し、全ての通信をリバースプロキシを介すことで実現しようと思う。
最終的にリバースプロキシでこの様にリクエストを捌く
https://api.sampleApp.com => バックエンド
https://sampleApp.com => フロント
構成
- フロント(React): http://127.0.0.1:3001
- バックエンド(golang): http://127.0.0.1:8081
- リバースプロキシ(nginx): http://127.0.0.1:443
(格サーバーはdocker-composeによって独立していて、networksを共有している状態。)
事前準備事項
-
フロントエンドとバックエンドのサーバーを建てる(この記事ならバックエンド8081、フロントエンド3001)。
-
docker-composeでnetworksを共有
-
mkcertの準備
$ brew install mkcert # mkcertのインストール
$ mkcert -install # mkcertでローカルに認証局をインストール
- hostsの編集
127.0.0.1 api.sampleApp.com
127.0.0.1 sampleApp.com
リバースプロキシを立てる
- まずはポート80を開けて、通信が可能か確認
docker-compose.yaml
version: '3.8'
services:
rpx:
image: nginx:latest
container_name: コンテナ名
ports:
- 80:80
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
networks:
- 共有dockerネットワーク名
networks:
共有dockerネットワーク名:
external: true
nginx.conf
events {
worker_connections 16;
}
http {
server {
listen 80;
server_name sampleApp.com;
location / {
proxy_pass http://host.docker.internal:3001/;
proxy_redirect off;
}
}
server {
listen 80;
server_name api.sampleApp.com;
location / {
proxy_pass http://host.docker.internal:8081/;
proxy_redirect off;
}
}
}
下記に通信できればok
SSL化
- 証明書と秘密鍵を生成する
# 証明書と鍵を保管するディレクトリに移動
# 私の場合はリポジトリのルート直下にsslディレクトリを作成し、その中
$ cd ssl
$ mkcert sampleApp.com
$ mkcert api.sampleApp.com
$ ls -la
# 下のように生成されていたらok
# sampleApp.com.pem
# sampleApp.com-key.pem
# api.sampleApp.com.pem
# api.sampleApp.com-key.pem
docker-compose.yaml
- 443ポートを解放
- 先ほど生成した証明書と鍵をコンテナ内にマウントする
version: '3.8'
services:
rpx:
image: nginx:latest
container_name: コンテナ名
ports:
- 443:443
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl/api.sampleApp.com-key.pem:/etc/certs/api.sampleApp.com-key.pem
- ./ssl/api.sampleApp.com.pem:/etc/certs/api.sampleApp.com.pem
- ./ssl/sampleApp.com-key.pem:/etc/certs/sampleApp.com-key.pem
- ./ssl/sampleApp.com.pem:/etc/certs/sampleApp.com.pem
networks:
- 共有dockerネットワーク名
networks:
共有dockerネットワーク名:
external: true
nginx.conf
events {
worker_connections 16;
}
http {
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/certs/sampleApp.com.pem
ssl_certificate_key /etc/certs/sampleApp.com-key.pem;
location / {
proxy_pass http://host.docker.internal:3001/;
proxy_redirect off;
}
}
server {
listen 443 ssl;
server_name api.sampleApp.com;
ssl_certificate /etc/certs/api.sampleApp.com.pemm;
ssl_certificate_key /etc/certs/api.sampleApp.com-key.pem;
location / {
proxy_pass http://host.docker.internal:8081/;
proxy_redirect off;
}
}
}
下記に通信できる様になっていればok
まとめ
- mkcertを使うと簡単に実装できました。今回は個人の学習のためのアプローチでしたが、実際に実務でやる分にはどのように対応するのがベターなのか気になります。
Discussion
docker composeを利用しているなら以下の書き方でいけるっぽい
hostsファイルいじる必要なかった。。。