docker-compose、nginxプロキシでhttps対応する。

Nginxプロキシでhttps対応

docker-composeで何かしらのWEBアプリケーションを立ち上げた際、
nginxプロキシを挟むことで、https対応させる事ができます。

簡単なサンプルを用意しました。

証明書には、もちろん簡単に導入できる Let's Encrypt を使用します。
letsencrypt-nginx-proxy-companionというDockerイメージを使う事で自動発行してくれます。

GCEインスタンスを用意

GCPじゃなくてもいいんですが、ちょっとお試しするだけなら
GCEインスタンスをサクッと立ち上げた方が早いです。

  • asia-northeast1 (東京)
  • n1-standard-2 (2 vCPU, 7.5GBメモリ)
  • Ubuntu18.04 LTS
  • 標準の永続ディスク 10GB
  • HTTP トラフィックを許可する にチェック
  • HTTPS トラフィックを許可する にチェック
  • 管理 > プリエンプティブ オン (24時間以内に停止する)

これだけで、1 時間あたり約 $0.027 (3円くらい) なので、
一日立ち上げっぱでも100円いかないです。
土日だけ立ち上げてサーバー構築をちょっと試すような用途には充分かと。

※ディスクは、30GBまで無料ですが、
停止中のインスタンスでも30GB超えてるとディスク料だけはかかるのでご注意を
(Compute Engine > ディスク を確認しておこう)

今回はこんな設定で、Ubuntu 18.04 LTSにdockerとdocker-composeをインストールして試します。

Ubuntuにdocker, docker-composeをインストール

dockerとdocker-composeのインストールは、こちらの記事を参考に。
Ubuntu 18.04 LTS で、Docker使えるようにする

Webアプリケーションを用意

まず簡単な、WEBアプリケーションを用意。
今回は、Dockerイメージのnginxをそのまま起動しています。

docker-compose.yaml

version: '3'
services:
  web:
    image: nginx
    ports:
     - "8080:80"

docker-compose up -d すると、curl localhost:8080
起動したnginxサーバーのデフォルトページが表示されます。

$ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
~ (省略) ~
</html>

nginx-proxyと、letsencrypt-nginx-proxy-companionを追記

nginxプロキシと、証明書発行用のコンテナ、letsencrypt-nginx-proxy-companionを追記します。

あと、WEBアプリケーションの方にも、環境変数として以下を追加しましょう。

  • VIRTUAL_HOST
  • VIRTUAL_PORT (アプリケーション側のExposeポートが80なら省略可能)
  • LETSENCRYPT_HOST
  • LETSENCRYPT_EMAIL

この環境変数を、フックしてnginx-proxyと、letsencrypt-nginx-proxy-companionは
発行するべきドメイン名(※1)と、プロキシのバックエンドになるアプリケーションを判別しているようです。

docker-compose.yaml

version: '3'
services:
  web:
    image: nginx
    restart: always
    ports:
    - "8080:80" 
    environment:
      VIRTUAL_HOST: sample.com
      LETSENCRYPT_HOST:  sample.com
      LETSENCRYPT_EMAIL: sample@sample.com

  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    restart: always
    ports:
    - "80:80"
    - "443:443"
    volumes:
    - html:/usr/share/nginx/html
    - dhparam:/etc/nginx/dhparam
    - vhost:/etc/nginx/vhost.d
    - certs:/etc/nginx/certs:ro
    - /var/run/docker.sock:/tmp/docker.sock:ro
    labels:
    - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"

  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: nginx-proxy-lets-encrypt
    restart: always
    depends_on:
    - "nginx-proxy"
    volumes:
    - certs:/etc/nginx/certs:rw
    - vhost:/etc/nginx/vhost.d
    - html:/usr/share/nginx/html
    - /var/run/docker.sock:/var/run/docker.sock:ro

volumes:
  certs:
  html:
  vhost:
  dhparam:

volume_fromの代わりに

letsencrypt-nginx-proxy-companion のREADMEには、
--volumes-from (volumes_from:)を使う感じで書いてあるんですが、docker-compose.yaml の version: '3' 以降ではエラーになるので、下記issueの通りvolumes定義を使う。

ERROR: The Compose file './docker-compose.yaml' is invalid because:
Unsupported config option for services.letsencrypt: 'volumes_from'

https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion/issues/102#issuecomment-463573796

おわり

docker-compose up -d すると、WEBアプリケーション、nginx-proxy, letsencrypt-nginx-proxy-companionが立ち上がります。

docker-compose logs -f で、ログを確認すると自動で証明書発行されているのがわかるでしょう。
外部からhttpsでアクセスすると、nginx-proxyを通して、WEBアプリケーションが応答しているのも確認ができます。


注釈

※1 nip.io というワイルドカードDNS

グローバルIPはあるけど、ドメインを持っていない場合、
nio.io というワイルドカードDNSを使うと良いです。
IPアドレスのあとに .nip.io をつけると、ドメインとして使えて指定のIPにDNS解決してくれます。

xxx.xxx.xxx.xxx.nip.io とするとxxx.xxx.xxx.xxx の部分をIPとして名前解決してくれます。

更にサブドメインを追加して使用してもOKです。
mywebapp.xxx.xxx.xxx.xxx.nip.io

コメントを残す