Docker上でPHP拡張モジュール『GD』を有効化する

この記事ではDocker上でPHP拡張モジュール『GD』を有効化する方法をお伝えします。

# どうしてGDの有効化が必要になったか

LaravelとVueを用いたSPAを勉強したく、『[Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう](https://www.hypertextcandy.com/vue-laravel-tutorial-introduction/)』に取り組んでいました。

[(9)写真投稿API](https://www.hypertextcandy.com/vue-laravel-tutorial-submit-photo/)でテストを実行した際に
`Error: Call to undefined function Illuminate\Http\Testing\imagecreatetruecolor().`
というエラーで行き詰まり、原因を調査したところPHP拡張モジュール『GD』の有効化が必要との情報にたどり着きました。

# 環境

| | version |
|:-:|:--|
| PHP | 7.4.1 |
| Laravel | 6.15.0 |
| Docker for Mac | 19.03.5 |

# GD有効化の方法

DockerファイルにGDの有効化、必要なライブラリのインストールの部分を記載することでGDを有効化できます。
有効化した後、再ビルドすることで正しく動作するようになります。

まずはGDが使えない状態のDockerfileをご紹介します。

```Dockerfile:Dockerfile
FROM php:7.4.1-fpm

COPY install-composer.sh /
RUN apt-get update \
  && apt-get install -y wget git unzip libpq-dev \
  && : 'Install Node.js' \
  &&  curl -sL https://deb.nodesource.com/setup_12.x | bash - \
  && apt-get install -y nodejs \
  && : 'Install PHP Extensions' \
  && docker-php-ext-install -j$(nproc) pdo_pgsql \
  && : 'Install Composer' \
  && chmod 755 /install-composer.sh \
  && /install-composer.sh \
  && mv composer.phar /usr/local/bin/composer

WORKDIR /var/www/html/vuesplash
```

【参考】
[Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう (3) SPA開発環境とVue Router](https://www.hypertextcandy.com/vue-laravel-tutorial-setting-up-spa-project)

これを下記のように変更します。

```dockerfile
:Dockerfile
FROM php:7.4.1-fpm

COPY install-composer.sh /
RUN apt-get update \
  && apt-get install -y wget git unzip libpq-dev libfreetype6-dev libjpeg62-turbo-dev libpng-dev \
  && : 'Install Node.js' \
  && curl -sL https://deb.nodesource.com/setup_12.x | bash - \
  && apt-get install -y nodejs \
  && : 'Install PHP Extensions' \
  && docker-php-ext-install -j$(nproc) pdo_pgsql \
  && docker-php-ext-configure gd --with-freetype --with-jpeg \
  && docker-php-ext-install -j$(nproc) gd \
  && : 'Install Composer' \
  && chmod 755 /install-composer.sh \
  && /install-composer.sh \
  && mv composer.phar /usr/local/bin/composer

WORKDIR /var/www/html/vuesplash
```

変更点は3行です。

---

まずは5行目。

```dockerfile
-  && apt-get install -y wget git unzip libpq-dev \
+  && apt-get install -y wget git unzip libpq-dev libfreetype6-dev libjpeg62-turbo-dev libpng-dev \
```
`libfreetype6-dev`、`libjpeg62-turbo-dev`、`libpng-dev`の3つのライブラリを追加しています。

【参考】
[docs/php at master · docker-library/docs](https://github.com/docker-library/docs/tree/master/php)

---

2点目の変更点は、変更後のファイル11行目に新たに一行挿入しています。

```dockerfile
+  && docker-php-ext-configure gd --with-freetype --with-jpeg \
```

PHP7.4系では`docker-php-ext-configure`の引数が変更されているので注意が必要です。

【参考】
[【PHP】Docker PHP7.4系でgdをインストールしてimagecreatefromjpegを使う](https://uiuifree.com/blog/develop/docker-gd-php-7/)
[docs/php at master · docker-library/docs](https://github.com/docker-library/docs/tree/master/php)

---

最後に変更後のファイルの12行目のように、GDのインストールコマンドを追加して変更完了です。


```dockerfile
+  && docker-php-ext-install -j$(nproc) gd \
```

【参考】
[docs/php at master · docker-library/docs](https://github.com/docker-library/docs/tree/master/php)

# まとめ

Laravelを勉強しているものの、基本的な言語仕様は同じだろうと高をくくっており、PHP自体の構成や拡張モジュールについては全く勉強しておらず、長時間ハマり続けてしまいました…

これを機に基本的な言語仕様や拡張モジュールについても勉強していければと思います。

また、長時間ハマり続けた別の理由として、古い情報がうまくいかない場合が多かったこともあるので、今回の記事のように苦労して解決したことは積極的に記事にしていきたいです。

まだまだPHPもLaravelもDockerも未熟なので、誤りがありましたらご指摘いただけると幸いです。

# 参考
- 教材
    - [Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう](https://www.hypertextcandy.com/vue-laravel-tutorial-introduction/)
- 問題解決の参考サイト
    - [docs/php at master · docker-library/docs](https://github.com/docker-library/docs/tree/master/php)
    - [【PHP】Docker PHP7.4系でgdをインストールしてimagecreatefromjpegを使う](https://uiuifree.com/blog/develop/docker-gd-php-7/)