Making PHP-GD work in Docker

May 25
Making PHP-GD work in Docker

After having myself issues with the php-gd extension in some Docker images, and seeing that many answers around the web tend to be wrong or inaccurate, I decided to compile a guide for troubleshooting the functionality of this extension in community-based images of PHP 7+.

For demonstrative purposes, I am using the php:8.1-fpm base image in this guide, and I'm trying to enable JPEG support in PHP

Possible problems

1) php-gd was enabled, but PHP throws a Call to undefined function ... imagecreatefromjpeg()

2) php-gd was enabled with JPEG support but PHP throws a Call to undefined function ... imagecreatefromjpeg()

3) php-gd was installed, but it was not enabled in php

Healthchecks

1) Make sure that that the php-gd in enabled in php

 php -r "echo (extension_loaded('gd') ? 'loaded' : 'not loaded') . PHP_EOL;"
 php -r "echo (function_exists('gd_info') ? 'ok' : 'not ok') . PHP_EOL;"

If the extension is not loaded in PHP, you will have to enable it.

2) Have a look at the individual image format support.

root@afc11f39eac2:/usr/src/app# php -r "var_dump(gd_info());"
array(14) {
  ["GD Version"]=>
  string(26) "bundled (2.1.0 compatible)"
  ["FreeType Support"]=>
  bool(false)
  ["GIF Read Support"]=>
  bool(true)
  ["GIF Create Support"]=>
  bool(true)
  ["JPEG Support"]=>
  bool(true)
  ["PNG Support"]=>
  bool(true)
  ["WBMP Support"]=>
  bool(true)
  ["XPM Support"]=>
  bool(false)
  ["XBM Support"]=>
  bool(true)
  ["WebP Support"]=>
  bool(false)
  ["BMP Support"]=>
  bool(true)
  ["AVIF Support"]=>
  bool(false)
  ["TGA Read Support"]=>
  bool(true)
  ["JIS-mapped Japanese Font Support"]=>
  bool(false)
}

If JPEG Support key is missing or set to false, it's a problem. If it was configured with JPEG support, it might indicate that the options passed on the configuration part were wrong, or the path to the library is not correct

In order to find the exact path of the JPEG library, use

root@afc12f39eac4:/# find / -type f -name *lib*jpeg*.so* 2> /dev/null
/usr/lib/x86_64-linux-gnu/libjpeg.so.62.3.0

So, in my case it's in /usr/lib/x86_64-linux-gnu, instead of /usr/lib as indicated in multiple answers on the web. Note the path as it will be used later in the Dockerfile

Setting up the Dockerfile

Before diving into the Dockerfile, I want to point out a few important things:

  • run docker-php-ext-configure gd before docker-php-ext-install gd
  • before docker-php-ext-configure gd, install the required OS packages (libgd-dev libfreetype6-dev libjpeg62-turbo-dev libjpeg-dev)
  • when configuring GD, use the correct path in the --with-jpeg flag as indicated earlier
FROM php:8.1-fpm
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        libz-dev \
        libpq-dev \
        libssl-dev \
        libzip-dev \
        libxml2-dev \
        libxml2 \
        libgd-dev libfreetype6-dev libjpeg62-turbo-dev libpng-dev libjpeg-dev jpegoptim libwebp-dev optipng pngquant gifsicle \
        libmcrypt-dev \
        libcurl4-openssl-dev \
        libonig-dev \
        curl \
        unzip \
        zip \
        ca-certificates curl gnupg \
    && apt-get clean \
    && docker-php-ext-configure gd \
          --with-freetype=/usr/include/ \
          --with-jpeg=/usr/lib/x86_64-linux-gnu \
          --with-webp=/usr/lib/x86_64-linux-gnu \
    && docker-php-ext-install \
        gd \
        exif \
        xml \
        curl \
        opcache \
        intl \
        pdo_mysql \
        pdo \
        pcntl \
        zip \
        intl \
        mysqli \
        mbstring \
    && docker-php-ext-enable gd \
    && rm -rf /var/lib/apt/lists/*;

Next Post Previous Post