Pulog

Drupal 9の環境をDockerを用いて構築する

Drupal Advent Calendar 2020 - Qiita の8日目です。
ものすごくギリギリになっちゃいました、スミマセン。

DockerでDrupal環境を構築していこうと思います。

Drupalは公式でDockerイメージを公開しているので、それをベースに作っていこうと思います。

Dockerfile

FROM drupal:latest

# Drushインストール
RUN composer global require drush/drush \
  && ln -s /root/.composer/vendor/bin/drush /usr/local/bin/drush \
  && drush --version

# Drupal Consoleインストール
RUN composer require drupal/console \
  && ln -s /opt/drupal/vendor/bin/drupal /usr/local/bin/drupal \
  && drupal --version

# 初回起動時にDrupalをインストールする用のshellを配置
COPY docker-entrypoint.sh /tmp
RUN sed -i 's/\r//g' /tmp/docker-entrypoint.sh
ENTRYPOINT ["/tmp/docker-entrypoint.sh"]
CMD ["apache2-foreground"]

とりあえずDrupalのイメージをベースに drush 及び drupal コマンドを使用できるようにします。
また、コンテナを初めて立ち上げた時のみ起動するシェルスクリプトファイルをコピーする用にしておきます。

docker-compose.yml

version: '3.7'

services:
  mysql:
    image: mariadb
    volumes:
      - data:/var/lib/mysql
      - ./dump:/docker-entrypoint-initdb.d
    environment:
      MYSQL_ROOT_PASSWORD: "password"
      MYSQL_DATABASE: "drupal"
    ports:
      - "3306:3306"

  drupal:
    build: ./
    volumes:
      - ./web/themes:/var/www/html/themes
      - ./web/modules:/var/www/html/modules
      - ./web/sites:/var/www/html/sites
      - ./config:/opt/drupal/config
      - ./composer.json:/opt/drupal/composer.json
      - ./composer.lock:/opt/drupal/composer.lock
    environment:
      PROFILE: "minimal"
    ports:
      - "80:80"
    depends_on:
      - mysql

volumes:
  data: {}

永続化のために各種 volumes の指定をしています。

drupalや各種モジュールのバージョンを保持するために composer.json composer.lock を volumes に含めています。

また、各種 module や theme, sites設定 をGitで管理することを想定してこれらも volumes に含めています。

drupal の environment でプロファイルを指定しています。
ちょうど Drupal Advent Calendarの前日の Drupal9 インストール機能を追いかける | Irologue blog で詳しく紹介してくださっているので、その辺りを見ていただければと思います。

docker-entrypoint.sh

#!/bin/sh

# 初回起動時Drupalインストールを走らせる
if [ ! -d "/tmp/check" ]; then
  mkdir /tmp/check

  mkdir -p /opt/drupal/web/sites/default/files/translations/
  curl https://ftp.drupal.org/files/translations/all/drupal/drupal-${DRUPAL_VERSION}.ja.po \
    -o /opt/drupal/web/sites/default/files/translations/drupal-${DRUPAL_VERSION}.ja.po
  sleep 30s && drush si -y ${PROFILE} \
    --account-name="admin" --account-pass="admin" --account-mail="test@example.com" \
    --db-url="mysql://root:password@mysql:3306/drupal" \
    --site-mail="test@example.com" --site-name="Drupal Test" \
    --locale="ja"
  drush config-set system.site uuid e707291e-7532-46d1-822c-0983cb676f8d
  drush config-set language.entity.ja uuid 0a2ddbab-8662-4d8a-bc0b-e20dd875e041
  drush cim

fi

exec "$@"

最後に、コンテナを立ち上げたタイミングで Drupal のインストールを自動的に行なってくれるようなshellを書いておきます。

Docker で Drupal を立ち上げる記事はいくつかあったのですが、コンテナ立ち上げたタイミングで Drupal のインストールしている記事はなさそうだったので、今回記事にしてみました。

Drupal console のドキュメントを見る限り、drupal コマンドで drupalのインストールをする場合、多言語ファイルを先に web/sites/default/files/translations/ に配置していないと正常にインストールができないっぽいので取得する処理を別途記述しています。

drush コマンドでも Drupal インストールできればdrupal consoleを入れなくても済むのですが……出来なさそうだったので Dockerfile に含めた、といった具合です。

最後に Drupal の configuration management を有効にするために、固定のUUIDをセットしています。

このUUIDはプロジェクトごとに変更すると良いと思います。

このUUIDをセットする処理を省くと、以下のようなエラーが出てしまい、正常に config/ 配下に出力されている 設定用の yaml 郡を取り込めないので、セットする必要があります。

The import failed due for the following reasons:                                                                                                          [error]
Site UUID in source storage does not match the target storage.
(ソースのストレージにあるサイトのUUIDが、対象のストレージに一致しません。)

ソース一式

一応以下で上記の内容を含んだスケルトン的なものを置いているので、ちょっと試したいなと思われましたらDLしていただければ幸いです。

https://git.pu10g.com/root/drupalExample