nginxとDockerでローカル環境のWebアプリとHTTPS通信をする

インフラ

前回、独自ドメインとローカルのWebアプリをつなげるプロキシサーバをnginxとDcokerで構築するでローカル環境用のプロキシサーバをnginxとDockerで構築する方法について紹介しました。

今回は前回の記事で紹介したnginxをSSL(HTTPS通信)に対応させる手順について紹介します。
https://web.local.example-dev.comでローカル環境に構築したWebアプリケーションへ接続することが今回の記事のゴールです。

なお、nginxのDocker環境はすでに構築されている前提で説明をします。

下準備

ローカル環境の/etc/hostsを編集する

localhost127.0.0.1を指すホスト名です。
任意のドメインでローカル環境を参照するには/etc/hosts127.0.0.1にドメインをマッピングします。

# 以下を追加する
127.0.0.1   web.local.example-dev.com

SSL化に必要な証明書と秘密鍵の作成

SSL化するには証明書と秘密鍵が必要です。
今回はmkcertを利用してローカル環境用の証明書と秘密鍵を作成します。

mkcertの詳細解説はローカル環境のSSL対応(HTTPS通信)をmkcertで実現するで紹介しています。

### docker-composeのディレクトリへ移動
$ cd path/to/docker-compose

### 証明書と秘密鍵を生成するディレクトリの作成と移動
$ mkdir certs && cd $_

### 証明書と秘密鍵をmkcertで作成
$ mkcert -cert-file localhost.pem -key-file localhost-key.pem web.local.example-dev.com

Created a new certificate valid for the following names 📜
 - "web.local.example-dev.com"

The certificate is at "localhost.pem" and the key at "localhost-key.pem" ✅

It will expire on 15 May 2024 🗓

nginxの設定ファイルを変更

HTTPS通信を行えるようにするためには以下の設定が必要です。

  • 443番ポートでリクエストを受け付ける
  • SSLの有効化
  • 証明書の配置
  • 秘密鍵の配置

具体的なnginxの設定ファイルは以下の通りです。

default.conf

server {
  ### SSLを有効にして443番ポートでlistenする
  listen 443 ssl;

  ### web.local.example-dev.comのリクエストを受け取る
  server_name  web.local.example-dev.com;

  ### 証明書の設定
  ssl_certificate /etc/ssl/certs/localhost.pem;

  ### 秘密鍵の設定
  ssl_certificate_key /etc/ssl/certs/localhost-key.pem;

  location / {
    ### リクエストヘッダに$hostをセット
    # $host: Hostリクエストヘッダがあればそのサーバ名、なければプライマリサーバ名(server_name)
    proxy_set_header Host $host;

    ### ローカル環境(host.docker.internal)の3001番ポートへプロキシする
    proxy_pass http://host.docker.internal:3001;
  }
}

参考: sslディレクティブの廃止について

nginxのSSL化はlisten 443ssl on;と2行にわたって記述されていましたが、nginx 1.15.0でのsslディレクティブの廃止に伴い1listen 443 ssl;に変更されています。

[warn] the "ssl" directive is deprecated, use the "listen ... ssl" directive insteadというエラーが発生した場合はlisten 443 ssl;の記述を利用してください。

docker-compose.ymlの修正

証明書を作成したローカル環境のディレクトリをバインドマウントさせることで、ローカル環境の証明書と秘密鍵をDocker環境で利用できるようにします。
また、443番ポートで通信できるようにするためポートフォワーディングの設定を追加します。

docker-compose.yml

version: '3'
services:
  nginx:
    image: nginx:1.21
    ports:
      - '80:80'
+     - '443:443'
    command: [nginx-debug, '-g', 'daemon off;']
    volumes:
      - ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
+     - ./certs:/etc/ssl/certs

動作確認

Webアプリケーションとnginxを起動後、https://web.local.example-dev.com/で接続できればOKです。curlの結果は以下の通りです。

### 『200 OK』のレスポンスが返ってくればOK
$ curl -I https://web.local.example-dev.com/

HTTP/1.1 200 OK
Server: nginx/1.21.6
Date: Tue, 15 Feb 2022 00:46:51 GMT
(略)

さいごに

Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!