From 5958c2c5d6530911c8e97b68360f1b4d285aae1c Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Fri, 3 Oct 2025 16:28:48 -0500 Subject: [PATCH 01/16] rootless php --- .github/workflows/docker.yml | 71 +++++++++++++++++++++ Dockerfile | 78 +++++++++++++++++++++++- rootfs/etc/nginx/conf.d/default.conf.tpl | 4 +- rootfs/usr/bin/clevyr-build | 5 +- rootfs/usr/bin/s6-svscan-rootless | 25 ++++++++ 5 files changed, 177 insertions(+), 6 deletions(-) create mode 100755 rootfs/usr/bin/s6-svscan-rootless diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 378a569..9743e98 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -40,6 +40,22 @@ jobs: # {{major}}-base type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-base,value=${{ matrix.php_version }}.0 + - name: Docker meta (base-rootless) + id: meta-base-rootless + uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 + with: + images: | + clevyr/php + ghcr.io/clevyr/php + flavor: latest=false + tags: | + # {{major}}.{{minor}}-composer{{major}}-base-rootless + type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }}-base,value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-base-rootless + type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},suffix=-base-rootless,value=${{ matrix.php_version }}.0 + # {{major}}-base-rootless + type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-base-rootless,value=${{ matrix.php_version }}.0 + - name: Docker meta (onbuild) id: meta-onbuild uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 @@ -66,6 +82,30 @@ jobs: # {{major}} type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},value=${{ matrix.php_version }}.0 + - name: Docker meta (onbuild-rootless) + id: meta-onbuild-rootless + uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 + with: + images: | + clevyr/php + ghcr.io/clevyr/php + flavor: latest=false + tags: | + # {{major}}.{{minor}}-composer{{major}}-onbuild-rootless + type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }}-onbuild-rootless,value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-composer{{major}} + type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }},value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-onbuild-rootless + type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},suffix=-onbuild-rootless,value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}} + type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},value=${{ matrix.php_version }}.0 + # {{major}}-composer{{major}} + type=semver,enable=${{ (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-composer${{ matrix.composer_version }},value=${{ matrix.php_version }}.0 + # {{major}}-onbuild-rootless + type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-onbuild-rootless,value=${{ matrix.php_version }}.0 + # {{major}} + type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},value=${{ matrix.php_version }}.0 + - name: Set up QEMU uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 @@ -121,6 +161,22 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max + - name: Build and Push (base-rootless) + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + pull: true + push: ${{ github.ref_name == 'main' }} + platforms: ${{ matrix.platforms }} + tags: ${{ steps.meta-base-rootless.outputs.tags }} + labels: ${{ steps.meta-base-rootless.outputs.labels }} + build-args: | + COMPOSER_VERSION=${{ matrix.composer_version }} + PHP_VERSION=${{ matrix.php_version }} + target: base-rootless + cache-from: type=gha + cache-to: type=gha,mode=max + - name: Build and Push (onbuild) uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: @@ -135,3 +191,18 @@ jobs: target: onbuild cache-from: type=gha cache-to: type=gha,mode=max + + - name: Build and Push (onbuild-rootless) + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + push: ${{ github.ref_name == 'main' }} + platforms: ${{ matrix.platforms }} + tags: ${{ steps.meta-onbuild-rootless.outputs.tags }} + labels: ${{ steps.meta-onbuild-rootless.outputs.labels }} + build-args: | + COMPOSER_VERSION=${{ matrix.composer_version }} + PHP_VERSION=${{ matrix.php_version }} + target: onbuild-rootless + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile index b65f360..b5c863e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,6 @@ ARG ALPINE_VERSION FROM composer:$COMPOSER_VERSION AS local-composer FROM php:$PHP_VERSION-fpm-alpine$ALPINE_VERSION AS base -WORKDIR /app COPY --from=mlocati/php-extension-installer:2.10.6 /usr/bin/install-php-extensions /usr/bin/ @@ -36,7 +35,7 @@ RUN < /etc/nginx/conf.d/default.conf + NGINX_EXPIRES="${NGINX_EXPIRES:-7d}" \ + NGINX_PORT="${NGINX_PORT:-80}" +envsubst '$NGINX_ROOT $NGINX_EXPIRES $NGINX_PORT' < /etc/nginx/conf.d/default.conf.tpl > /etc/nginx/conf.d/default.conf log 'Removing all tmp files' rm -rf /tmp/* diff --git a/rootfs/usr/bin/s6-svscan-rootless b/rootfs/usr/bin/s6-svscan-rootless new file mode 100755 index 0000000..f68e10b --- /dev/null +++ b/rootfs/usr/bin/s6-svscan-rootless @@ -0,0 +1,25 @@ +#!/bin/sh + +set -euo pipefail + +# Wrapper to run s6-svscan from a writable directory +# s6-svscan creates .s6-svscan in the service directory, so we need to copy services to /tmp + +# See https://skarnet.org/software/s6/scandir.html + +SERVICE_DIR="$1" + +if [ -z "$SERVICE_DIR" ]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +# Create a unique directory in /tmp for our services +TEMP_SERVICE_DIR="/tmp/s6-services-$$" +mkdir -p "$TEMP_SERVICE_DIR" + +# Copy the service directory contents to /tmp +cp -r "$SERVICE_DIR"/* "$TEMP_SERVICE_DIR/" 2>/dev/null || cp -r "$SERVICE_DIR"/. "$TEMP_SERVICE_DIR/" + +# Run s6-svscan against the copied services +exec s6-svscan "$TEMP_SERVICE_DIR" From f1d2cbbc0c0f31a6a9199f7abc03bbe74844d10c Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Thu, 16 Apr 2026 20:56:48 -0500 Subject: [PATCH 02/16] strip rootful targets, nginx, and php-fpm in favor of roadrunner --- Dockerfile | 121 +---------------------- README.md | 21 +--- rootfs/entrypoint | 6 -- rootfs/etc/nginx/conf.d/0-gzip.conf | 3 - rootfs/etc/nginx/conf.d/default.conf.tpl | 49 --------- rootfs/etc/services.d/nginx/run | 3 - rootfs/etc/services.d/php-fpm/run | 3 - rootfs/health-check | 17 +--- rootfs/usr/bin/clevyr-build | 7 -- rootfs/usr/bin/clevyr-php-pre-stop | 5 - rootfs/usr/bin/php-fpm-status | 15 --- 11 files changed, 9 insertions(+), 241 deletions(-) delete mode 100755 rootfs/entrypoint delete mode 100644 rootfs/etc/nginx/conf.d/0-gzip.conf delete mode 100644 rootfs/etc/nginx/conf.d/default.conf.tpl delete mode 100755 rootfs/etc/services.d/nginx/run delete mode 100755 rootfs/etc/services.d/php-fpm/run delete mode 100755 rootfs/usr/bin/clevyr-php-pre-stop delete mode 100755 rootfs/usr/bin/php-fpm-status diff --git a/Dockerfile b/Dockerfile index b5c863e..9a4296b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,25 +6,15 @@ ARG ALPINE_VERSION FROM composer:$COMPOSER_VERSION AS local-composer -FROM php:$PHP_VERSION-fpm-alpine$ALPINE_VERSION AS base +FROM php:$PHP_VERSION-cli-alpine$ALPINE_VERSION AS base COPY --from=mlocati/php-extension-installer:2.10.6 /usr/bin/install-php-extensions /usr/bin/ RUN </dev/null +wget -qO /dev/null "http://${HEALTH_CHECK_HOST}:${HEALTH_CHECK_PORT}/health?plugin=http" diff --git a/rootfs/usr/bin/clevyr-build b/rootfs/usr/bin/clevyr-build index b0a8c12..95d51b0 100755 --- a/rootfs/usr/bin/clevyr-build +++ b/rootfs/usr/bin/clevyr-build @@ -61,12 +61,5 @@ fi log "Beginning install: ${INSTALL[*]}" install-php-extensions "${INSTALL[@]}" -# Template nginx config -log 'Templating nginx config' -export NGINX_ROOT="${NGINX_ROOT:-/app/public}" \ - NGINX_EXPIRES="${NGINX_EXPIRES:-7d}" \ - NGINX_PORT="${NGINX_PORT:-80}" -envsubst '$NGINX_ROOT $NGINX_EXPIRES $NGINX_PORT' < /etc/nginx/conf.d/default.conf.tpl > /etc/nginx/conf.d/default.conf - log 'Removing all tmp files' rm -rf /tmp/* diff --git a/rootfs/usr/bin/clevyr-php-pre-stop b/rootfs/usr/bin/clevyr-php-pre-stop deleted file mode 100755 index 3fc49c7..0000000 --- a/rootfs/usr/bin/clevyr-php-pre-stop +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -while [[ "$(php-fpm-status active_processes)" -gt 1 ]]; do - sleep 3; -done diff --git a/rootfs/usr/bin/php-fpm-status b/rootfs/usr/bin/php-fpm-status deleted file mode 100755 index 85be3a0..0000000 --- a/rootfs/usr/bin/php-fpm-status +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -set -e - -query='fromjson? | with_entries(.key |= gsub(" "; "_"))' -if [ -n "${1:-}" ]; then - query="$query | .[\$key]" -fi - -SCRIPT_NAME=/status \ - SCRIPT_FILENAME=/status \ - REQUEST_METHOD=GET \ - QUERY_STRING=json \ - cgi-fcgi -bind -connect 127.0.0.1:9000 \ - | jq -Rr --arg key "${1:-}" "$query" From e6918e2ede355f555cee6f9be36ed034b901c197 Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Thu, 16 Apr 2026 20:59:37 -0500 Subject: [PATCH 03/16] ci: make only rootless images --- .github/workflows/docker.yml | 79 ++---------------------------------- 1 file changed, 3 insertions(+), 76 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9743e98..cc62735 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -40,22 +40,6 @@ jobs: # {{major}}-base type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-base,value=${{ matrix.php_version }}.0 - - name: Docker meta (base-rootless) - id: meta-base-rootless - uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 - with: - images: | - clevyr/php - ghcr.io/clevyr/php - flavor: latest=false - tags: | - # {{major}}.{{minor}}-composer{{major}}-base-rootless - type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }}-base,value=${{ matrix.php_version }}.0 - # {{major}}.{{minor}}-base-rootless - type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},suffix=-base-rootless,value=${{ matrix.php_version }}.0 - # {{major}}-base-rootless - type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-base-rootless,value=${{ matrix.php_version }}.0 - - name: Docker meta (onbuild) id: meta-onbuild uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 @@ -82,30 +66,6 @@ jobs: # {{major}} type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},value=${{ matrix.php_version }}.0 - - name: Docker meta (onbuild-rootless) - id: meta-onbuild-rootless - uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 - with: - images: | - clevyr/php - ghcr.io/clevyr/php - flavor: latest=false - tags: | - # {{major}}.{{minor}}-composer{{major}}-onbuild-rootless - type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }}-onbuild-rootless,value=${{ matrix.php_version }}.0 - # {{major}}.{{minor}}-composer{{major}} - type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }},value=${{ matrix.php_version }}.0 - # {{major}}.{{minor}}-onbuild-rootless - type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},suffix=-onbuild-rootless,value=${{ matrix.php_version }}.0 - # {{major}}.{{minor}} - type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},value=${{ matrix.php_version }}.0 - # {{major}}-composer{{major}} - type=semver,enable=${{ (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-composer${{ matrix.composer_version }},value=${{ matrix.php_version }}.0 - # {{major}}-onbuild-rootless - type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-onbuild-rootless,value=${{ matrix.php_version }}.0 - # {{major}} - type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},value=${{ matrix.php_version }}.0 - - name: Set up QEMU uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 @@ -138,12 +98,10 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max - - name: Test nginx config - run: docker run --rm -i "$TEST_TAG" nginx -t - - name: Test php-fpm config - run: docker run --rm -i "$TEST_TAG" php-fpm -tt + - name: Test RoadRunner + run: docker run --rm -i "$TEST_TAG" rr --version - name: Test commands exist - run: docker run --rm -i "$TEST_TAG" which composer install-php-extensions clevyr-build + run: docker run --rm -i "$TEST_TAG" which composer install-php-extensions clevyr-build rr - name: Build and Push (base) uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 @@ -161,22 +119,6 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max - - name: Build and Push (base-rootless) - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: . - pull: true - push: ${{ github.ref_name == 'main' }} - platforms: ${{ matrix.platforms }} - tags: ${{ steps.meta-base-rootless.outputs.tags }} - labels: ${{ steps.meta-base-rootless.outputs.labels }} - build-args: | - COMPOSER_VERSION=${{ matrix.composer_version }} - PHP_VERSION=${{ matrix.php_version }} - target: base-rootless - cache-from: type=gha - cache-to: type=gha,mode=max - - name: Build and Push (onbuild) uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: @@ -191,18 +133,3 @@ jobs: target: onbuild cache-from: type=gha cache-to: type=gha,mode=max - - - name: Build and Push (onbuild-rootless) - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: . - push: ${{ github.ref_name == 'main' }} - platforms: ${{ matrix.platforms }} - tags: ${{ steps.meta-onbuild-rootless.outputs.tags }} - labels: ${{ steps.meta-onbuild-rootless.outputs.labels }} - build-args: | - COMPOSER_VERSION=${{ matrix.composer_version }} - PHP_VERSION=${{ matrix.php_version }} - target: onbuild-rootless - cache-from: type=gha - cache-to: type=gha,mode=max From 516f2c69d0a2b06b7730130193adce3625bc02c5 Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Thu, 16 Apr 2026 21:14:57 -0500 Subject: [PATCH 04/16] chore(scripts): be a bit more pedantic --- rootfs/health-check | 2 +- rootfs/usr/bin/clevyr-build | 20 ++++++++++---------- rootfs/usr/bin/s6-svscan-rootless | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/rootfs/health-check b/rootfs/health-check index 4f0fb8a..303b5b4 100755 --- a/rootfs/health-check +++ b/rootfs/health-check @@ -1,6 +1,6 @@ #!/bin/sh -set -e +set -efu HEALTH_CHECK_HOST="${1:-127.0.0.1}" HEALTH_CHECK_PORT="${2:-2114}" diff --git a/rootfs/usr/bin/clevyr-build b/rootfs/usr/bin/clevyr-build index 95d51b0..e4b193a 100755 --- a/rootfs/usr/bin/clevyr-build +++ b/rootfs/usr/bin/clevyr-build @@ -1,34 +1,34 @@ #!/bin/bash -set -ef +set -efuo pipefail log() { printf '%s: %s\n' "$(basename "$0")" "$@" >&2 } -if [ "$INSTALL_MYSQL" = "true" ]; then +if [ "${INSTALL_MYSQL:-}" = "true" ]; then unset INSTALL_MYSQL - export INSTALL="$INSTALL mysqli pdo_mysql" + export INSTALL="${INSTALL:-} mysqli pdo_mysql" fi -if [ "$INSTALL_SQLSRV" = "true" ]; then +if [ "${INSTALL_SQLSRV:-}" = "true" ]; then unset INSTALL_SQLSRV - export INSTALL="$INSTALL sqlsrv pdo_sqlsrv" + export INSTALL="${INSTALL:-} sqlsrv pdo_sqlsrv" fi # Add workaround for xdebug alpha release -if [ "$INSTALL_XDEBUG" == "true" ]; then +if [ "${INSTALL_XDEBUG:-}" = "true" ]; then unset INSTALL_XDEBUG - export INSTALL="$INSTALL xdebug-stable" + export INSTALL="${INSTALL:-} xdebug-stable" fi # Add old dependency args to new variable -INSTALL=( $INSTALL "$@" ) +INSTALL=( ${INSTALL:-} "$@" ) INSTALL+=( $(env | grep '^INSTALL_.*=true$' | cut -d= -f1 | cut -d_ -f2- | tr '[:upper:]' '[:lower:]' | tr '_' '-') ) -DEPS=( $DEPS ) -UNTRUSTED_DEPS=( $UNTRUSTED_DEPS ) +DEPS=( ${DEPS:-} ) +UNTRUSTED_DEPS=( ${UNTRUSTED_DEPS:-} ) # Check for dependencies export BUILD_TMP='/tmp/clevyr-build' diff --git a/rootfs/usr/bin/s6-svscan-rootless b/rootfs/usr/bin/s6-svscan-rootless index f68e10b..5571846 100755 --- a/rootfs/usr/bin/s6-svscan-rootless +++ b/rootfs/usr/bin/s6-svscan-rootless @@ -1,6 +1,6 @@ #!/bin/sh -set -euo pipefail +set -efu # Wrapper to run s6-svscan from a writable directory # s6-svscan creates .s6-svscan in the service directory, so we need to copy services to /tmp From ff0459b79167d3020bcb5172eb908debd8ed60ae Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Fri, 17 Apr 2026 08:59:17 -0500 Subject: [PATCH 05/16] restore fpm rootfs --- Dockerfile => Dockerfile.rr | 3 +- .../usr/bin/clevyr-build | 0 .../99-docker-php-ext-xdebug-config.ini | 0 rootfs.fpm/entrypoint | 6 +++ rootfs.fpm/etc/nginx/conf.d/0-gzip.conf | 3 ++ rootfs.fpm/etc/nginx/conf.d/default.conf.tpl | 49 +++++++++++++++++++ rootfs.fpm/etc/services.d/nginx/run | 3 ++ rootfs.fpm/etc/services.d/php-fpm/run | 3 ++ rootfs.fpm/health-check | 14 ++++++ rootfs.fpm/usr/bin/clevyr-php-pre-stop | 5 ++ rootfs.fpm/usr/bin/php-fpm-status | 15 ++++++ {rootfs => rootfs.rr}/health-check | 0 .../usr/bin/s6-svscan-rootless | 0 13 files changed, 100 insertions(+), 1 deletion(-) rename Dockerfile => Dockerfile.rr (98%) rename {rootfs => rootfs.common}/usr/bin/clevyr-build (100%) rename {rootfs => rootfs.common}/usr/local/etc/php/conf.d/99-docker-php-ext-xdebug-config.ini (100%) create mode 100755 rootfs.fpm/entrypoint create mode 100644 rootfs.fpm/etc/nginx/conf.d/0-gzip.conf create mode 100644 rootfs.fpm/etc/nginx/conf.d/default.conf.tpl create mode 100755 rootfs.fpm/etc/services.d/nginx/run create mode 100755 rootfs.fpm/etc/services.d/php-fpm/run create mode 100755 rootfs.fpm/health-check create mode 100755 rootfs.fpm/usr/bin/clevyr-php-pre-stop create mode 100755 rootfs.fpm/usr/bin/php-fpm-status rename {rootfs => rootfs.rr}/health-check (100%) rename {rootfs => rootfs.rr}/usr/bin/s6-svscan-rootless (100%) diff --git a/Dockerfile b/Dockerfile.rr similarity index 98% rename from Dockerfile rename to Dockerfile.rr index 9a4296b..0aafbe6 100644 --- a/Dockerfile +++ b/Dockerfile.rr @@ -56,7 +56,8 @@ RUN </dev/null diff --git a/rootfs.fpm/usr/bin/clevyr-php-pre-stop b/rootfs.fpm/usr/bin/clevyr-php-pre-stop new file mode 100755 index 0000000..3fc49c7 --- /dev/null +++ b/rootfs.fpm/usr/bin/clevyr-php-pre-stop @@ -0,0 +1,5 @@ +#!/bin/bash + +while [[ "$(php-fpm-status active_processes)" -gt 1 ]]; do + sleep 3; +done diff --git a/rootfs.fpm/usr/bin/php-fpm-status b/rootfs.fpm/usr/bin/php-fpm-status new file mode 100755 index 0000000..85be3a0 --- /dev/null +++ b/rootfs.fpm/usr/bin/php-fpm-status @@ -0,0 +1,15 @@ +#!/bin/sh + +set -e + +query='fromjson? | with_entries(.key |= gsub(" "; "_"))' +if [ -n "${1:-}" ]; then + query="$query | .[\$key]" +fi + +SCRIPT_NAME=/status \ + SCRIPT_FILENAME=/status \ + REQUEST_METHOD=GET \ + QUERY_STRING=json \ + cgi-fcgi -bind -connect 127.0.0.1:9000 \ + | jq -Rr --arg key "${1:-}" "$query" diff --git a/rootfs/health-check b/rootfs.rr/health-check similarity index 100% rename from rootfs/health-check rename to rootfs.rr/health-check diff --git a/rootfs/usr/bin/s6-svscan-rootless b/rootfs.rr/usr/bin/s6-svscan-rootless similarity index 100% rename from rootfs/usr/bin/s6-svscan-rootless rename to rootfs.rr/usr/bin/s6-svscan-rootless From a53d26011fa96300c3eeefd51e95ac9d248cd119 Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Fri, 17 Apr 2026 09:04:03 -0500 Subject: [PATCH 06/16] restore fpm dockerfile --- Dockerfile.fpm | 144 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 Dockerfile.fpm diff --git a/Dockerfile.fpm b/Dockerfile.fpm new file mode 100644 index 0000000..6a5e685 --- /dev/null +++ b/Dockerfile.fpm @@ -0,0 +1,144 @@ +#syntax=docker/dockerfile:1 + +ARG PHP_VERSION +ARG COMPOSER_VERSION +ARG ALPINE_VERSION + +FROM composer:$COMPOSER_VERSION AS local-composer + +FROM php:$PHP_VERSION-fpm-alpine$ALPINE_VERSION AS base +WORKDIR /app + +COPY --from=mlocati/php-extension-installer:2.10.6 /usr/bin/install-php-extensions /usr/bin/ + +RUN < Date: Fri, 17 Apr 2026 09:05:09 -0500 Subject: [PATCH 07/16] dockerfile: fpm remove ext-sockets from default --- Dockerfile.fpm | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile.fpm b/Dockerfile.fpm index 6a5e685..e036261 100644 --- a/Dockerfile.fpm +++ b/Dockerfile.fpm @@ -125,7 +125,6 @@ ONBUILD ARG INSTALL_GD ONBUILD ARG INSTALL_IMAGICK ONBUILD ARG INSTALL_MOSQUITTO ONBUILD ARG INSTALL_MYSQL -ONBUILD ARG INSTALL_SOCKETS=true ONBUILD ARG INSTALL_SQLSRV ONBUILD ARG INSTALL_XDEBUG From e08f4bb6cdb0e902f8f84ea38f60d5da8d8deb79 Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Fri, 17 Apr 2026 09:10:39 -0500 Subject: [PATCH 08/16] ci: build both servers --- .github/workflows/docker.yml | 49 ++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index cc62735..c7160bc 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,6 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: + server: ["fpm", "rr"] php_version: ["8.1", "8.2", "8.3", "8.4", "8.5"] composer_version: ["2"] platforms: ["linux/amd64,linux/arm64/v8"] @@ -33,12 +34,12 @@ jobs: ghcr.io/clevyr/php flavor: latest=false tags: | - # {{major}}.{{minor}}-composer{{major}}-base - type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }}-base,value=${{ matrix.php_version }}.0 - # {{major}}.{{minor}}-base - type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},suffix=-base,value=${{ matrix.php_version }}.0 - # {{major}}-base - type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-base,value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-composer{{major}}-{{server}}-base + type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }}-${{ matrix.server }}-base,value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-{{server}}-base + type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},suffix=-${{ matrix.server }}-base,value=${{ matrix.php_version }}.0 + # {{major}}-{{server}}-base + type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-${{ matrix.server }}-base,value=${{ matrix.php_version }}.0 - name: Docker meta (onbuild) id: meta-onbuild @@ -51,18 +52,18 @@ jobs: tags: | # latest type=raw,enable=${{ matrix.latest == 'true' }},value=latest - # {{major}}.{{minor}}-composer{{major}}-onbuild - type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }}-onbuild,value=${{ matrix.php_version }}.0 - # {{major}}.{{minor}}-composer{{major}} - type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }},value=${{ matrix.php_version }}.0 - # {{major}}.{{minor}}-onbuild - type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},suffix=-onbuild,value=${{ matrix.php_version }}.0 - # {{major}}.{{minor}} - type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},value=${{ matrix.php_version }}.0 - # {{major}}-composer{{major}} - type=semver,enable=${{ (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-composer${{ matrix.composer_version }},value=${{ matrix.php_version }}.0 - # {{major}}-onbuild - type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-onbuild,value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-composer{{major}}-{{server}}-onbuild + type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }}-${{ matrix.server }}-onbuild,value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-composer{{major}}-{{server}} + type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }}-${{ matrix.server }},value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-{{server}}-onbuild + type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},suffix=-${{ matrix.server }}-onbuild,value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-{{server}} + type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},suffix=-${{ matrix.server }},value=${{ matrix.php_version }}.0 + # {{major}}-composer{{major}}-{{server}} + type=semver,enable=${{ (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-composer${{ matrix.composer_version }}-${{ matrix.server }},value=${{ matrix.php_version }}.0 + # {{major}}-{{server}}-onbuild + type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-${{ matrix.server }}-onbuild,value=${{ matrix.php_version }}.0 # {{major}} type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},value=${{ matrix.php_version }}.0 @@ -91,6 +92,7 @@ jobs: context: . pull: true load: true + file: Dockerfile.${{ matrix.server }} tags: ${{ env.TEST_TAG }} build-args: | COMPOSER_VERSION=${{ matrix.composer_version }} @@ -98,10 +100,17 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max + - name: Test nginx config + if: matrix.server == 'fpm' + run: docker run --rm -i "$TEST_TAG" nginx -t + - name: Test php-fpm config + if: matrix.server == 'fpm' + run: docker run --rm -i "$TEST_TAG" php-fpm -tt - name: Test RoadRunner + if: matrix.server == 'rr' run: docker run --rm -i "$TEST_TAG" rr --version - name: Test commands exist - run: docker run --rm -i "$TEST_TAG" which composer install-php-extensions clevyr-build rr + run: docker run --rm -i "$TEST_TAG" which composer install-php-extensions clevyr-build - name: Build and Push (base) uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 @@ -109,6 +118,7 @@ jobs: context: . pull: true push: ${{ github.ref_name == 'main' }} + file: Dockerfile.${{ matrix.server }} platforms: ${{ matrix.platforms }} tags: ${{ steps.meta-base.outputs.tags }} labels: ${{ steps.meta-base.outputs.labels }} @@ -124,6 +134,7 @@ jobs: with: context: . push: ${{ github.ref_name == 'main' }} + file: Dockerfile.${{ matrix.server }} platforms: ${{ matrix.platforms }} tags: ${{ steps.meta-onbuild.outputs.tags }} labels: ${{ steps.meta-onbuild.outputs.labels }} From 4c077878d5b61e8b51906d220ee751dfc6e19af6 Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Fri, 17 Apr 2026 09:12:07 -0500 Subject: [PATCH 09/16] ci: label build with server --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index c7160bc..7dbc105 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -8,7 +8,7 @@ concurrency: jobs: build: - name: Build ${{ matrix.php_version }}-composer${{ matrix.composer_version }} + name: Build ${{ matrix.php_version }}-composer${{ matrix.composer_version }}-${{ matrix.server }} runs-on: ubuntu-latest strategy: matrix: From 809b4ed2713065a84fd90c6c9ee79369da92cfb6 Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Fri, 17 Apr 2026 09:18:36 -0500 Subject: [PATCH 10/16] ci: ensure image tags for FPM are unchanged --- .github/workflows/docker.yml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 7dbc105..7976a2e 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -40,6 +40,12 @@ jobs: type=semver,enable=${{ matrix.composer_version == '2' }},pattern={{major}}.{{minor}},suffix=-${{ matrix.server }}-base,value=${{ matrix.php_version }}.0 # {{major}}-{{server}}-base type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-${{ matrix.server }}-base,value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-composer{{major}}-base (FPM only) + type=semver,enable=${{ matrix.composer_version == '2' && matrix.server == 'fpm' }},pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }}-base,value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-base (FPM only) + type=semver,enable=${{ matrix.composer_version == '2' && matrix.server == 'fpm' }},pattern={{major}}.{{minor}},suffix=-base,value=${{ matrix.php_version }}.0 + # {{major}}-base (FPM only) + type=semver,enable=${{ matrix.composer_version == '2' && matrix.server == 'fpm' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-base,value=${{ matrix.php_version }}.0 - name: Docker meta (onbuild) id: meta-onbuild @@ -50,8 +56,8 @@ jobs: ghcr.io/clevyr/php flavor: latest=false tags: | - # latest - type=raw,enable=${{ matrix.latest == 'true' }},value=latest + # latest (FPM only) + type=raw,enable=${{ matrix.latest == 'true' && matrix.server == 'fpm' }},value=latest # {{major}}.{{minor}}-composer{{major}}-{{server}}-onbuild type=semver,pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }}-${{ matrix.server }}-onbuild,value=${{ matrix.php_version }}.0 # {{major}}.{{minor}}-composer{{major}}-{{server}} @@ -66,6 +72,18 @@ jobs: type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-${{ matrix.server }}-onbuild,value=${{ matrix.php_version }}.0 # {{major}} type=semver,enable=${{ matrix.composer_version == '2' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-composer{{major}}-onbuild (FPM only) + type=semver,enable=${{ matrix.composer_version == '2' && matrix.server == 'fpm' }},pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }}-onbuild,value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-composer{{major}} (FPM only) + type=semver,enable=${{ matrix.composer_version == '2' && matrix.server == 'fpm' }},pattern={{major}}.{{minor}},suffix=-composer${{ matrix.composer_version }},value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}}-onbuild (FPM only) + type=semver,enable=${{ matrix.composer_version == '2' && matrix.server == 'fpm' }},pattern={{major}}.{{minor}},suffix=-onbuild,value=${{ matrix.php_version }}.0 + # {{major}}.{{minor}} (FPM only) + type=semver,enable=${{ matrix.composer_version == '2' && matrix.server == 'fpm' }},pattern={{major}}.{{minor}},value=${{ matrix.php_version }}.0 + # {{major}}-composer{{major}} (FPM only) + type=semver,enable=${{ matrix.composer_version == '2' && matrix.server == 'fpm' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},suffix=-composer${{ matrix.composer_version }},value=${{ matrix.php_version }}.0 + # {{major}} (FPM only) + type=semver,enable=${{ matrix.composer_version == '2' && matrix.server == 'fpm' && (matrix.latest_major == 'true' || matrix.latest == 'true') }},pattern={{major}},value=${{ matrix.php_version }}.0 - name: Set up QEMU uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 From 402429741c85ab95ad30ad75a55b3d1eb45f8602 Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Fri, 17 Apr 2026 09:23:32 -0500 Subject: [PATCH 11/16] docker: rr: add sockets extension to PHP installation --- Dockerfile.rr | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile.rr b/Dockerfile.rr index 0aafbe6..db53ec4 100644 --- a/Dockerfile.rr +++ b/Dockerfile.rr @@ -13,7 +13,7 @@ COPY --from=mlocati/php-extension-installer:2.10.6 /usr/bin/install-php-extensio RUN < Date: Fri, 17 Apr 2026 09:23:40 -0500 Subject: [PATCH 12/16] docker: rr: remove s6 --- Dockerfile.rr | 4 +--- rootfs.rr/usr/bin/s6-svscan-rootless | 25 ------------------------- 2 files changed, 1 insertion(+), 28 deletions(-) delete mode 100755 rootfs.rr/usr/bin/s6-svscan-rootless diff --git a/Dockerfile.rr b/Dockerfile.rr index db53ec4..a2bf660 100644 --- a/Dockerfile.rr +++ b/Dockerfile.rr @@ -12,7 +12,7 @@ COPY --from=mlocati/php-extension-installer:2.10.6 /usr/bin/install-php-extensio RUN <" >&2 - exit 1 -fi - -# Create a unique directory in /tmp for our services -TEMP_SERVICE_DIR="/tmp/s6-services-$$" -mkdir -p "$TEMP_SERVICE_DIR" - -# Copy the service directory contents to /tmp -cp -r "$SERVICE_DIR"/* "$TEMP_SERVICE_DIR/" 2>/dev/null || cp -r "$SERVICE_DIR"/. "$TEMP_SERVICE_DIR/" - -# Run s6-svscan against the copied services -exec s6-svscan "$TEMP_SERVICE_DIR" From e6c29d831b5221f7ce0382dad48a96d5397ed2aa Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Fri, 17 Apr 2026 09:28:05 -0500 Subject: [PATCH 13/16] README: restore FPM/nginx sections --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index f5cd277..96c96b1 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,16 @@ Some php.ini values can be configured as a build arg. | `PHP_UPLOAD_MAX_FILESIZE` | See [`upload_max_filesize`](https://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize). | `8M` | | `PHP_MAX_FILE_UPLOADS` | See [`max_file_uploads`](https://www.php.net/manual/en/ini.core.php#ini.max-file-uploads). | `20` | +### PHP-FPM Configuration + +| Environment Variable | Description | Default | +|--------------------------------|-----------------------------------------------------------------------------------------------------------------|---------| +| `PHP_FPM_PM_MAX_CHILDREN` | See [`pm.max_children`](https://www.php.net/manual/en/install.fpm.configuration.php#pm.max-children). | `80` | +| `PHP_FPM_PM_START_SERVERS` | See [`pm.start_servers`](https://www.php.net/manual/en/install.fpm.configuration.php#pm.start-servers). | `2` | +| `PHP_FPM_PM_MIN_SPARE_SERVERS` | See [`pm.min_spare_servers`](https://www.php.net/manual/en/install.fpm.configuration.php#pm.min-spare-servers). | `1` | +| `PHP_FPM_PM_MAX_SPARE_SERVERS` | See [`pm.max_spare_servers`](https://www.php.net/manual/en/install.fpm.configuration.php#pm.max-spare-servers). | `3` | +| `PHP_FPM_PM_MAX_REQUESTS` | See [`pm.max_requests`](https://www.php.net/manual/en/install.fpm.configuration.php#pm.max-requests). | `0` | + ## Build Arguments The following variables can be only be configured at build. @@ -38,6 +48,15 @@ The following variables can be only be configured at build. | `INSTALL` | PHP extensions to install. See [here](https://github.com/mlocati/docker-php-extension-installer#supported-php-extensions) for available extensions. | | `DEPS` | `apk` dependencies to install during the build. | +### Nginx Configuration + +Some nginx values can be configured as a build arg. + +| Build Arg | Nginx Directive | Default | +|-----------------|-------------------------------------------------------------------------------|---------------| +| `NGINX_ROOT` | [root](http://nginx.org/en/docs/http/ngx_http_core_module.html#root) | `/app/public` | +| `NGINX_EXPIRES` | [expires](http://nginx.org/en/docs/http/ngx_http_headers_module.html#expires) | `7d` | + ### Legacy Build Arguments These are the legacy build args. They will still be supported for the forseeable future, but they are not as powerful as the new `INSTALL` build arg, so if you are creating an app from scratch, the `INSTALL` build arg may be more useful for you. These are also convenient because they group up some extensnions. For example, if you set `INSTALL_MYSQL=true`, then both `mysqli` and `pdo_mysql` will be installed. From 87a36697e3b380f7e9eb921fd41b99667914aa4e Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Fri, 17 Apr 2026 09:32:23 -0500 Subject: [PATCH 14/16] readme: document new image variant --- README.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 96c96b1..bb4e036 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,27 @@ An enhanced version of the default [PHP Docker image](https://hub.docker.com/_/php) which can install PHP extensions without requiring manual dependency installation using [mlocati/docker-php-extension-installer](https://github.com/mlocati/docker-php-extension-installer). +## Image Variants + +Two image variants are available, distinguished by tag suffix: + +| Tag Suffix | Description | Example | +|------------|--------------------------------------------------------------|-----------| +| `-fpm` | PHP-FPM with Nginx, managed by s6 | `8.5-fpm` | +| `-rr` | PHP CLI with [RoadRunner](https://roadrunner.dev) (rootless) | `8.5-rr` | + +Tags without a suffix (e.g. `8.5`) default to the `-fpm` variant for backward compatibility. + ## Pull Command The following command will retrieve an image with PHP 8.5 and Composer v2: ```sh -docker pull ghcr.io/clevyr/php:8.5 +# PHP-FPM + Nginx +docker pull ghcr.io/clevyr/php:8.5-fpm + +# RoadRunner +docker pull ghcr.io/clevyr/php:8.5-rr ``` ## Runtime Configuration @@ -29,7 +44,7 @@ Some php.ini values can be configured as a build arg. | `PHP_UPLOAD_MAX_FILESIZE` | See [`upload_max_filesize`](https://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize). | `8M` | | `PHP_MAX_FILE_UPLOADS` | See [`max_file_uploads`](https://www.php.net/manual/en/ini.core.php#ini.max-file-uploads). | `20` | -### PHP-FPM Configuration +### PHP-FPM Configuration (`-fpm` only) | Environment Variable | Description | Default | |--------------------------------|-----------------------------------------------------------------------------------------------------------------|---------| @@ -48,7 +63,7 @@ The following variables can be only be configured at build. | `INSTALL` | PHP extensions to install. See [here](https://github.com/mlocati/docker-php-extension-installer#supported-php-extensions) for available extensions. | | `DEPS` | `apk` dependencies to install during the build. | -### Nginx Configuration +### Nginx Configuration (`-fpm` only) Some nginx values can be configured as a build arg. From 5e658c2d4c57aa9664030cffffd3b2b0ab6d03b4 Mon Sep 17 00:00:00 2001 From: Jacob McSwain Date: Fri, 17 Apr 2026 09:35:26 -0500 Subject: [PATCH 15/16] clevyr-build: re-add nginx templating --- rootfs.fpm/usr/bin/clevyr-build | 71 +++++++++++++++++++ .../usr/bin/clevyr-build | 0 2 files changed, 71 insertions(+) create mode 100755 rootfs.fpm/usr/bin/clevyr-build rename {rootfs.common => rootfs.rr}/usr/bin/clevyr-build (100%) diff --git a/rootfs.fpm/usr/bin/clevyr-build b/rootfs.fpm/usr/bin/clevyr-build new file mode 100755 index 0000000..c7153e9 --- /dev/null +++ b/rootfs.fpm/usr/bin/clevyr-build @@ -0,0 +1,71 @@ +#!/bin/bash + +set -efuo pipefail + +log() { + printf '%s: %s\n' "$(basename "$0")" "$@" >&2 +} + +if [ "${INSTALL_MYSQL:-}" = "true" ]; then + unset INSTALL_MYSQL + export INSTALL="${INSTALL:-} mysqli pdo_mysql" +fi + +if [ "${INSTALL_SQLSRV:-}" = "true" ]; then + unset INSTALL_SQLSRV + export INSTALL="${INSTALL:-} sqlsrv pdo_sqlsrv" +fi + +# Add workaround for xdebug alpha release +if [ "${INSTALL_XDEBUG:-}" = "true" ]; then + unset INSTALL_XDEBUG + export INSTALL="${INSTALL:-} xdebug-stable" +fi + +# Add old dependency args to new variable + +INSTALL=( ${INSTALL:-} "$@" ) +INSTALL+=( $(env | grep '^INSTALL_.*=true$' | cut -d= -f1 | cut -d_ -f2- | tr '[:upper:]' '[:lower:]' | tr '_' '-') ) + +DEPS=( ${DEPS:-} ) +UNTRUSTED_DEPS=( ${UNTRUSTED_DEPS:-} ) + +# Check for dependencies +export BUILD_TMP='/tmp/clevyr-build' +mkdir -p "$BUILD_TMP" +for extension in "${INSTALL[@]}"; do + case "$extension" in + pgsql | pdo_pgsql) + if ! [ -f "$BUILD_TMP/pgsql" ]; then + log 'Adding postgresql-client to DEPS' + DEPS+=( 'postgresql-client' ) + touch "$BUILD_TMP/pgsql" + fi + ;; + esac +done + +# Install untrusted permanent dependencies +if [ "${#UNTRUSTED_DEPS[@]}" != 0 ]; then + log "Installing UNTRUSTED_DEPS: ${UNTRUSTED_DEPS[*]}" + apk add --no-cache --allow-untrusted "${UNTRUSTED_DEPS[@]}" +fi + +# Install permanent dependencies +if [ "${#DEPS[@]}" != 0 ]; then + log "Installing DEPS: ${DEPS[*]}" + apk add --no-cache "${DEPS[@]}" +fi + +# Install all php extensions +log "Beginning install: ${INSTALL[*]}" +install-php-extensions "${INSTALL[@]}" + +# Template nginx config +log 'Templating nginx config' +export NGINX_ROOT="${NGINX_ROOT:-/app/public}" \ + NGINX_EXPIRES="${NGINX_EXPIRES:-7d}" +envsubst '$NGINX_ROOT $NGINX_EXPIRES' < /etc/nginx/conf.d/default.conf.tpl > /etc/nginx/conf.d/default.conf + +log 'Removing all tmp files' +rm -rf /tmp/* diff --git a/rootfs.common/usr/bin/clevyr-build b/rootfs.rr/usr/bin/clevyr-build similarity index 100% rename from rootfs.common/usr/bin/clevyr-build rename to rootfs.rr/usr/bin/clevyr-build From 208f361a8a6f68a6fe7aba1fdc563bacae424781 Mon Sep 17 00:00:00 2001 From: Gabe Cook Date: Mon, 27 Apr 2026 10:55:25 -0500 Subject: [PATCH 16/16] chore: deduplicate build script --- .../usr/bin/clevyr-build | 10 +-- rootfs.rr/usr/bin/clevyr-build | 65 ------------------- 2 files changed, 6 insertions(+), 69 deletions(-) rename {rootfs.fpm => rootfs.common}/usr/bin/clevyr-build (85%) delete mode 100755 rootfs.rr/usr/bin/clevyr-build diff --git a/rootfs.fpm/usr/bin/clevyr-build b/rootfs.common/usr/bin/clevyr-build similarity index 85% rename from rootfs.fpm/usr/bin/clevyr-build rename to rootfs.common/usr/bin/clevyr-build index c7153e9..4acb901 100755 --- a/rootfs.fpm/usr/bin/clevyr-build +++ b/rootfs.common/usr/bin/clevyr-build @@ -62,10 +62,12 @@ log "Beginning install: ${INSTALL[*]}" install-php-extensions "${INSTALL[@]}" # Template nginx config -log 'Templating nginx config' -export NGINX_ROOT="${NGINX_ROOT:-/app/public}" \ - NGINX_EXPIRES="${NGINX_EXPIRES:-7d}" -envsubst '$NGINX_ROOT $NGINX_EXPIRES' < /etc/nginx/conf.d/default.conf.tpl > /etc/nginx/conf.d/default.conf +if [[ -f /etc/nginx/conf.d/default.conf.tpl ]]; then + log 'Templating nginx config' + export NGINX_ROOT="${NGINX_ROOT:-/app/public}" \ + NGINX_EXPIRES="${NGINX_EXPIRES:-7d}" + envsubst '$NGINX_ROOT $NGINX_EXPIRES' < /etc/nginx/conf.d/default.conf.tpl > /etc/nginx/conf.d/default.conf +fi log 'Removing all tmp files' rm -rf /tmp/* diff --git a/rootfs.rr/usr/bin/clevyr-build b/rootfs.rr/usr/bin/clevyr-build deleted file mode 100755 index e4b193a..0000000 --- a/rootfs.rr/usr/bin/clevyr-build +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash - -set -efuo pipefail - -log() { - printf '%s: %s\n' "$(basename "$0")" "$@" >&2 -} - -if [ "${INSTALL_MYSQL:-}" = "true" ]; then - unset INSTALL_MYSQL - export INSTALL="${INSTALL:-} mysqli pdo_mysql" -fi - -if [ "${INSTALL_SQLSRV:-}" = "true" ]; then - unset INSTALL_SQLSRV - export INSTALL="${INSTALL:-} sqlsrv pdo_sqlsrv" -fi - -# Add workaround for xdebug alpha release -if [ "${INSTALL_XDEBUG:-}" = "true" ]; then - unset INSTALL_XDEBUG - export INSTALL="${INSTALL:-} xdebug-stable" -fi - -# Add old dependency args to new variable - -INSTALL=( ${INSTALL:-} "$@" ) -INSTALL+=( $(env | grep '^INSTALL_.*=true$' | cut -d= -f1 | cut -d_ -f2- | tr '[:upper:]' '[:lower:]' | tr '_' '-') ) - -DEPS=( ${DEPS:-} ) -UNTRUSTED_DEPS=( ${UNTRUSTED_DEPS:-} ) - -# Check for dependencies -export BUILD_TMP='/tmp/clevyr-build' -mkdir -p "$BUILD_TMP" -for extension in "${INSTALL[@]}"; do - case "$extension" in - pgsql | pdo_pgsql) - if ! [ -f "$BUILD_TMP/pgsql" ]; then - log 'Adding postgresql-client to DEPS' - DEPS+=( 'postgresql-client' ) - touch "$BUILD_TMP/pgsql" - fi - ;; - esac -done - -# Install untrusted permanent dependencies -if [ "${#UNTRUSTED_DEPS[@]}" != 0 ]; then - log "Installing UNTRUSTED_DEPS: ${UNTRUSTED_DEPS[*]}" - apk add --no-cache --allow-untrusted "${UNTRUSTED_DEPS[@]}" -fi - -# Install permanent dependencies -if [ "${#DEPS[@]}" != 0 ]; then - log "Installing DEPS: ${DEPS[*]}" - apk add --no-cache "${DEPS[@]}" -fi - -# Install all php extensions -log "Beginning install: ${INSTALL[*]}" -install-php-extensions "${INSTALL[@]}" - -log 'Removing all tmp files' -rm -rf /tmp/*