Skip to content

Instantly share code, notes, and snippets.

@WoZ
Last active May 17, 2024 10:29
Show Gist options
  • Save WoZ/2052f24264742914f1dd9cdc7e64f17e to your computer and use it in GitHub Desktop.
Save WoZ/2052f24264742914f1dd9cdc7e64f17e to your computer and use it in GitHub Desktop.
PHP-FPM with debug mode build instructions on top of docker-php repository

Intro

This tutorial helps to build your own version of the official php docker image with enabled debug options. Additionaly, this tutorial covers the steps to manualy patch php sources and manually rebuild it inside the container based on php official docker image.

Building php docker image with debug enabled

Starting from Dec 2023, building tools used to build official php docker image received support of DOCKER_PHP_ENABLE_DEBUG field. So, now it's pretty easy to build needed php version with --enable-debug flag.

Steps:

  1. Clone docker-library/php repository to docker-library-php folder
$ git clone https://github.com/docker-library/php.git docker-library-php
$ cd docker-library-php
  1. Regenerate Dockerfiles with the latest version of php, but with debug option.
DOCKER_PHP_ENABLE_DEBUG=1 ./apply-templates.sh 8.1
  1. Go to the folder with the specific version and run docker build.
$ cd 8.1/bullseye/fpm/
$ docker build --progress plain -t php:8.1-fpm-debug

Building specific version of php

If you need specific version run clone the repository as was shown above and run the next commands. For example, I'm trying to fetch data for the version 8.1.15.

  1. Run versions.sh
$ ./versions.sh 8.1.15

This command fecthes URLs and checksum of the specific versions of the PHP source code archive and adds the data to versions.json file.

  1. Get the url, ascUrl, and sha256 fields from generated versions.json from the desired version (8.1.15) and put it under 8.1 json section.

The final file will look like

$ git diff versions.json
diff --git a/versions.json b/versions.json
index 1a8641f1..6d9801fa 100644
--- a/versions.json
+++ b/versions.json
@@ -1,8 +1,8 @@
 {
   "8.1": {
-    "ascUrl": "https://www.php.net/distributions/php-8.1.28.tar.xz.asc",
-    "sha256": "95d0b2e9466108fd750dab5c30a09e5c67f5ad2cb3b1ffb3625a038a755ad080",
-    "url": "https://www.php.net/distributions/php-8.1.28.tar.xz",
+    "ascUrl": "https://www.php.net/distributions/php-8.1.15.tar.xz.asc",
+    "sha256": "cd450fb4ee50488c5bf5f08851f514e5a1cac18c9512234d9e16c3a1d35781a6",
+    "url": "https://www.php.net/distributions/php-8.1.15.tar.xz",
     "variants": [
       "bookworm/cli",
       "bookworm/apache",
@@ -19,9 +19,32 @@
       "alpine3.18/fpm",
       "alpine3.18/zts"
     ],
-    "version": "8.1.28"
+    "version": "8.1.15"
   },
   "8.1-rc": null,
+  "8.1.15": {
+    "ascUrl": "https://www.php.net/distributions/php-8.1.15.tar.xz.asc",
+    "sha256": "cd450fb4ee50488c5bf5f08851f514e5a1cac18c9512234d9e16c3a1d35781a6",
+    "url": "https://www.php.net/distributions/php-8.1.15.tar.xz",
+    "variants": [
+      "bookworm/cli",
+      "bookworm/apache",
+      "bookworm/fpm",
+      "bookworm/zts",
+      "bullseye/cli",
+      "bullseye/apache",
+      "bullseye/fpm",
+      "bullseye/zts",
+      "alpine3.19/cli",
+      "alpine3.19/fpm",
+      "alpine3.19/zts",
+      "alpine3.18/cli",
+      "alpine3.18/fpm",
+      "alpine3.18/zts"
+    ],
+    "version": "8.1.15"
+  },
+  "8.1.15-rc": null,
   "8.2": {
     "ascUrl": "https://www.php.net/distributions/php-8.2.19.tar.xz.asc",
     "sha256": "aecd63f3ebea6768997f5c4fccd98acbf897762ed5fc25300e846197a9485c13",
  1. Finally run
DOCKER_PHP_ENABLE_DEBUG=1 ./apply-templates.sh 8.1
  1. Go to the folder with the specific version and run docker build.
$ cd 8.1/bullseye/fpm/
$ docker build --progress plain -t php:8.1.15-fpm-debug .

The way to continiously debug and rebuild from php sources the docker image

First proceed with steps from "Building specific version of php" section, but stop before running docker build.

  1. Make sure you are located in the folder with the Dockerfile
$ cd 8.1/bullseye/fpm
  1. Download 2 files that will be moved to the image during the build phase.
$ wget -O docker-php-manual-build-dependencies https://gist.githubusercontent.com/WoZ/2052f24264742914f1dd9cdc7e64f17e/raw/7abf7178b099ec8b04fcaa8d52bb7d4120ba61bf/docker-php-manual-build-dependencies

$ wget -O docker-php-manual-build-preparations https://gist.githubusercontent.com/WoZ/2052f24264742914f1dd9cdc7e64f17e/raw/7abf7178b099ec8b04fcaa8d52bb7d4120ba61bf/docker-php-manual-build-preparations
  1. Change permissions for these files
$ chmod +x docker-php-manual-build-*
  1. Add instruction to Dockerfile to copy created files to the image.
$ echo "COPY docker-php-manual-build-* /usr/local/bin/" >> Dockerfile
  1. Run docker build
$ docker build --progress plain -t php:8.1.15-fpm-debug .
  1. Run docker container, but use the trick with tail as an exntrypoint instead of php-fpm. This will keep container running and allows you to relaunch php-fpm process without stopping the container.
$ docker run -d --name php-fpm-builder php:8.1.15-fpm-debug tail -f /dev/null
  1. Connect to running docker container and checkout the proper vesrion from the github (or you may download archive instead).
$ docker exec -it php-fpm-builder bash

Inside the container run

# mkdir -p /usr/src/php
# cd /usr/src/php
# git clone -b php-8.1.15 --depth 1 https://github.com/php/php-src.git .
  1. Install dependencies and configure the build.
# docker-php-manual-build-dependencies
# docker-php-manual-build-preparations
  1. Now you may make changes to php sources and rebuild them with the commands
# make -j "$(nproc)"
# make install

You may run it directly from the build folder, skippin make install.

#!/bin/sh
set -eux; \
apt-get update ; \
apt-get install -y --no-install-recommends \
libargon2-dev \
libcurl4-openssl-dev \
libonig-dev \
libreadline-dev \
libsodium-dev \
libsqlite3-dev \
libssl-dev \
libxml2-dev \
zlib1g-dev \
bison \
vim \
git \
; \
mkdir -p /usr/src/php ;
#!/bin/sh
set -eux; \
export CFLAGS="$PHP_CFLAGS" CPPFLAGS="$PHP_CPPFLAGS" LDFLAGS="$PHP_LDFLAGS" ; \
cd /usr/src/php ; \
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" ; \
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)" ; \
./buildconf --force --debug; \
./configure \
--build="$gnuArch" \
--with-config-file-path="$PHP_INI_DIR" \
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
--enable-option-checking=fatal \
--with-mhash \
--with-pic \
--enable-ftp \
--enable-mbstring \
--enable-mysqlnd \
--with-password-argon2 \
--with-sodium=shared \
--with-pdo-sqlite=/usr \
--with-sqlite3=/usr \
--with-curl \
--with-iconv \
--with-openssl \
--with-readline \
--with-zlib \
--disable-phpdbg \
--with-pear \
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
--with-libdir="lib/$debMultiarch" \
--disable-cgi \
--enable-fpm \
--with-fpm-user=www-data \
--with-fpm-group=www-data \
--enable-debug \
;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment