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

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

著者は、 Write for DOnations プログラムの一環として、国連財団を選択して寄付を受け取りました。

このチュートリアルの元のWordPressバージョンは、 KathleenJuellによって作成されました。

序章

Drupal は、 PHP で記述され、オープンソースの GNU General Public Licenseの下で配布されるコンテンツ管理システム(CMS)です。 世界中の人々や組織がDrupalを使用して、政府のサイト、個人のブログ、企業などに電力を供給しています。 Drupalが他のCMSフレームワークと異なる点は、成長するコミュニティと、安全なプロセス、信頼性の高いパフォーマンス、モジュール性、適応する柔軟性などの一連の機能です。

Drupalでは、 LAMP (Linux、Apache、MySQL、およびPHP)または LEMP (Linux、Nginx、MySQL、およびPHP)スタックをインストールする必要がありますが、個々のコンポーネントのインストールには時間がかかります。タスク。 DockerDockerCompose などのツールを使用して、Drupalのインストールプロセスを簡素化できます。 このチュートリアルでは、Dockerイメージを使用してDockerコンテナー内に個々のコンポーネントをインストールします。 Docker Composeを使用することで、データベース、アプリケーション、およびそれらの間のネットワーク/通信用の複数のコンテナーを定義および管理できます。

このチュートリアルでは、Docker Composeを使用してDrupalをインストールし、コンテナー化を利用してDrupalWebサイトをサーバーにデプロイできるようにします。 MySQL データベース、 Nginx Webサーバー、およびDrupalのコンテナーを実行します。 また、サイトに関連付けたいドメインのLet'sEncryptを使用してTLS/ SSL証明書を取得することにより、インストールを保護します。 最後に、 cronジョブを設定して証明書を更新し、ドメインのセキュリティを維持します。

前提条件

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

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

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

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

まず、drupalという名前のDrupalセットアップ用のプロジェクトディレクトリを作成しましょう。

mkdir drupal 

新しく作成したディレクトリに移動します。

cd drupal

これで、構成ファイル用のディレクトリを作成できます。

mkdir nginx-conf

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

nano nginx-conf/nginx.conf

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

次のコードをファイルに追加します。 your_domainは必ず独自のドメイン名に置き換えてください。

〜/ drupal / nginx-conf / nginx.conf

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

    server_name your_domain www.your_domain;

    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;
    }

    rewrite ^/core/authorize.php/core/authorize.php(.*)$ /core/authorize.php$1;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass drupal: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:これは、サーバー名と、サーバーへのリクエストに使用するサーバーブロックを定義します。 この行のyour_domainは、必ず独自のドメイン名に置き換えてください。
  • index:indexディレクティブは、サーバーへのリクエストを処理するときにインデックスとして使用されるファイルを定義します。 ここでデフォルトの優先順位を変更し、index.phpindex.htmlの前に移動して、可能な場合はindex.phpというファイルをNginxが優先するようにしました。
  • root:ルートディレクティブは、サーバーへのリクエストのルートディレクトリに名前を付けます。 このディレクトリ/var/www/htmlは、Drupal Dockerfileの指示により、ビルド時にマウントポイントとして作成されます。 これらのDockerfile命令は、Drupalリリースのファイルがこのボリュームにマウントされていることも確認します。
  • rewrite:指定された正規表現(^/core/authorize.php/core/authorize.php(.*)$)が要求URIと一致する場合、URIは置換文字列(/core/authorize.php$1)で指定されたとおりに変更されます。

ロケーションブロック:

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

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

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

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

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

Drupalアプリケーションには、サイトに関連する情報を保存するためのデータベース(MySQL、PostgresSQLなど)が必要です。 Drupalコンテナーは、データベース(MySQL)コンテナーにアクセスするために、実行時に特定の環境変数にアクセスする必要があります。 これらの変数にはデータベースのクレデンシャルなどの機密情報が含まれているため、Docker Composeファイル(コンテナの実行方法に関する情報を含むメインファイル)で直接公開することはできません。

.envファイルに機密値を設定し、その循環を制限することを常にお勧めします。 これにより、これらの値がプロジェクトリポジトリにコピーされ、公開されるのを防ぐことができます。

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

nano .env

次の変数を.envファイルに追加し、強調表示されたセクションを使用する資格情報に置き換えます。

〜/ drupal / .env

MYSQL_ROOT_PASSWORD=root_password
MYSQL_DATABASE=drupal
MYSQL_USER=drupal_database_user
MYSQL_PASSWORD=drupal_database_password

これで、MySQLルート管理者アカウントのパスワードと、アプリケーションデータベースの優先ユーザー名とパスワードが追加されました。

.envファイルには機密情報が含まれているため、GitリポジトリとDockerに追加されないように、プロジェクトの.gitignoreファイルと.dockerignoreファイルに含めることを常にお勧めします画像。

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

git init

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

nano .gitignore

以下を追加します。

〜/ drupal / .gitignore

.env

ファイルを保存して終了します。

同様に、.dockerignoreファイルを開きます。

nano .dockerignore

次に、以下を追加します。

〜/ drupal / .dockerignore

.env
.git

ファイルを保存して終了します。

クレデンシャルを環境変数として保護するための対策を講じたので、docker-compose.ymlファイルでサービスを定義する次のステップに進みましょう。

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

Docker Composeは、マルチコンテナーDockerアプリケーションを定義および実行するためのツールです。 YAMLファイルを定義して、アプリケーションのサービスを構成します。 DockerComposeのserviceは実行中のコンテナーであり、Composeを使用すると、これらのサービスを共有ボリュームおよびネットワークとリンクできます。

Drupalアプリケーション、データベース、およびWebサーバー用にさまざまなコンテナーを作成します。 これらに加えて、Webサーバーの証明書を取得するためにCertbotを実行するコンテナーも作成します。

docker-compose.ymlファイルを作成します。

nano docker-compose.yml

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

〜/ drupal / docker-compose.yml

version: "3"

services:
  mysql:
    image: mysql:8.0
    container_name: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: unless-stopped
    env_file: .env
    volumes:
      - db-data:/var/lib/mysql
    networks:
      - internal

mysqlサービスのすべての構成オプションを使用してこれらを1つずつ見ていきましょう。

  • image:コンテナの作成に使用/プルされるイメージを指定します。 今後の競合を避けるために、latestタグを除く適切なバージョンタグを使用してイメージを使用することを常にお勧めします。 DockerのドキュメントからDockerfileのベストプラクティスの詳細をお読みください。
  • container_name:コンテナの名前を定義します。
  • command:これは、画像のデフォルトコマンド(CMD命令)を上書きするために使用されます。 MySQLはさまざまな認証プラグインをサポートしていますが、mysql_native_passwordは従来の認証方法です。 PHP、つまりDrupalは新しいMySQL認証をサポートしないため、デフォルトの認証メカニズムとして--default-authentication-plugin=mysql_native_passwordを設定する必要があります。
  • restart:これはコンテナの再起動ポリシーを定義するために使用されます。 unless-stoppedポリシーは、手動で停止しない限り、コンテナーを再起動します。
  • env_file:ファイルから環境変数を追加します。 この場合、前の手順で定義した.envファイルから環境変数を読み取ります。
  • volumes:これは、サービスのサブオプションとして指定されたホストパスまたは名前付きボリュームをマウントします。 db-dataという名前のボリュームをコンテナの/var/lib/mysqlディレクトリにマウントします。MySQLはデフォルトでデータファイルを書き込みます。
  • networks:これは、アプリケーションサービスが参加するinternalネットワークを定義します。 ファイルの最後にネットワークを定義します。

mysqlサービス定義を定義したので、ファイルの最後にdrupalアプリケーションサービスの定義を追加しましょう。

〜/ drupal / docker-compose.yml

...
  drupal:
    image: drupal:8.7.8-fpm-alpine
    container_name: drupal
    depends_on:
      - mysql
    restart: unless-stopped
    networks:
      - internal
      - external
    volumes:
      - drupal-data:/var/www/html

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

  • image:ここでは、 8.7.8-fpm-alpineDrupalイメージを使用しています。 この画像には、NginxWebサーバーがPHP処理を処理するために必要なphp-fpmプロセッサが搭載されています。 さらに、 AlpineLinuxプロジェクトから派生したalpineイメージを使用しています。これにより、イメージ全体のサイズが縮小され、Dockerfileのベストプラクティスで推奨されます。 Drupalにはさらに多くのバージョンのイメージがあるので、Dockerhubでそれらをチェックしてください。
  • depends_on:これはサービス間の依存関係を表すために使用されます。 mysqlサービスをdrupalコンテナーへの依存関係として定義すると、drupalコンテナーがmysqlコンテナーの後に作成され、アプリケーションを開始できるようになります。スムーズに。
  • networks:ここでは、このコンテナをinternalネットワークとともにexternalネットワークに追加しました。 これにより、mysqlサービスにdrupalコンテナからinternalネットワーク経由でのみアクセスできるようになり、このコンテナはexternalネットワーク経由で他のコンテナにアクセスできるようになります。 。
  • volumesdrupal-dataという名前のボリュームをDrupalイメージによって作成された/var/www/htmlマウントポイントにマウントしています。 このように名前付きボリュームを使用すると、アプリケーションコードを他のコンテナと共有できます。

次に、drupalサービス定義の後にNginxサービス定義を追加しましょう。

〜/ drupal / docker-compose.yml

...
  webserver:
    image: nginx:1.17.4-alpine
    container_name: webserver
    depends_on:
      - drupal
    restart: unless-stopped
    ports:
      - 80:80
    volumes:
      - drupal-data:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - external

繰り返しになりますが、コンテナーに名前を付け、開始順にDrupalコンテナーに依存するようにしています。 また、アルパインイメージ( 1.17.4-alpine Nginxイメージ)も使用しています。

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

  • ports:これにより、ポート80が公開され、手順1でnginx.confファイルで定義した構成オプションが有効になります。
  • volumes:ここでは、名前付きボリュームとホストパスの両方を定義しています。
    • drupal-data:/var/www/html:これにより、Drupalアプリケーションコードが/var/www/htmlディレクトリにマウントされます。このディレクトリは、Nginxサーバーブロックのルートとして設定されています。
    • ./nginx-conf:/etc/nginx/conf.d:これにより、ホスト上のNginx構成ディレクトリがコンテナ上の関連するディレクトリにマウントされ、ホスト上のファイルに加えた変更がコンテナに反映されるようになります。
    • certbot-etc:/etc/letsencrypt:これにより、ドメインに関連するLet'sEncryptの証明書とキーがコンテナの適切なディレクトリにマウントされます。
    • networksexternalネットワークは、このコンテナがdrupalコンテナと通信できるようにするためだけに定義されており、mysqlコンテナとは通信できません。

最後に、certbotサービスの最後のサービス定義を追加します。 sammy@your_domainyour_domainは、必ず自分のメールアドレスとドメイン名に置き換えてください。

〜/ drupal / docker-compose.yml

...
  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - drupal-data:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain

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

また、depends_onを使用して、webserverサービスの実行後にcertbotコンテナーが開始されるようにしました。

このコンテナはネットワークを介してどのサービスとも通信しないため、ここではnetworksを指定していません。 名前付きボリュームを使用してマウントしたドメイン証明書とキーを追加するだけです。

コンテナのデフォルトのcertbotコマンドで実行するサブコマンドを指定するcommandオプションも含まれています。 Certbotクライアントは、証明書を取得およびインストールするためのプラグインをサポートしています。 webrootプラグインを使用して、コマンドラインにcertonly--webrootを含めて証明書を取得しています。 プラグインと追加コマンドの詳細については、公式のCertbotドキュメントをご覧ください。

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

〜/ drupal / docker-compose.yml

...
networks:
  external:
    driver: bridge
  internal:
    driver: bridge

volumes:
  drupal-data:
  db-data:
  certbot-etc:

トップレベルのnetworksキーを使用すると、作成するネットワークを指定できます。 networksは、すべてのポートのサービス/コンテナーが同じDockerデーモンホスト上にあるため、それらの間の通信を許可します。 webserverdrupalmysqlサービスの通信を保護するために、internalexternalの2つのネットワークを定義しました。

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

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

〜/ drupal / docker-compose.yml

version: "3"

services:
  mysql:
    image: mysql:8.0
    container_name: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: unless-stopped
    env_file: .env
    volumes:
      - db-data:/var/lib/mysql
    networks:
      - internal
  
  drupal:
    image: drupal:8.7.8-fpm-alpine
    container_name: drupal
    depends_on:
      - mysql
    restart: unless-stopped
    networks:
      - internal
      - external
    volumes:
      - drupal-data:/var/www/html
  
  webserver:
    image: nginx:1.17.4-alpine
    container_name: webserver
    depends_on:
      - drupal
    restart: unless-stopped
    ports:
      - 80:80
    volumes:
      - drupal-data:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - external
  
  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - drupal-data:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain

networks:
  external:
    driver: bridge
  internal:
    driver: bridge

volumes:
  drupal-data:
  db-data:
  certbot-etc:

サービスの定義は完了です。 次に、コンテナを起動して、証明書リクエストをテストしましょう。

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

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

コンテナをバックグラウンドで実行するには、docker-compose upコマンドを-dフラグとともに使用します。

docker-compose up -d

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

Output...
Creating mysql     ... done
Creating drupal    ... done
Creating webserver ... done
Creating certbot   ... done

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

docker-compose ps

mysqldrupal、およびwebserverサービスのStateUpで、certbot0ステータスメッセージで終了します。

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

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

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 Oct  5 09:15 .
drwxr-xr-x    9 root     root          4096 Oct  5 09:15 ..
-rw-r--r--    1 root     root           740 Oct  5 09:15 README
drwxr-xr-x    2 root     root          4096 Oct  5 09:15 your_domain

すべてが正常に実行されたので、certbotサービス定義を編集して、--stagingフラグを削除できます。

docker-compose.ymlファイルを開き、certbotサービス定義に移動し、コマンドオプションの--stagingフラグを--force-renewalフラグに置き換えます。これによりCertbotに通知されます。既存の証明書と同じドメインを持つ新しい証明書を要求すること。 更新されたcertbot定義は次のようになります。

〜/ drupal / docker-compose.yml

...
  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - drupal-data:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
...

certbotコンテナを再作成するには、docker-compose upを再度実行する必要があります。 また、--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 your_domain
certbot      | http-01 challenge for www.your_domain
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/your_domain/fullchain.pem
certbot      |    Your key file has been saved at:
certbot      |    /etc/letsencrypt/live/your_domain/privkey.pem
certbot      |    Your cert will expire on 2020-01-03. 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証明書をインストールした後、すべてのHTTPリクエストをHTTPSにリダイレクトする必要があります。 また、SSL証明書とキーの場所を指定し、セキュリティパラメータとヘッダーを追加する必要があります。

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

docker-compose stop webserver

これにより、次の出力が得られます。

OutputStopping webserver ... done

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

rm nginx-conf/nginx.conf

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

nano nginx-conf/nginx.conf

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

〜/ drupal / nginx-conf / nginx.conf

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

    server_name your_domain www.your_domain;

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

    location / {
        rewrite ^ https://$host$request_uri? permanent;
    }
}
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name your_domain www.your_domain;

    index index.php index.html index.htm;

    root /var/www/html;

    server_tokens off;

    ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;

    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;

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

    rewrite ^/core/authorize.php/core/authorize.php(.*)$ /core/authorize.php$1;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass drupal: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更新要求用のwebrootプラグインを指定します。 また、ルートディレクトリへのHTTPリクエストをHTTPSに転送するrewriteディレクティブも含まれています。

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

これらのブロックはSSLを有効にします。これは、SSL証明書とキーの場所、および推奨されるヘッダーが含まれているためです。 これらのヘッダーにより、 SSLLabsおよびSecurityHeadersサーバーテストサイトでAの評価を取得できます。

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

更新されたNginx構成ファイルを保存して閉じます。

webserverコンテナを再作成する前に、SSL証明書を有効にしているため、443ポートマッピングをwebserverサービス定義に追加する必要があります。

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

nano docker-compose.yml

webserverサービス定義に次の変更を加えます。

〜/ drupal / docker-compose.yml

...
  webserver:
    image: nginx:1.17.4-alpine
    container_name: webserver
    depends_on:
      - drupal
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - drupal-data:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - external
...

SSL証明書を有効にすると、docker-compose.ymlは次のようになります。

〜/ drupal / docker-compose.yml

version: "3"

services:
  mysql:
    image: mysql:8.0
    container_name: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: unless-stopped
    env_file: .env
    volumes:
      - db-data:/var/lib/mysql
    networks:
      - internal
  
  drupal:
    image: drupal:8.7.8-fpm-alpine
    container_name: drupal
    depends_on:
      - mysql
    restart: unless-stopped
    networks:
      - internal
      - external
    volumes:
      - drupal-data:/var/www/html
  
  webserver:
    image: nginx:1.17.4-alpine
    container_name: webserver
    depends_on:
      - drupal
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - drupal-data:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - external
  
  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - drupal-data:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain

networks:
  external:
    driver: bridge
  internal:
    driver: bridge

volumes:
  drupal-data:
  db-data:
  certbot-etc:

ファイルを保存して閉じます。 更新された構成でwebserverサービスを再作成しましょう。

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

これにより、次の出力が得られます。

OutputRecreating webserver ... done

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

docker-compose ps

mysqldrupal、およびwebserverサービスはUpとして表示され、certbot0で終了します。 ] ステータスメッセージ:

Output  Name                 Command               State           Ports
--------------------------------------------------------------------------
certbot     certbot certonly --webroot ...   Exit 0
drupal      docker-php-entrypoint php-fpm    Up       9000/tcp
mysql       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

これで、すべてのサービスが実行され、Webインターフェイスを介してDrupalのインストールを進めることができます。

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

DrupalのWebインターフェイスからインストールを完了しましょう。

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

https://your_domain

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

保存して続行をクリックします。 インストールプロファイルページに移動します。 Drupalには複数のプロファイルがあるため、標準プロファイルを選択し、保存して続行をクリックします。

プロファイルを選択したら、データベース構成ページに進みます。 データベースタイプをMySQL、MariaDB、Percona Server、または同等のとして選択し、データベース名ユーザー名、およびパスワードの値を入力します手順2の.envファイルでそれぞれ定義されたMYSQL_DATABASEMYSQL_USER、およびMYSQL_PASSWORDに対応する値から。 詳細オプションをクリックし、Hostの値をmysqlサービスコンテナの名前に設定します。 [保存して続行]をクリックします。

データベースを構成した後、Drupalのデフォルトのモジュールとテーマのインストールを開始します。

サイトがインストールされると、サイト名、電子メール、ユーザー名、パスワード、および地域設定を構成するためのDrupalサイトセットアップページが表示されます。 情報を入力し、保存して続行をクリックします。

保存して続行をクリックすると、 Drupalへようこそページが表示され、Drupalサイトが正常に稼働していることが示されます。

Drupalのインストールが完了したので、SSL証明書が自動的に更新されることを確認する必要があります。

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

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

ssl_renew.shファイルを作成して、証明書を更新しましょう。

nano ssl_renew.sh

次のコードを追加します。 ディレクトリ名をroot以外のユーザーに置き換えることを忘れないでください。

〜/ drupal / ssl_renew.sh

#!/bin/bash

cd /home/sammy/drupal/
/usr/local/bin/docker-compose -f docker-compose.yml run certbot renew --dry-run && \
/usr/local/bin/docker-compose -f docker-compose.yml kill -s SIGHUP webserver

このスクリプトは~/drupalプロジェクトディレクトリに移動し、次のdocker-composeコマンドを実行します。

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

次のコマンドを実行して、ファイルを閉じて実行可能にします。

sudo 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
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

Choose 1-4 [1]:
...

ファイルの最後に次の行を追加し、sammyを自分のユーザー名に置き換えます。

crontab

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

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

5分後、tailコマンドを使用して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/your_domain/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

CTRL+Cを押して、tailプロセスを終了します。

これで、crontabファイルを変更して、週の2日ごとの午前2時にスクリプトを実行できるようになりました。 crontabの最終行を次のように変更します。

crontab

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

終了してファイルを保存します。

それでは、ssl_renew.shスクリプトから--dry-runオプションを削除しましょう。 まず、それを開きます:

nano ssl_renew.sh

次に、内容を次のように変更します。

〜/ drupal / ssl_renew.sh

#!/bin/bash

cd /home/sammy/drupal/
/usr/local/bin/docker-compose -f docker-compose.yml run certbot renew && \
/usr/local/bin/docker-compose -f docker-compose.yml kill -s SIGHUP webserver

cronジョブは、SSL証明書が適格になったときに更新することで、SSL証明書の有効期限を処理します。

結論

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

Dockerについて詳しく知りたい場合は、Dockerトピックページをご覧ください。