PeeeeRONの日記

更新頻度はあまり高くはありませんがネタがあったら書いていこうと思います。

docker-composeでLet's Encrypt SSL,HTTP2通信対応Nginxリバースプロキシサーバを構築する

お久しぶりです。

最近CoreOSのサーバを構築しました。WebサーバとしてNginxを動かしたのですが、docker-composeを使った方法がすごく簡単にLet's Encryptを使ったSSL対応のNginxを動かせたので皆さんにも使っていただきたく記事にしました。

Let's Encryptは無料のSSL証明書で簡単にサーバをSSL対応できますが、証明書の更新をcronに登録したり、ドメインごとに設定しなければならず少し面倒でした。しかし、Dockerを使えば自動的にこれらの作業を行わせることができます。Nginxの設定を自らいじる必要もありませんでした。

それでは、手順を紹介したいと思います。

リポジトリのクローン

まずこちらオープンソースをクローンします。

git clone https://github.com/evertramos/docker-compose-letsencrypt-nginx-proxy-companion.git

以下のdocker-compose.ymlが今回利用するものです。

version: '3'
services:
  nginx:
    image: nginx
    labels:
        com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true"
    container_name: nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ${NGINX_FILES_PATH}/conf.d:/etc/nginx/conf.d
      - ${NGINX_FILES_PATH}/vhost.d:/etc/nginx/vhost.d
      - ${NGINX_FILES_PATH}/html:/usr/share/nginx/html
      - ${NGINX_FILES_PATH}/certs:/etc/nginx/certs:ro

  nginx-gen:
    image: jwilder/docker-gen
    command: -notify-sighup nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
    container_name: nginx-gen
    restart: unless-stopped
    volumes:
      - ${NGINX_FILES_PATH}/conf.d:/etc/nginx/conf.d
      - ${NGINX_FILES_PATH}/vhost.d:/etc/nginx/vhost.d
      - ${NGINX_FILES_PATH}/html:/usr/share/nginx/html
      - ${NGINX_FILES_PATH}/certs:/etc/nginx/certs:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro

  nginx-letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: nginx-letsencrypt
    restart: unless-stopped
    volumes:
      - ${NGINX_FILES_PATH}/conf.d:/etc/nginx/conf.d
      - ${NGINX_FILES_PATH}/vhost.d:/etc/nginx/vhost.d
      - ${NGINX_FILES_PATH}/html:/usr/share/nginx/html
      - ${NGINX_FILES_PATH}/certs:/etc/nginx/certs:rw
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      NGINX_DOCKER_GEN_CONTAINER: "nginx-gen"
      NGINX_PROXY_CONTAINER: "nginx"

networks:
  default:
    external:
      name: webproxy

必要であれば、編集してください。
自分は使っているdocker-composeがバージョン3に対応していなかったので、version: "2"にして、CoreOSは自動アップデートのときに再起動を行うので、restart: unless-stoppedrestart: alwaysに変更しました。

Dockerネットワークの作成

次にnetworkを作成します。

docker network create webproxy

設定ファイルの用意

.envファイルを用意する。 docker-compose.ymlと同じディレクトリに以下の内容の.envファイルを用意します。

NGINX_FILES_PATH=/path/to/your/nginx/data

これはdocker-compose.ymlの環境変数を設定するためです。このパスにはnginxの設定ファイル等が保存されます。

コンテナ起動

コンテナの起動 コマンドを入力してコンテナを起動しましょう。

docker-compose up -d

これでLet's EncryptによるSSL対応のNginxリバースプロキシサーバの起動できました。このコンテナでは証明書の自動更新なども行ってくれるので自分で設定する必要はありません。

ブラウザでサーバにアクセスするとNginxの503エラーページが表示されるはずです。

アプリケーションサーバの用意

次に動かしたいWebアプリのサーバを作成します。 こちらもdocker-composeで動かすようにします。Dockerfileはご自分で作成してください。注意点としては80番と443番のポートをEXPOSEしてください。あとAPPサーバは80番、または443番をListenするようにしてください。

EXPOSE 80 443

そして起動するためのdocker-composeファイルを作成します。例えば以下のように作成します。アプリに応じてDBサーバの設定などを書いてもいいです。

version: "2"
services:
  app:
    build: .
    command: /app
    environment:
      - VIRTUAL_HOST=example.com
      - LETSENCRYPT_HOST=example.com
      - LETSENCRYPT_EMAIL=example@example.com
    restart: always

networks:
  default:
    external:
      name: webproxy

必ず設定しなければならないのは、環境変数VIRTUAL_HOST,LETSENCRYPT_HOST,LETSENCRYPT_EMAILと、Docker ネットワークの設定だけです。

アプリケーションサーバの起動

docker-compose up -d

アプリケーションサーバを起動すると、自動的に先程起動したNginxコンテナが起動を検知しLet's Encryptの証明書を取得し、Nginxの設定ファイルを生成します。これは先程設定したNginxの設定ファイルのディレクトリを見ればわかります。

しばらくまって、ブラウザでドメインにアクセスするとSSL通信できるようになっています。

まとめ

以上でNginxのSSL対応リバースプロキシサーバとアプリケーションサーバが構築できました。また別のサービスを立ち上げた時は、docker-composeファイルを作れば、リバースプロキシやSSLの設定は自動的に行なってくれるのでとても簡単です。是非使ってみてください。

追記

ちなみに通信はHTTP2になるようです。