WNT-Technology-20170126
Technology

はじめてのDocker その2 〜SSLに対応した複数ドメイン環境を作る方法〜

はじめてのDocker その2 〜SSLに対応した複数ドメイン環境を作る方法〜

本記事は前回の記事で作成した環境を前提にしています。まだ読んでいない方は下記記事をご覧ください。
はじめてのDocker 〜公式イメージで簡単にWordPressサイトをつくる方法〜

みなさんこんにちは!

前回の記事ではDockerを使ってWordPressサイトを立ち上げるところまでをやってみましたが、サイトを立ち上げる際は多くの場合テスト環境が必要になるかと思います。
そこで今回は本番環境とテスト環境を立ち上げ、nginx-porxyというDockerイメージを使用してアクセスをドメインごとに振り分けてみましょう。

また、商用利用も可能なSSL/TLS証明書を無料で取得できるサービス「Let’s encrypt」を使用してSSL対応もしてみたいと思います。

目次


概要

今回つくる環境は以下のようになります。
img01
ユーザからのアクセスは、まずはnginx-proxyコンテナが受け、アクセスされたドメインによってそれぞれのwordpressコンテナに振り分けます。
もちろん各Dockerイメージは自作のDockerfileからもつくることができますが、前回同様にできるだけ手軽に環境をつくってみるためにDocker Hubに公開されているイメージを利用することにしましょう。

nginx-proxyを使ってみる

まずは1つの環境でnginx-proxyを使ってみます。

前回作成したdocker-compose.ymlを修正して、下記のようにします。

version: '2'
services:
  proxy:
    image: jwilder/nginx-proxy
    privileged: true
    ports:
      - 80:80
    volumes:
      - /etc/nginx/vhost.d
      - /usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro
  mysite_db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
  mysite:
    image: wordpress
    environment:
      WORDPRESS_DB_PASSWORD: password
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_HOST: mysite_db:3306
      WORDPRESS_DB_NAME: mysite
      VIRTUAL_HOST: 172.17.8.101
      VIRTUAL_PORT: 80
    links:
      - mysite_db
※ ローカルIPアドレスが172.17.8.101である前提で記述しています。

3行目から11行目までが、新しく追加されたnginx-proxyイメージを使用したproxyコンテナになります。
mysiteコンテナのportsの記述を削除し、proxyコンテナのports80:80に設定しているので、仮想サーバの80番ポートへのアクセスはproxyコンテナにアクセスするようになります。
また、mysiteコンテナに、

      VIRTUAL_HOST: 172.17.8.101
      VIRTUAL_PORT: 80

という記述を追加していますが、これによってproxyコンテナへアクセスした際のホストが172.17.8.101であれば、mysiteコンテナの80番ポートへと振り分けられるようになります。
実際のサイトで利用する際には「172.17.8.101」部分を「hogehoge.com」などのようにそのサーバへ向いているドメインに書き換えておけば良いでしょう。

実際に172.17.8.101へとアクセスし、前回同様にwordpress画面が表示されれば成功です。

複数ドメイン環境を立ち上げる

それでは本番環境とテスト環境の2つの環境を立ち上げてみましょう。
nginx-proxyはアクセスした際のホストを元に振り分けるため、2つのホストでサーバにアクセスできる必要があります。実際のサーバ等であれば、「hogehoge.com」と「test.hogehoge.com」といったようにサブドメインをサーバへ向けてあげれば良いかと思いますが、本記事ではVagrantを使用した仮想サーバのため、最初にVagrantfileを少し修正します。

#Vagrantfile
 
〜〜省略〜〜
      ip = "172.17.8.#{i+100}"
      config.vm.network :private_network, ip: ip
〜〜省略〜〜

となっている箇所を、

#Vagrantfile
 
〜〜省略〜〜
      config.vm.network :private_network, ip: "172.17.8.101"
      config.vm.network :private_network, ip: "172.17.8.102"
〜〜省略〜〜

のように変更します。これで「172.17.8.101」と「172.17.8.102」の2つのローカルIPアドレスから仮想サーバにアクセスすることができるようになりました。
次にdocker-compose.ymlに下記のように追記をします。

version: '2'
services:
  proxy:
    image: jwilder/nginx-proxy
    privileged: true
    ports:
      - 80:80
    volumes:
      - /etc/nginx/vhost.d
      - /usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro
    restart: always
  mysite_db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
  mysite:
    image: wordpress
    environment:
      WORDPRESS_DB_PASSWORD: password
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_HOST: mysite_db:3306
      WORDPRESS_DB_NAME: mysite
      VIRTUAL_HOST: 172.17.8.101
      VIRTUAL_PORT: 80
    links:
      - mysite_db
  test_mysite_db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
  test_mysite:
    image: wordpress
    environment:
      WORDPRESS_DB_PASSWORD: password
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_HOST: test_mysite_db:3306
      WORDPRESS_DB_NAME: mysite
      VIRTUAL_HOST: 172.17.8.102
      VIRTUAL_PORT: 80
    links:
      - test_mysite_db

2つの環境は同様の環境とするため、mysite_dbコンテナ、mysiteコンテナと同じDockerイメージを使用して、test_mysite_dbコンテナ、test_mysiteコンテナを作成します。
また、VIRTUAL_HOSTの値をtest_mysiteコンテナでは「172.17.8.102」とすることで、172.17.8.101にアクセスした際はmysiteコンテナへ、172.17.8.102にアクセスした際はtest_mysiteコンテナへとアクセスが振り分けられるようになります。

仮想サーバ内で$ docker-compose up -dコマンドを実行したらhttp://172.17.8.101/http://172.17.8.102/にアクセスしてみましょう。
初期状態ではどちらも同じWordPressインストール画面のため分かりづらいですが、それぞれ違う設定でインストールを行うと、違う環境にアクセスできていることがわかるのではないかと思います。

このようにnginx-proxyイメージを使用すると、docker-compose.ymlファイルを少し変更するだけで複数環境をお手軽に構築することができます。さらに、nginx-proxyはdockerの実行状態を監視しており、新たなコンテナが起動すると自動で振り分け設定を更新してくれます。
これをうまく使えば本番環境とテスト環境だけではなく、ちょっと新しいプラグインを試してみたいときやWordPressのバージョンをあげるときなどに一時的に新たな環境を追加するのも簡単ですし、試したあとはコンテナを破棄してしまえばサーバ内が汚染されることもありません。

SSL対応をする

複数環境が無事作れたところで次はこれらの環境をSSL対応させます。
SSL対応をさせるためには「SSLサーバ証明書」の取得が必要となるのですが、今回は無料でSSLサーバ証明書を取得できる「Let’s encrypt」というサービスを使用してみます。

Let’s encryptの証明書発行を自動で行ってくれるletsencrypt-nginx-proxy-companionというDockerイメージがあるためこちらを使用します。
ただし証明書の発行には外部ネットワークからアクセス可能な環境が必要なため、ここからは外部からのアクセスが可能なサーバ等を用意し、複数環境にそれぞれドメインを割り当ててください。
「hogehoge.com」と「test.hogehoge.com」というドメインがサーバに割り当てられている想定で説明していきます。

docker-compose.ymlを下記のように修正します。

version: '2'
services:
  proxy:
    image: jwilder/nginx-proxy
    privileged: true
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./docker-compose.d/certs:/etc/nginx/certs:ro
      - /etc/nginx/vhost.d
      - /usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro
    restart: always
  letsencrypt-proxy:
    image: jrcs/letsencrypt-nginx-proxy-companion
    privileged: true
    volumes:
      - ./docker-compose.d/certs:/etc/nginx/certs:rw
      - /var/run/docker.sock:/var/run/docker.sock:ro
    volumes_from:
      - proxy
  mysite_db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
  mysite:
    image: wordpress
    environment:
      WORDPRESS_DB_PASSWORD: password
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_HOST: mysite_db:3306
      WORDPRESS_DB_NAME: mysite
      VIRTUAL_HOST: hogehoge.com
      VIRTUAL_PORT: 80
      LETSENCRYPT_HOST: hogehoge.com
      LETSENCRYPT_EMAIL: hogehoge@hoge.co.jp
    links:
      - mysite_db
  test_mysite_db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
  test_mysite:
    image: wordpress
    environment:
      WORDPRESS_DB_PASSWORD: password
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_HOST: test_mysite_db:3306
      WORDPRESS_DB_NAME: mysite
      VIRTUAL_HOST: test.hogehoge.com
      VIRTUAL_PORT: 80
      LETSENCRYPT_HOST: test.hogehoge.com
      LETSENCRYPT_EMAIL: hogehoge@hoge.co.jp
    links:
      - test_mysite_db

まずはproxyコンテナのportsに443番ポートを追加し、httpsによる接続を許可します。(8行目)

次にletsencrypt-proxyコンテナを作成するのですが、18-19行目の

    volumes:
      - ./docker-compose.d/certs:/etc/nginx/certs:rw

については、サーバ内の「./docker-compose.d/certs」ディレクトリをコンテナ内の「/etc/nginx/certs」ディレクトリにマウント(同期)させるという意味になります。
letsencrypt-proxyコンテナはLet’s encryptから取得してきたサーバ証明書をコンテナ内の/etc/nginx/certsディレクトリに格納しますが、それをサーバ内のディレクトリにマウントさせることで他のコンテナからも読み込めるようにします。

proxyコンテナにも9-10行目に

    volumes:
      - ./docker-compose.d/certs:/etc/nginx/certs:ro

という記述を追加し、letsencrypt-proxyコンテナが取得してきた証明書をproxyコンテナ内で読み込むようにします。ここで証明書が正しく読み込めれば、proxyコンテナは自動でhttps接続を有効にし、httpからhttpsへのリダイレクトも自動的に行うようになります。

また、mysiteコンテナ、test_mysiteコンテナには

      LETSENCRYPT_HOST: hogehoge.com
      LETSENCRYPT_EMAIL: hogehoge@hoge.co.jp
      LETSENCRYPT_HOST: test.hogehoge.com
      LETSENCRYPT_EMAIL: hogehoge@hoge.co.jp

といった記述を追加しており、ここの記述をもとにletsencrypt-proxyコンテナはサーバ証明書の発行を行っています。

https://hogehoge.com と https://test.hogehoge.com にアクセスし、正しくサイトが表示されれば成功です。

おわりに

いかがでしたでしょうか?
このようにDockerを使えば複数の環境を生成・破棄することも簡単にできてしまいます。
また、サーバの引越しなどを行う際にもDockerが動く環境さえ用意すれば、docker-compose.ymlファイルひとつで同じ環境を再現することができます。
ドキュメントを読みながらミドルウェアやアプリケーションを手動でインストールし、細かい環境の差によるエラーなどに泣かされることがなくなるだけでも大きなメリットではないでしょうか。
みなさんがDockerを使ってみる際の参考になれば。

それでは今日はこの辺で!

※ 今回の例ではDocker Hubからイメージをダウンロードしていますが、バージョンを指定していないため基本的にはlatestバージョンがダウンロードされます。そのためイメージをダウンロードするタイミングによっては異なるバージョンがダウンロードされ、正確には冪等性が担保されなくなってしまいます。
より正確に同じ環境を作成するためには使用するイメージのバージョンを全て指定するか、Dockerfileを自作し、そこからイメージをビルドするようにしてください。
thumbnail_technology_170124

記事が気に入ったらシェアしよう

この記事を書いたメンバー

丸山 佳郎 エンジニア/ディレクター

山と技術を愛するアウトドア系エンジニア。
フロントエンドをメインにしつつ、バックエンドもインフラも対応します。
好きな食べ物はライチと白米。

成果につながるWeb制作を

成果につながるWeb制作を
ビーワークスのミッションは「デザインで世の中を動かすこと」。
出版物、販促ツール、WEBサイト、ゲームアプリなど、多用な領域でクライアントのビジネス拡大に貢献するデザインを提供する制作会社です。

記事の更新をお知らせします!

  • 採用情報

    採用情報

    記事を読んで興味を持った方、
    ビーワークスの考え方に共感した方、
    一緒に新しいデザイン、創りませんか?

  • 制作実績

    制作実績

    日々、制作実績を更新中!
    ビーワークスの多様な実績をぜひご覧ください。

  • 乙女座
  • 天秤座
  • 蠍座