DockerComposeでWordPressをインストールする方法

提供:Dev Guides
移動先:案内検索

序章

WordPress は、PHP処理を備えたMySQLデータベース上に構築された無料のオープンソースコンテンツ管理システム(CMS)です。 拡張可能なプラグインアーキテクチャとテンプレートシステム、およびその管理のほとんどがWebインターフェイスを介して実行できるという事実のおかげで、WordPressは、ブログから製品ページ、eコマースサイトまで、さまざまなタイプのWebサイトを作成するときに人気があります。

WordPressの実行には通常、 LAMP (Linux、Apache、MySQL、およびPHP)または LEMP (Linux、Nginx、MySQL、およびPHP)スタックのインストールが含まれます。 ただし、DockerDockerCompose などのツールを使用すると、優先スタックのセットアップとWordPressのインストールのプロセスを簡素化できます。 個々のコンポーネントを手動でインストールする代わりに、ライブラリ、構成ファイル、環境変数などを標準化する images を使用して、これらのイメージを container 、で実行される分離されたプロセスで実行できます。共有オペレーティングシステム。 さらに、Composeを使用すると、アプリケーションやデータベースなどの複数のコンテナーを調整して、相互に通信できます。

このチュートリアルでは、マルチコンテナのWordPressインストールをビルドします。 コンテナには、MySQLデータベース、Nginx Webサーバー、およびWordPress自体が含まれます。 また、サイトに関連付けたいドメインの Let'sEncryptを使用してTLS/SSL証明書を取得することにより、インストールを保護します。 最後に、 cron ジョブを設定して証明書を更新し、ドメインのセキュリティを維持します。

前提条件

このチュートリアルに従うには、次のものが必要です。

  • Ubuntu 18.04を実行しているサーバーと、sudo特権とアクティブなファイアウォールを持つ非rootユーザー。 これらの設定方法のガイダンスについては、この初期サーバー設定ガイドを参照してください。
  • Ubuntu18.04にDockerをインストールして使用する方法の手順1と2に従ってサーバーにDockerをインストールします。
  • Ubuntu 18.04にDockerComposeをインストールする方法のステップ1に従って、サーバーにDockerComposeをインストールします。
  • 登録されたドメイン名。 このチュートリアルでは、全体を通してexample.comを使用します。 Freenom で無料で入手するか、選択したドメインレジストラを使用できます。
  • 次の両方のDNSレコードがサーバー用に設定されています。 DigitalOceanアカウントに追加する方法の詳細については、このDigitalOcean DNSの概要をフォローしてください(使用している場合)。
    • サーバーのパブリックIPアドレスを指すexample.comのAレコード。
    • サーバーのパブリックIPアドレスを指すwww.example.comのAレコード。

ステップ1—Webサーバー構成の定義

コンテナを実行する前に、最初のステップはNginxWebサーバーの構成を定義することです。 構成ファイルには、WordPress固有のロケーションブロックと、証明書の自動更新のためにLet'sEncryptの検証要求をCertbotクライアントに送信するロケーションブロックが含まれます。

まず、WordPressセットアップ用のwordpressというプロジェクトディレクトリを作成し、次の場所に移動します。

mkdir wordpress && cd wordpress

次に、構成ファイル用のディレクトリを作成します。

mkdir nginx-conf

nanoまたはお気に入りのエディターでファイルを開きます。

nano nginx-conf/nginx.conf

このファイルでは、サーバー名とドキュメントルートのディレクティブを含むサーバーブロックと、証明書、PHP処理、静的アセットリクエストに対するCertbotクライアントのリクエストを送信するロケーションブロックを追加します。

次のコードをファイルに貼り付けます。 example.comは必ず独自のドメイン名に置き換えてください。

〜/ wordpress / nginx-conf / nginx.conf

server {
        listen 80;
        listen [::]:80;

        server_name example.com www.example.com;

        index index.php index.html index.htm;

        root /var/www/html;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

サーバーブロックには、次の情報が含まれています。

ディレクティブ:

  • listen:これはNginxにポート80でリッスンするように指示します。これにより、証明書リクエストにCertbotのwebrootプラグインを使用できるようになります。 ポート443はまだではなくであることに注意してください。証明書を正常に取得したら、SSLを含むように構成を更新します。
  • server_name:これは、サーバー名と、サーバーへの要求に使用する必要があるサーバーブロックを定義します。 この行のexample.comは、必ず独自のドメイン名に置き換えてください。
  • indexindexディレクティブは、サーバーへの要求を処理するときにインデックスとして使用されるファイルを定義します。 ここでデフォルトの優先順位を変更し、index.phpindex.htmlの前に移動して、可能な場合はindex.phpというファイルをNginxが優先するようにしました。
  • rootrootディレクティブは、サーバーへのリクエストのルートディレクトリに名前を付けます。 このディレクトリ/var/www/htmlは、 WordPress Dockerfile の指示により、ビルド時にマウントポイントとして作成されます。 これらのDockerfile命令は、WordPressリリースのファイルがこのボリュームにマウントされていることも確認します。

ロケーションブロック:

  • location ~ /.well-known/acme-challenge:このロケーションブロックは、.well-knownディレクトリへのリクエストを処理します。ここで、Certbotは、ドメインのDNSがサーバーに解決されることを検証するための一時ファイルを配置します。 この構成が適切に行われると、Certbotのwebrootプラグインを使用して、ドメインの証明書を取得できるようになります。
  • location /:このロケーションブロックでは、try_filesディレクティブを使用して、個々のURI要求に一致するファイルをチェックします。 ただし、デフォルトで404 Not Foundステータスを返す代わりに、リクエスト引数を使用してWordPressのindex.phpファイルに制御を渡します。
  • location ~ \.php$:このロケーションブロックはPHP処理を処理し、これらのリクエストをwordpressコンテナにプロキシします。 WordPressDockerイメージはphp:fpmイメージに基づいているため、このブロックにはFastCGIプロトコルに固有の構成オプションも含まれます。 Nginxには、PHPリクエスト用の独立したPHPプロセッサが必要です。この場合、これらのリクエストは、php:fpmイメージに含まれているphp-fpmプロセッサによって処理されます。 さらに、このロケーションブロックには、FastCGI固有のディレクティブ、変数、およびオプションが含まれており、wordpressコンテナーで実行されているWordPressアプリケーションにリクエストをプロキシし、解析されたリクエストURIの優先インデックスを設定し、URIリクエストを解析します。
  • location ~ /\.ht:Nginxは.htaccessファイルを処理します。 deny_allディレクティブは、.htaccessファイルがユーザーに提供されないようにします。
  • location = /favicon.icolocation = /robots.txt:これらのブロックは、/favicon.icoおよび/robots.txtへの要求がログに記録されないようにします。
  • location ~* \.(css|gif|ico|jpeg|jpg|js|png)$:このブロックは、静的アセットリクエストのロギングをオフにし、これらのアセットは通常、提供に費用がかかるため、高度にキャッシュ可能であることを保証します。

FastCGIプロキシの詳細については、NginxでのFastCGIプロキシの理解と実装を参照してください。 サーバーとロケーションブロックの詳細については、Nginxサーバーとロケーションブロックの選択アルゴリズムについてを参照してください。

編集が終了したら、ファイルを保存して閉じます。 nanoを使用した場合は、CTRL+XYENTERの順に押してください。

Nginx構成が整ったら、実行時にアプリケーションとデータベースコンテナーに渡す環境変数の作成に進むことができます。

ステップ2—環境変数を定義する

データベースとWordPressアプリケーションコンテナは、アプリケーションデータを保持してアプリケーションにアクセスできるようにするために、実行時に特定の環境変数にアクセスする必要があります。 これらの変数には、機密情報と非機密情報の両方が含まれます。MySQL root パスワードとアプリケーションデータベースのユーザーとパスワードの機密値、およびアプリケーションデータベース名とホストの非機密情報です。

Docker Composeファイル(コンテナーの実行方法に関する情報を含むメインファイル)でこれらすべての値を設定するのではなく、.envファイルで機密値を設定し、その循環を制限できます。 これにより、これらの値がプロジェクトリポジトリにコピーされ、公開されるのを防ぐことができます。

メインプロジェクトディレクトリ~/wordpressで、.envというファイルを開きます。

nano .env

このファイルに設定する機密値には、MySQL root ユーザーのパスワードと、WordPressがデータベースにアクセスするために使用するユーザー名とパスワードが含まれます。

次の変数名と値をファイルに追加します。 ここで、変数ごとに独自の値を指定することを忘れないでください。

〜/ wordpress / .env

MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password

root 管理者アカウントのパスワードと、アプリケーションデータベースの優先ユーザー名とパスワードが含まれています。

編集が終了したら、ファイルを保存して閉じます。

.envファイルには機密情報が含まれているため、プロジェクトの.gitignoreファイルと.dockerignoreファイルに含まれていることを確認してください。 Dockerは、GitリポジトリとDockerイメージにそれぞれnotをコピーします。

バージョン管理のためにGitを使用する場合は、現在の作業ディレクトリをgit initを使用してリポジトリとして初期化します。

git init

次に、.gitignoreファイルを開きます。

nano .gitignore

.envをファイルに追加します。

〜/ wordpress / .gitignore

.env

編集が終了したら、ファイルを保存して閉じます。

同様に、.env.dockerignoreファイルに追加して、このディレクトリをビルドコンテキストとして使用しているときにコンテナに追加されないようにすることをお勧めします。

ファイルを開きます。

nano .dockerignore

.envをファイルに追加します。

〜/ wordpress / .dockerignore

.env

この下に、オプションで、アプリケーションの開発に関連するファイルとディレクトリを追加できます。

〜/ wordpress / .dockerignore

.env
.git
docker-compose.yml
.dockerignore

終了したら、ファイルを保存して閉じます。

機密情報が揃ったら、docker-compose.ymlファイルでのサービスの定義に進むことができます。

ステップ3—DockerComposeを使用したサービスの定義

docker-compose.ymlファイルには、セットアップのサービス定義が含まれています。 Composeのserviceは実行中のコンテナーであり、サービス定義は各コンテナーの実行方法に関する情報を指定します。

Composeを使用すると、マルチコンテナーアプリケーションを実行するためにさまざまなサービスを定義できます。これは、Composeを使用すると、これらのサービスを共有ネットワークおよびボリュームとリンクできるためです。 これは、データベース、WordPressアプリケーション、およびWebサーバー用にさまざまなコンテナーを作成するため、現在のセットアップに役立ちます。 また、Webサーバーの証明書を取得するために、Certbotクライアントを実行するためのコンテナーを作成します。

まず、docker-compose.ymlファイルを開きます。

nano docker-compose.yml

次のコードを追加して、作成ファイルのバージョンとdbデータベースサービスを定義します。

〜/ wordpress / docker-compose.yml

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

dbサービス定義には、次のオプションが含まれています。

  • image:これは、コンテナーを作成するためにプルするイメージを作成するように指示します。 mysql:latestイメージは引き続き更新されるため、今後の競合を回避するために、 mysql:8.0イメージをここに固定しています。 バージョンの固定と依存関係の競合の回避の詳細については、Dockerfileのベストプラクティスに関するDockerのドキュメントを参照してください。
  • container_name:コンテナの名前を指定します。
  • restart:これはコンテナの再起動ポリシーを定義します。 デフォルトはnoですが、手動で停止しない限り、コンテナーを再起動するように設定しています。
  • env_file:このオプションは、ビルドコンテキストにある.envというファイルから環境変数を追加することをComposeに指示します。 この場合、ビルドコンテキストは現在のディレクトリです。
  • environment:このオプションを使用すると、.envファイルで定義されているもの以外に、環境変数を追加できます。 MYSQL_DATABASE変数をwordpressに設定して、アプリケーションデータベースの名前を指定します。 これは機密情報ではないため、docker-compose.ymlファイルに直接含めることができます。
  • volumes:ここでは、dbdataという名前のボリュームをコンテナの/var/lib/mysqlディレクトリにマウントしています。 これは、ほとんどのディストリビューションでのMySQLの標準データディレクトリです。
  • command:このオプションは、イメージのデフォルトのCMD命令をオーバーライドするコマンドを指定します。 この例では、Dockerイメージの標準 mysqldコマンドにオプションを追加します。これにより、コンテナーでMySQLサーバーが起動します。 このオプション--default-authentication-plugin=mysql_native_passwordは、--default-authentication-pluginシステム変数をmysql_native_passwordに設定し、サーバーへの新しい認証要求を管理する認証メカニズムを指定します。 PHP、したがってWordPressイメージ MySQLの新しい認証デフォルトをサポートしないため、アプリケーションデータベースユーザーを認証するには、この調整を行う必要があります。
  • networks:これは、アプリケーションサービスがapp-networkネットワークに参加することを指定します。これは、ファイルの下部で定義します。

次に、dbサービス定義の下に、wordpressアプリケーションサービスの定義を追加します。

〜/ wordpress / docker-compose.yml

...
  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

このサービス定義では、dbサービスで行ったように、コンテナーに名前を付け、再起動ポリシーを定義しています。 このコンテナに固有のオプションもいくつか追加しています。

  • depends_on:このオプションにより、コンテナーが依存関係の順に開始され、wordpressコンテナーがdbコンテナーの後に開始されます。 WordPressアプリケーションは、アプリケーションデータベースとユーザーの存在に依存しているため、この依存関係の順序を表現することで、アプリケーションを適切に起動できます。
  • image:このセットアップでは、 5.1.1-fpm-alpine WordPressimageを使用しています。 ステップ1で説明したように、このイメージを使用すると、NginxがPHP処理を処理するために必要なphp-fpmプロセッサがアプリケーションに確実に搭載されます。 これもalpineイメージであり、 Alpine Linuxプロジェクトから派生したものであり、全体的なイメージサイズを抑えるのに役立ちます。 alpineイメージを使用するメリットとデメリット、およびこれがアプリケーションにとって意味があるかどうかの詳細については、DockerHubのImageVariantsセクションの詳細な説明を参照してください。 WordPress画像ページ
  • env_file:ここでも、.envファイルから値を取得することを指定します。これは、アプリケーションデータベースのユーザーとパスワードを定義した場所だからです。
  • environment:ここでは、.envファイルで定義した値を使用していますが、WordPressイメージが期待する変数名にそれらを割り当てています:WORDPRESS_DB_USERおよびWORDPRESS_DB_PASSWORD。 また、WORDPRESS_DB_HOSTを定義しています。これは、MySQLのデフォルトポート3306でアクセス可能なdbコンテナーで実行されるMySQLサーバーになります。 WORDPRESS_DB_NAMEは、MYSQL_DATABASEのMySQLサービス定義で指定した値wordpressと同じになります。
  • volumes:WordPressイメージによって作成された/var/www/htmlマウントポイントwordpressという名前のボリュームをマウントしています。 このように名前付きボリュームを使用すると、アプリケーションコードを他のコンテナと共有できます。
  • networkswordpressコンテナもapp-networkネットワークに追加します。

次に、wordpressアプリケーションサービス定義の下に、webserverNginxサービスの次の定義を追加します。

〜/ wordpress / docker-compose.yml

...
  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

ここでも、コンテナーに名前を付け、開始順にwordpressコンテナーに依存するようにしています。 alpineイメージ—1.15.12-アルパインNginxイメージも使用しています。

このサービス定義には、次のオプションも含まれています。

  • ports:これにより、ポート80が公開され、ステップ1nginx.confファイルで定義した構成オプションが有効になります。
  • volumes :ここでは、名前付きボリュームとバインドマウント : wordpress:/ var / www / html:これにより、WordPressアプリケーションコードが/ var / www / htmlディレクトリ(Nginxサーバーブロックのルートとして設定したディレクトリ)にマウントされます。 ./nginx-conf:/etc/nginx/conf.d:これにより、ホスト上のNginx構成ディレクトリがコンテナ上の関連ディレクトリにバインドマウントされ、ホスト上のファイルに加えた変更が確実に反映されます。容器。 certbot-etc:/ etc /letsencrypt:これにより、ドメインに関連するLet'sEncryptの証明書とキーがコンテナの適切なディレクトリにマウントされます。

また、このコンテナをapp-networkネットワークに追加しました。

最後に、webserver定義の下に、certbotサービスの最後のサービス定義を追加します。 ここに記載されているメールアドレスとドメイン名は、必ず自分の情報に置き換えてください。

〜/ wordpress / docker-compose.yml

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email [email protected] --agree-tos --no-eff-email --staging -d example.com -d www.example.com

この定義は、DockerHubからcertbot / certbotimageをプルするようにComposeに指示します。 また、名前付きボリュームを使用して、certbot-etcのドメイン証明書とキーおよびwordpressのアプリケーションコードを含むリソースをNginxコンテナーと共有します。

ここでも、depends_onを使用して、webserverサービスの実行後にcertbotコンテナーを開始するように指定しました。

コンテナのデフォルトのcertbotコマンドで実行するサブコマンドを指定するcommandオプションも含まれています。 certonlyサブコマンドは、次のオプションを使用して証明書を取得します。

  • --webroot:これは、認証のためにwebrootプラグインを使用してファイルをwebrootフォルダーに配置するようにCertbotに指示します。 このプラグインは、 HTTP-01検証メソッドに依存しています。このメソッドは、HTTPリクエストを使用して、Certbotが特定のドメイン名に応答するサーバーからリソースにアクセスできることを証明します。
  • --webroot-path:これはwebrootディレクトリのパスを指定します。
  • --email:登録と復旧のためのご希望のメールアドレス。
  • --agree-tos:これは、ACMEのサブスクライバー契約に同意することを指定します。
  • --no-eff-email:これは、電子メールを Electronic Frontier Foundation (EFF)と共有したくないことをCertbotに通知します。 必要に応じて、これを省略してください。
  • --staging:これは、Let'sEncryptのステージング環境を使用してテスト証明書を取得することをCertbotに通知します。 このオプションを使用すると、構成オプションをテストして、ドメイン要求の制限を回避できます。 これらの制限の詳細については、Let'sEncryptのレート制限のドキュメントを参照してください。
  • -d:これにより、リクエストに適用するドメイン名を指定できます。 この場合、example.comwww.example.comが含まれています。 これらは必ず独自のドメインに置き換えてください。

certbotサービス定義の下に、ネットワークとボリュームの定義を追加します。

〜/ wordpress / docker-compose.yml

...
volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge  

トップレベルのvolumesキーは、ボリュームcertbot-etcwordpress、およびdbdataを定義します。 Dockerがボリュームを作成すると、ボリュームのコンテンツは、Dockerによって管理されるホストファイルシステム/var/lib/docker/volumes/上のディレクトリに保存されます。 次に、各ボリュームのコンテンツは、このディレクトリからボリュームを使用する任意のコンテナにマウントされます。 このようにして、コンテナ間でコードとデータを共有することが可能です。

ユーザー定義のブリッジネットワークapp-networkは、コンテナーが同じDockerデーモンホスト上にあるため、コンテナー間の通信を可能にします。 これにより、ポートを外部に公開することなく、同じブリッジネットワーク上のコンテナ間のすべてのポートが開かれるため、アプリケーション内のトラフィックと通信が合理化されます。 したがって、dbwordpress、およびwebserverコンテナーは相互に通信でき、フロントエンドアクセス用にポート80を公開するだけで済みます。アプリケーション。

完成したdocker-compose.ymlファイルは次のようになります。

〜/ wordpress / docker-compose.yml

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email [email protected] --agree-tos --no-eff-email --staging -d example.com -d www.example.com

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge  

編集が終了したら、ファイルを保存して閉じます。

サービス定義が整ったら、コンテナを起動して証明書要求をテストする準備が整います。

ステップ4—SSL証明書とクレデンシャルを取得する

docker-compose up コマンドを使用してコンテナーを開始できます。これにより、指定した順序でコンテナーが作成および実行されます。 ドメイン要求が成功すると、出力に正しい終了ステータスが表示され、webserverコンテナの/etc/letsencrypt/liveフォルダに適切な証明書がマウントされます。

docker-compose up-dフラグを使用してコンテナーを作成します。これにより、dbwordpress、およびwebserverコンテナーが実行されます。バックグラウンドで:

docker-compose up -d

サービスが作成されたことを確認する出力が表示されます。

OutputCreating db ... done
Creating wordpress ... done
Creating webserver ... done
Creating certbot   ... done

docker-compose ps を使用して、サービスのステータスを確認します。

docker-compose ps

すべてが成功した場合、dbwordpress、およびwebserverサービスはUpになり、certbotコンテナーは0ステータスメッセージ:

Output  Name                 Command               State           Ports       
-------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0                      
db          docker-entrypoint.sh --def ...   Up       3306/tcp, 33060/tcp
webserver   nginx -g daemon off;             Up       0.0.0.0:80->80/tcp 
wordpress   docker-entrypoint.sh php-fpm     Up       9000/tcp           

dbwordpress、またはwebserverサービスのState列にUp以外のものが表示された場合、または終了ステータスcertbotコンテナの0以外の場合は、 docker-composelogsコマンドでサービスログを確認してください。

docker-compose logs service_name

これで、 docker-compose exec を使用して、証明書がwebserverコンテナーにマウントされていることを確認できます。

docker-compose exec webserver ls -la /etc/letsencrypt/live

証明書の要求が成功した場合は、次のような出力が表示されます。

Outputtotal 16
drwx------    3 root     root          4096 May 10 15:45 .
drwxr-xr-x    9 root     root          4096 May 10 15:45 ..
-rw-r--r--    1 root     root           740 May 10 15:45 README
drwxr-xr-x    2 root     root          4096 May 10 15:45 example.com

リクエストが成功することがわかったので、certbotサービス定義を編集して、--stagingフラグを削除できます。

docker-compose.ymlを開きます:

nano docker-compose.yml

certbotサービス定義のあるファイルのセクションを見つけ、commandオプションの--stagingフラグを--force-renewalフラグに置き換えます。これによりCertbotに通知されます。既存の証明書と同じドメインを持つ新しい証明書を要求すること。 certbotサービス定義は次のようになります。

〜/ wordpress / docker-compose.yml

...
  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - certbot-var:/var/lib/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email [email protected] --agree-tos --no-eff-email --force-renewal -d example.com -d www.example.com
...

これで、docker-compose upを実行して、certbotコンテナーを再作成できます。 また、--no-depsオプションを含めて、webserverサービスがすでに実行されているため、開始をスキップできることをComposeに通知します。

docker-compose up --force-recreate --no-deps certbot

証明書要求が成功したことを示す出力が表示されます。

OutputRecreating certbot ... done
Attaching to certbot
certbot      | Saving debug log to /var/log/letsencrypt/letsencrypt.log
certbot      | Plugins selected: Authenticator webroot, Installer None
certbot      | Renewing an existing certificate
certbot      | Performing the following challenges:
certbot      | http-01 challenge for example.com
certbot      | http-01 challenge for www.example.com
certbot      | Using the webroot path /var/www/html for all unmatched domains.
certbot      | Waiting for verification...
certbot      | Cleaning up challenges
certbot      | IMPORTANT NOTES:
certbot      |  - Congratulations! Your certificate and chain have been saved at:
certbot      |    /etc/letsencrypt/live/example.com/fullchain.pem
certbot      |    Your key file has been saved at:
certbot      |    /etc/letsencrypt/live/example.com/privkey.pem
certbot      |    Your cert will expire on 2019-08-08. To obtain a new or tweaked
certbot      |    version of this certificate in the future, simply run certbot
certbot      |    again. To non-interactively renew *all* of your certificates, run
certbot      |    "certbot renew"
certbot      |  - Your account credentials have been saved in your Certbot
certbot      |    configuration directory at /etc/letsencrypt. You should make a
certbot      |    secure backup of this folder now. This configuration directory will
certbot      |    also contain certificates and private keys obtained by Certbot so
certbot      |    making regular backups of this folder is ideal.
certbot      |  - If you like Certbot, please consider supporting our work by:
certbot      | 
certbot      |    Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
certbot      |    Donating to EFF:                    https://eff.org/donate-le
certbot      | 
certbot exited with code 0

証明書を配置したら、Nginx構成を変更してSSLを含めることができます。

手順5—Webサーバーの構成とサービス定義を変更する

Nginx構成でSSLを有効にするには、HTTPSへのHTTPリダイレクトの追加、SSL証明書とキーの場所の指定、セキュリティパラメーターとヘッダーの追加が必要です。

webserverサービスを再作成してこれらの追加を含めるので、ここで停止できます。

docker-compose stop webserver

構成ファイル自体を変更する前に、まずcurlを使用してCertbotから推奨のNginxセキュリティパラメーターを取得しましょう。

curl -sSLo nginx-conf/options-ssl-nginx.conf https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf

このコマンドは、nginx-confディレクトリにあるoptions-ssl-nginx.confというファイルにこれらのパラメータを保存します。

次に、前に作成したNginx構成ファイルを削除します。

rm nginx-conf/nginx.conf

ファイルの別のバージョンを開きます。

nano nginx-conf/nginx.conf

次のコードをファイルに追加して、HTTPをHTTPSにリダイレクトし、SSLクレデンシャル、プロトコル、およびセキュリティヘッダーを追加します。 example.comを独自のドメインに置き換えることを忘れないでください。

〜/ wordpress / nginx-conf / nginx.conf

server {
        listen 80;
        listen [::]:80;

        server_name example.com www.example.com;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                rewrite ^ https://$host$request_uri? permanent;
        }
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name example.com www.example.com;

        index index.php index.html index.htm;

        root /var/www/html;

        server_tokens off;

        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

        include /etc/nginx/conf.d/options-ssl-nginx.conf;

        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Referrer-Policy "no-referrer-when-downgrade" always;
        add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
        # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        # enable strict transport security only if you understand the implications

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }
        
        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

HTTPサーバーブロックは、.well-known/acme-challengeディレクトリへのCertbot更新要求のWebルートを指定します。 また、ルートディレクトリへのHTTPリクエストをHTTPSに転送するrewriteディレクティブも含まれています。

HTTPSサーバーブロックは、sslおよびhttp2を有効にします。 HTTP / 2がHTTPプロトコルを反復処理する方法と、それがWebサイトのパフォーマンスにもたらすメリットの詳細については、 Ubuntu18.04でHTTP/2サポートを使用してNginxをセットアップする方法の概要を参照してください。

このブロックには、SSL証明書とキーの場所、およびnginx-conf/options-ssl-nginx.confに保存した推奨されるCertbotセキュリティパラメーターも含まれています。

さらに、 SSLLabsSecurityHeadersサーバーテストサイトなどでAの評価を取得できるようにするセキュリティヘッダーがいくつか含まれています。 これらのヘッダーには、 X-Frame-OptionsX-Content-Type-OptionsReferrer PolicyContent-Security-Policy 、およびX-XSS-ProtectionHTTP Strict Transport Security (HSTS)ヘッダーはコメント化されています。これは、影響を理解し、「プリロード」機能を評価した場合にのみ有効にしてください。

rootおよびindexディレクティブもこのブロックにあり、ステップ1で説明した残りのWordPress固有のロケーションブロックも同様です。

編集が終了したら、ファイルを保存して閉じます。

webserverサービスを再作成する前に、443ポートマッピングをwebserverサービス定義に追加する必要があります。

docker-compose.ymlファイルを開きます。

nano docker-compose.yml

webserverサービス定義で、次のポートマッピングを追加します。

〜/ wordpress / docker-compose.yml

...
  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

docker-compose.ymlファイルは、終了すると次のようになります。

〜/ wordpress / docker-compose.yml

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email [email protected] --agree-tos --no-eff-email --force-renewal -d example.com -d www.example.com

volumes:
  certbot-etc:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge  

編集が終了したら、ファイルを保存して閉じます。

webserverサービスを再作成します。

docker-compose up -d --force-recreate --no-deps webserver

docker-compose psでサービスを確認してください。

docker-compose ps

dbwordpress、およびwebserverサービスが実行されていることを示す出力が表示されます。

Output  Name                 Command               State                     Ports                  
----------------------------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0                                           
db          docker-entrypoint.sh --def ...   Up       3306/tcp, 33060/tcp                     
webserver   nginx -g daemon off;             Up       0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress   docker-entrypoint.sh php-fpm     Up       9000/tcp    

コンテナが実行されている状態で、Webインターフェイスを介してWordPressのインストールを完了することができます。

ステップ6—Webインターフェイスを介したインストールの完了

コンテナが実行されている状態で、WordPressWebインターフェイスを介してインストールを完了することができます。

Webブラウザーで、サーバーのドメインに移動します。 ここでexample.comを独自のドメイン名に置き換えることを忘れないでください。

https://example.com

使用する言語を選択します。

続行をクリックすると、メインのセットアップページが表示されます。ここで、サイトの名前とユーザー名を選択する必要があります。 ここでは、(「admin」ではなく)覚えやすいユーザー名と強力なパスワードを選択することをお勧めします。 WordPressが自動的に生成するパスワードを使用することも、独自のパスワードを作成することもできます。

最後に、メールアドレスを入力し、検索エンジンがサイトのインデックスを作成しないようにするかどうかを決定する必要があります。

ページの下部にあるInstallWordPress をクリックすると、ログインプロンプトが表示されます。

ログインすると、WordPress管理ダッシュボードにアクセスできるようになります。

WordPressのインストールが完了したら、SSL証明書が自動的に更新されるようにするための手順を実行できます。

ステップ7—証明書の更新

Let's Encryptの証明書は90日間有効なので、自動更新プロセスを設定して、証明書が失効しないようにする必要があります。 これを行う1つの方法は、cronスケジューリングユーティリティを使用してジョブを作成することです。 この場合、cronジョブを作成して、証明書を更新し、Nginx構成をリロードするスクリプトを定期的に実行します。

まず、ssl_renew.shというスクリプトを開きます。

nano ssl_renew.sh

次のコードをスクリプトに追加して、証明書を更新し、Webサーバー構成を再ロードします。 ここにあるサンプルのユーザー名を、root以外の独自のユーザー名に置き換えることを忘れないでください。

〜/ wordpress / ssl_renew.sh

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

このスクリプトは、最初にdocker-composeバイナリをCOMPOSEという変数に割り当て、--no-ansiオプションを指定します。このオプションはANSI制御なしでdocker-composeコマンドを実行します。文字。 次に、dockerバイナリでも同じことを行います。 最後に、~/wordpressプロジェクトディレクトリに移動し、次のdocker-composeコマンドを実行します。

  • docker-compose run:これにより、certbotコンテナーが起動し、certbotサービス定義で提供されるcommandがオーバーライドされます。 ここでは、certonlyサブコマンドを使用する代わりに、renewサブコマンドを使用しています。これにより、有効期限が近づいている証明書が更新されます。 スクリプトをテストするために、ここに--dry-runオプションを含めました。
  • docker-compose kill :これにより、SIGHUPシグナルwebserverコンテナーに送信され、Nginx構成が再ロードされます。 このプロセスを使用してNginx構成をリロードする方法の詳細については、Dockerを使用した公式のNginxイメージのデプロイに関するこのDockerブログ投稿を参照してください。

次に、 docker system prune を実行して、未使用のコンテナーとイメージをすべて削除します。

編集が終了したら、ファイルを閉じます。 実行可能にする:

chmod +x ssl_renew.sh

次に、 root crontabファイルを開いて、指定した間隔で更新スクリプトを実行します。

sudo crontab -e 

このファイルを初めて編集する場合は、エディターを選択するように求められます。

Outputno crontab for root - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

Choose 1-4 [1]:
...

ファイルの最後に、次の行を追加します。

crontab

...
*/5 * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

これにより、ジョブ間隔が5分ごとに設定されるため、更新要求が意図したとおりに機能したかどうかをテストできます。 また、ジョブからの関連する出力を記録するために、ログファイルcron.logを作成しました。

5分後、cron.logをチェックして、更新要求が成功したかどうかを確認します。

tail -f /var/log/cron.log

更新が成功したことを確認する出力が表示されます。

Output- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

crontabファイルを変更して、1日の間隔を設定できるようになりました。 たとえば、毎日正午にスクリプトを実行するには、ファイルの最後の行を次のように変更します。

crontab

...
0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1

また、ssl_renew.shスクリプトから--dry-runオプションを削除することもできます。

〜/ wordpress / ssl_renew.sh

#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"
DOCKER="/usr/bin/docker"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af

cronジョブは、Let's Encrypt証明書が適格なときに更新することで、証明書が失効しないようにします。 Logrotateユーティリティを使用してログローテーションを設定し、ログファイルをローテーションおよび圧縮することもできます。

結論

このチュートリアルでは、Docker Composeを使用して、NginxWebサーバーでWordPressインストールを作成しました。 このワークフローの一環として、WordPressサイトに関連付けるドメインのTLS/SSL証明書を取得しました。 さらに、cronジョブを作成して、必要に応じてこれらの証明書を更新しました。

サイトのパフォーマンスと冗長性を向上させるための追加の手順として、WordPressアセットの配信とバックアップに関する次の記事を参照できます。

Kubernetesを使用してコンテナ化されたワークフローを探索することに興味がある場合は、以下も確認できます。

  • Helmを使用してKubernetesでMySQLを使用してWordPressを設定する方法。