Docker Linux Wordpress

Docker上でWordPressとnginx-proxyを連携(SSL対応)

投稿日:

今回は、Docker上でWordpressサーバを構築し、SSLに対応したnginx-proxyとの連携を行います。

追記(2017/10/08):作成したdocker-compose.ymlをGithubに公開しました。目次の「Github」からダウンロードできます。

背景

VPSをレンタルしてLinuxサーバを立てました。私がサーバで実現したい要件は以下です。

  • ブログ用のWebサーバの構築
  • タスク管理用のチケット管理システムの構築
  • 上記の2つのサービスへのアクセスを、1つのIPアドレスで待ち受ける
  • 上記の要件をSSLを用いて暗号化する

そこで、今回はDockerとDockerイメージを用いて、上記の要件を実現しようと思います。

  • Webサーバ→WordPress公式Dockerイメージ(Wordpress+mysql)
  • チケット管理システム→Redmine公式Dockerイメージ(Redmine+mysql)
  • 1つのIPアドレス(メイン+サブドメイン)で上記サービスへのリクエストを待ち受ける→nginx-proxyを用いたマルチドメイン環境
  • 上記のSSLでの暗号化→nginx-proxyとdocker-letsencrypt-nginx-proxy-companionの連携

本記事では、Wordpress公式イメージを使用してWordpressサーバを立てる部分を記述します。

事前条件

本Wordpress環境構築の記事は、下記別記事にあります、nginx-proxy及びdocker-letsencrypt-nginx-proxy-companionを完了させた状態で動作させる方法を記述しています。本記事の内容を試される場合は、先に下記記事の作業を完了させてください。

また、本記事は、過去に作成したRedmine環境構築の記事と類似した内容になりますことをご了承ください。

WordPress公式docker-composeの編集

WordPress公式のイメージでは、mysqlイメージとの依存関係があります。このため、公式ページには、Wordpressとmysqlが連携できるよう、docker-compose.ymlのサンプルが記述されています。

今回は、このサンプルをもとに、nginx-proxyと連携するための設定を付加していきます。

できあがったdocker-compose.ymlは以下になります。

version: '3.1'

services:

  wordpress:
    image: wordpress
    hostname: domainname2.net
    restart: always
    ports:
      - "8080:80"
    depends_on:
      - mysql
    links:
      - mysql
    volumes:
      - /srv/docker/wordpress/wp-content:/var/www/html/wp-content
    environment:
      VIRTUAL_HOST: domainname2.net
      VIRTUAL_PORT: 8080
      LETSENCRYPT_HOST: domainname2.net
      LETSENCRYPT_EMAIL: emailaddress@test.com
      LETSENCRYPT_TEST: "false"

      WORDPRESS_DB_PASSWORD: sample
    networks:
      - default
      - ssl_proxy

  mysql:
    image: mysql:5.7
    restart: always
    volumes:
    - /srv/docker/wordpress/mysql:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: sample
    networks:
      - default

networks:
  ssl_proxy:
    external: true

wordpress側の大きな変更点は以下です。

  • 15行目では、wordpressの設定を永続化させるため、volumesオプションでwordpressディレクトリをホスト側にマウントしています。
    volumes:
      - /srv/docker/wordpress/wp-content:/var/www/html/wp-content
  •  18〜19行目に、環境変数としてnginx-proxyの設定を追加しました
    • VIRTUAL_HOST:nginx-proxyにプロキシしてほしいドメイン名を記述します。
      VIRTUAL_HOST: domainname2.net

      この例の場合、domainname2.netに来たパケットをプロキシしてくれます。

    • VIRTUAL_PORT:VIRTUAL_HOSTに該当したパケットをどのポートにフォワードするかを決めます。
      VIRTUAL_PORT: 8080

      この例の場合は8080番ポートにフォワードするため、10行目のportsオプションにより、wordpress内部にフォワードされます。

  • 20〜22行目では、docker-letsencrypt-nginx-proxy-companionが、Let’s encryptで使用する情報を記述しています。
    LETSENCRYPT_HOST: domainname2.net
    LETSENCRYPT_EMAIL: emailaddress@test.com
    LETSENCRYPT_TEST: "false"

    それぞれ、証明書を申請するためのドメイン名、メールアドレスです。また、テストは行わないため、falseにしています。

  • 23行目には、networksオプションで、nginx-proxyが認識するネットワークブリッジ(ssl_proxy)を記述します。
    networks:
      - default
      - ssl_proxy

    ブリッジの指定を忘れると、nginx-proxyがVIRTUAL_HOST等を認識できず、プロキシが行われないため注意してください。

mysql側の大きな変更点は以下です。

  • 32行目では、データベースの永続化とwordpressとの連携を行うため、volumesコマンドでホスト側のwordpressディレクトリをマウントしています。
    volumes:
      - /srv/docker/wordpress/mysql:/var/lib/mysql

最後に、36行目からは、networksで、nginx-proxyと共有するネットワークブリッジについて、外部参照可能な状態にします。

networks:
  ssl_proxy:
    external: true

動作確認

nginx-proxy用のdocker-composeを起動後、wordpress用のdocker-compose.ymlファイルを起動します。

admin@hostname:~# docker-compose up -d

事前に動作させておいたnginx-proxyコンテナにexecして、wordpressコンテナが正しくproxyされているかを確認します。

admin@hostname:~# docker exec -it nginx-proxy /bin/bash
root@698eef80cff4:/app# cat /etc/nginx/conf.d/default.conf 
server {
        server_name _; # This is just an invalid value which will never trigger on a real hostname.
        listen 80;
        access_log /var/log/nginx/access.log vhost;
        return 503;
}
(中略)
# domainname2.net
upstream domainname2.net {
                                ## Can be connect with "ssl_proxy" network
                        # wordpress_wordpress_1
                        server 172.18.0.4:80;
}
server {
        server_name domainname2.net;
        listen 80 ;
        access_log /var/log/nginx/access.log vhost;
        return 301 https://$host$request_uri;
}
server {
        server_name domainname2.net;
        listen 443 ssl http2 ;
        access_log /var/log/nginx/access.log vhost;
        ssl_protocols (省略);
        (SSLの情報は省略)
        include /etc/nginx/vhost.d/default;
        location / {
                proxy_pass http://domainname2.net;
        }
}

domainname2.netに対するプロキシ及びSSLの情報が追加されていることが確認できます。

その後、設定したドメイン名に向かってブラウザ上からHTTPSでリクエストを投げ、無事、wordpressのアカウント登録画面が表示されれば、動作確認完了です。

終わりに

これで、nginx-proxy越しにサーバに対してアクセスする環境が整いました。以降は、プロキシしたいサービスが増加するたびに、docker-compose.ymlにnginx-proxyの設定を書き込めば良いわけです。

wordpress公式コンテナでは、データの永続化を行わないために、wordpress内で編集したデータはコンテナ削除後にはきされてしまいます。しかし、今回作成したdocker-composeならば、記事やテーマ、プラグインまで保存するため、コンテナ再起動後も問題なく動作します。

Github

今回使用したdocker-compose.ymlをGithubに公開しました。下記リンクからgit cloneすることで、docker-compose.ymlが取得できます。

-Docker, Linux, Wordpress
-, ,

執筆者:


  1. なにわ より:

    こんにちは、dockerでwordpressを運営していて参考にしております。
    例えば、本番環境でconfにproxy_set_header X-Forwarded-For 等の情報を反映させたい場合、docker-compose.ymlに何を書けば反映されるのでしょうか?
    それとも、docker-wordpress-using-nginx-proxy で反映させるにはconfを永続化して、直接編集する形がいいのでしょうか?
    もし、なにか知っていっていたら教えていただけると幸いです。

    • shinji_kirino より:

      こんにちは。コメントありがとうございます。

      >例えば、本番環境でconfにproxy_set_header X-Forwarded-For 等の情報を反映させたい場合、docker-compose.ymlに何を書けば反映されるのでしょうか?
      >それとも、docker-wordpress-using-nginx-proxy で反映させるにはconfを永続化して、直接編集する形がいいのでしょうか?
      nginx-proxyにX-Forwarded-For等のconf設定を反映させるには、下記2通りの方法があります。
      1.docker-compose等を使用し、コンテナ起動前にコンテナ内で編集してから起動する
      2.confをホストで編集してから、ホストのconfをコンテナ側に入れて起動する

      個人的には、2を推奨します。

      1の方法をとる場合、docker-compose.ymlのcommandを使用してecho等でconfを編集することになります(environment経由で設定可能な項目でないため)。
      しかし、docker-composeのcommandはDockerfileのCMDを上書きするため、nginx-proxyの動作を妨げることになり、推奨しかねます。
      参考:ja.stackoverflowにおけるdocker-composeのcommandについての書き込み

      したがって、2のように、ホストで編集済みのconfを何らかの手段でコンテナ側に流し込む手段を推奨します。
      流し込む手段はvolumeによるマウントによって、confのみをマウントして使用するのがよろしいかと思います。

comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

関連記事

cmake, googletestを利用したC++開発環境の構築テスト

自学用メモ。 業務で使用しているcmakeの勉強がてら、業務に近いソースツリーを作成した。 googletestを用いた単体テストも合わせて書けるような構成になっている。 テンプレートとして、今後のC …

systemdでのCPU制限方法~serviceファイルでの設定編

systemd に悩まされる皆様、進捗どうですか(? 標題の件、仕事で必要に迫られたため、備忘録として。 目次1 まえがき2 動作環境3 確認内容3.1 systemdから起動するserviceのデフ …

Dockerを使用した簡単なC++実行環境の構築

今回は、C++の機能を調査するための簡単なテスト環境を、Dockerを用いて構築する手順を解説します。 目次1 要件2 仕様3 実装3.1 元になるイメージ3.2 Dockerfileの作成3.3 実 …

Docker上でnginx-proxy他を使ってSSL対応マルチドメインサーバ環境の構築

今回は、nginx-proxyを使用し、SSLに対応したマルチドメイン環境を構築します。 追記(2017/10/08):作成したdocker-compose.ymlをGithubに公開しました。目次の …

Docker上でRedmineとnginx-proxyを連携(SSL対応)

今回は、Docker上でRedmineサーバを構築し、SSLに対応したnginx-proxyとの連携を行います。 追記(2017/10/08):作成したdocker-compose.ymlをGithu …