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
beforedocker-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/*;