Help us understand the problem. What is going on with this article?

ngx_mrubyを使って最初のHTTPSアクセス時に自動で証明書を設定可能にするnginx-fastcertificateのdockerコンテナを作った

More than 3 years have passed since last update.

matsumoto-rさんのngx_mrubyで最初のHTTPSアクセス時に自動で証明書を設定可能にするFastCertificateの提案とPoCを参考に、Let's EncryptからSSL証明書を自動取得する仕組みを内包した nginx-fastcertificate を実現するDockerコンテナとdocker-compose設定例を作ってみました。

全体像

image

使い方

以下のような yaml ファイルを用意します。

docker-compose.yml
version: '3'
services:
  nginx:
    image: quay.io/akiray03/nginx-fastcertificate
    ports:
      - '80:80'
      - '443:443'
    volumes:
      - ./logs:/usr/local/nginx/logs
    links:
      - redis:redis
    environment:
      NGINX_WORKER_PROCESSES: 2
      REDIS_HOST: "redis"
      RESOLVER_ADDRESS: 8.8.8.8

      # ホストのプライベートIPアドレスを指定する or CLOUD_PROVIDER を指定する
      CLOUD_PROVIDER: Amazon # or Google
      # INTERNAL_IP: 192.168.0.10

      # このサーバで終端するドメイン名を半角スペース区切りで指定
      SSL_DOMAINS: "test.example.com test2.example.com"

      # ドメインごとに接続先情報を記述します (test.example.com の接続先)
      test_example_com_PROXY_TO_HOST: INTERNAL_IP
      test_example_com_PROXY_TO_PORT: '3000'
      # test2.example.com のリバースプロキシ接続先
      test2_example_com_PROXY_TO_URL: "https://test2.original.example.com/"
    depends_on:
      - redis

  redis:
    image: redis:3.2-alpine
    expose:
      - '6379'

そして、以下のコマンドを実行することで、SSL証明書の自動取得が行われるnginxが起動します。

$ docker-compose up

環境変数の説明

項目 説明
SSL_DOMAINS サーバで終端するドメイン名を半角スペース区切りで指定します
test_example_com_PROXY_TO_HOST リバースプロキシ接続先のIPアドレスを指定します
test_example_com_PROXY_TO_PORT リバースプロキシ接続先のポートを指定します
test_exmaple_com_PROXY_TO_URL リバースプロキシ接続先のURLを指定します
CLOUD_PROVIDER クラウドベンダー名を指定します。 Amazon または Google をサポートします
INTERNAL_IP Dockerコンテナが動作するホストのプライベートIPアドレスを指定する

解説

INTERNAL_IPCLOUD_PROVIDER について

  • リバースプロキシ先が nginx-certificate コンテナが動作する docker-compose にリンクされている場合は、 INTERNAL_IP=127.0.0.1 と指定することでリバースプロキシが実現できます
  • リバースプロキシ先が docker-compose 外で動作している場合、ホストのプライベートIPを指定する必要があります
  • AmazonまたはGoogleのクラウドを利用している場合 CLOUD_PROVIDER=Amazon のように指定することで、メタデータAPI経由でIPアドレスを解決することができます

リバースプロキシ先をURLで指定したい場合 (固定IPアドレスではなく、ドメインの場合)

  • リバースプロキシ先が固定IPの場合には、 <domain_name>_PROXY_TO_URL 設定値を利用します
  • nginxのupstreamコンテキストを利用する方法によって、有償オプションを利用することなく、動的な名前解決を実現しています。

証明書の取得と有効期間

  • 冒頭にも書きましたが、SSL証明書はLet's Encryptから自動取得を行います
  • 最初のアクセス時にSSL証明書の発行とRedisへの永続化を行っていますので、数秒〜十数秒の時間がかかります。一方で2回目以降のアクセス時にはRedisから証明書を取得するので応答までの時間は(通常のWebサイトであれば)気にならないレベルになるでしょう
$ time curl https://b.test.yumiyama.com -o /dev/null

real    0m7.602s
user    0m0.020s
sys     0m0.000s
$ time curl https://b.test.yumiyama.com -o /dev/null

real    0m0.068s
user    0m0.012s
sys     0m0.004s
akiray03
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away