diff --git a/php/8.3-ubuntu-frankenphp/Dockerfile b/php/8.3-ubuntu-frankenphp/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..32dbb8d377ba0f5eeb9729be29018f549cf4d38d
--- /dev/null
+++ b/php/8.3-ubuntu-frankenphp/Dockerfile
@@ -0,0 +1,278 @@
+######
+# Base
+######
+ARG THE_BASE_IMAGE=ubuntu:noble
+
+ARG PHPIZE_DEPS="autoconf file g++ gcc make pkg-config re2c"
+
+ARG PHP_VERSION=8.3.11
+ARG PHP_SHA256_HASH="b862b098a08ab9bf4b36ed12c7d0d9f65353656b36fb0e3c5344093aceb35802  php.tar.xz"
+
+# Apply stack smash protection to functions using local buffers and alloca()
+# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64)
+# Enable optimization (-O2)
+# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default)
+# https://github.com/docker-library/php/issues/272
+# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php)
+ARG PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+ARG PHP_LDFLAGS="-Wl,-O1 -pie"
+
+FROM docker.io/dunglas/frankenphp:1-php${PHP_VERSION} AS frankenphp
+
+FROM ${THE_BASE_IMAGE} AS builder
+ENV DRUPALCI=TRUE TERM=xterm DEBIAN_FRONTEND=noninteractive
+
+#########
+# Php build
+######
+
+# PHP Version
+ARG PHP_VERSION
+ARG PHP_SHA256_HASH
+ARG PHP_URL="https://php.net/distributions/php-${PHP_VERSION}.tar.xz"
+ENV PHP_VERSION=${PHP_VERSION}
+
+ARG PHPIZE_DEPS
+
+ARG PHP_CFLAGS
+ARG PHP_LDFLAGS
+ENV PHP_CFLAGS="$PHP_CFLAGS"
+ENV PHP_CPPFLAGS="$PHP_CFLAGS"
+ENV PHP_LDFLAGS="$PHP_LDFLAGS"
+
+RUN set -eux &&\
+    echo 'APT::Install-Recommends "0";' >/etc/apt/apt.conf.d/99norecommends &&\
+    apt-get update && apt-get install -qy --no-install-recommends \
+        ca-certificates curl apt-utils xz-utils &&\
+    \
+    mkdir -p /usr/src &&\
+    cd /usr/src &&\
+    \
+    curl -LS -o php.tar.xz "$PHP_URL" &&\
+    \
+    echo $PHP_SHA256_HASH | sha256sum -c &&\
+    \
+    buildDeps=" \
+        libcurl4-openssl-dev \
+        libedit-dev \
+        libfreetype-dev \
+        libicu-dev \
+        libjpeg-turbo8-dev \
+        libonig-dev \
+        libkrb5-dev \
+        zlib1g-dev \
+        libpng-dev \
+        libwebp-dev \
+        libavif-dev \
+        libsqlite3-dev \
+        libpq-dev \
+        libssl-dev \
+        libtidy-dev \
+        libxml2-dev \
+        libxslt1-dev \
+        libyaml-dev \
+        libzip-dev \
+        libncurses-dev \
+    " &&\
+    apt-get install -qy --no-install-recommends $PHPIZE_DEPS $buildDeps &&\
+    rm -rf /var/lib/apt/lists/*
+
+COPY ./conf/php/php.ini /usr/local/etc/php/php.ini
+COPY ./conf/php/php-cli.ini /usr/local/etc/php/php-cli.ini
+COPY ./docker-php-* /usr/local/bin/
+
+RUN set -xe &&\
+    buildDir="/usr/src/php" &&\
+    mkdir -p /usr/local/etc/php/conf.d &&\
+    \
+    mkdir "$buildDir" &&\
+    tar -Jxf /usr/src/php.tar.xz -C "$buildDir" --strip-components=1 &&\
+    cd "$buildDir" &&\
+    CFLAGS="$PHP_CFLAGS" \
+    CPPFLAGS="$PHP_CPPFLAGS" \
+    LDFLAGS="$PHP_LDFLAGS" \
+    ./configure \
+        --with-config-file-path=/usr/local/etc/php \
+        --with-config-file-scan-dir=/usr/local/etc/php/conf.d \
+        --enable-ftp \
+        --enable-mbstring \
+        --enable-mysqlnd \
+        --with-curl \
+        --with-libedit \
+            --with-zlib \
+            --with-kerberos \
+            --with-openssl \
+            --with-mysqli=mysqlnd \
+            --with-pdo-mysql=mysqlnd \
+            --with-pdo-sqlite \
+            --with-pdo-pgsql \
+            --with-readline \
+            --with-freetype \
+            --with-jpeg \
+            --with-xsl \
+            --with-tidy \
+            --with-gettext=shared \
+            --enable-gd \
+            --with-webp \
+            --with-avif \
+            --with-pear \
+            --enable-sockets \
+            --enable-exif \
+            --with-zip \
+            --enable-soap \
+            --enable-sysvsem \
+            --enable-sysvshm \
+            --enable-shmop \
+            --enable-pcntl \
+            --enable-bcmath \
+            --enable-xmlreader \
+            --enable-intl \
+            --enable-opcache \
+        --enable-embed \
+        --enable-zts \
+        --disable-zend-signals \
+        --enable-zend-max-execution-timers \
+            --disable-cgi \
+            --disable-phpdbg \
+           &&\
+    make -j "$(nproc)" &&\
+    make install &&\
+    cd / && rm -fr "$buildDir"
+
+# install pecl extensions for apcu, pcov, xdebug, yaml, mongodb
+RUN pecl channel-update pecl.php.net &&\
+#    pecl install APCu-5.1.23 mongodb-1.19.4 pcov-1.0.11 xdebug-3.3.2 yaml-2.2.3 \
+    pecl install APCu-5.1.23 xdebug-3.3.2 yaml-2.2.3 \
+    &&\
+# stript .debug files out of executables
+    echo '\
+        for file in "$@"; do \
+            objcopy --only-keep-debug "$file" "$file".debug; \
+            strip --strip-debug --strip-unneeded "$file"; \
+            objcopy --add-gnu-debuglink="$file".debug "$file"; \
+        done' > /strip.sh; \
+    sh strip.sh \
+      /usr/local/bin/php \
+      $(php -r 'echo ini_get("extension_dir");')/*.so
+
+
+#########
+# Php Setup
+######
+
+FROM ${THE_BASE_IMAGE}
+ARG DEBIAN_FRONTEND=noninteractive
+ENV DRUPALCI=TRUE TERM=xterm
+
+COPY --from=builder /usr/local /usr/local
+
+RUN set -xe &&\
+    echo 'APT::Install-Recommends "0";' >/etc/apt/apt.conf.d/99norecommends ;\
+    apt-get update &&\
+    buildDeps=" \
+        libedit2 \
+        libfreetype6 \
+        libicu74 \
+        libjpeg-turbo8 \
+        libonig5 \
+        libkrb5-3 \
+        libpng16-16 \
+        zlib1g \
+        libwebp7 \
+        libavif16 \
+        libaom3 \
+        libsqlite3-0 \
+        libpq5 \
+        libtidy5deb1 \
+        libyaml-0-2 \
+        libxml2 \
+        libxslt1.1 \
+        libzip4 \
+        libncurses6 \
+    " &&\
+    runDeps=" \
+        bzip2 \
+        curl ca-certificates gnupg2 \
+        default-mysql-client postgresql-client sudo git sqlite3 \
+        patch \
+        rsync \
+        unzip \
+        xz-utils \
+    " &&\
+    apt-get install -qy --no-install-recommends $buildDeps $runDeps &&\
+    rm -rf /var/lib/apt/lists/*
+
+# Install Composer, Drush
+RUN curl -sSLo /tmp/composer-setup.php https://getcomposer.org/installer &&\
+    curl -sSLo /tmp/composer-setup.sig https://composer.github.io/installer.sig &&\
+    php -r "if (hash('SHA384', file_get_contents('/tmp/composer-setup.php')) !== trim(file_get_contents('/tmp/composer-setup.sig'))) { unlink('/tmp/composer-setup.php'); echo 'Invalid installer' . PHP_EOL; exit(1); }" &&\
+    php /tmp/composer-setup.php --filename composer --install-dir /usr/local/bin &&\
+    curl -sSLo /usr/local/bin/drush https://github.com/drush-ops/drush/releases/download/8.3.5/drush.phar &&\
+    chmod +x /usr/local/bin/drush &&\
+    /usr/local/bin/drush --version
+
+# Install nodejs and yarn
+RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/nodesource.gpg &&\
+    echo 'deb [signed-by=/etc/apt/trusted.gpg.d/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main' | tee /etc/apt/sources.list.d/nodesource.list &&\
+    curl -sSLo /etc/apt/trusted.gpg.d/yarn.gpg.asc https://dl.yarnpkg.com/debian/pubkey.gpg &&\
+    echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list &&\
+    apt-get update &&\
+    apt-get install -qy --no-install-recommends nodejs yarn &&\
+    rm -rf /var/lib/apt/lists/*
+
+# Install phantomjs, supervisor
+RUN _file=phantomjs-2.1.1-linux-x86_64 &&\
+    curl -sSLo /$_file.tar.bz2 https://bitbucket.org/ariya/phantomjs/downloads/$_file.tar.bz2 &&\
+    tar -jxf /$_file.tar.bz2 -C / &&\
+    mv /$_file/bin/phantomjs /usr/bin/phantomjs &&\
+    rm -f /$_file.tar.bz2 &&\
+    rm -rf /$_file &&\
+    chmod 755 /usr/bin/phantomjs &&\
+    apt-get update &&\
+    apt-get install -qy --no-install-recommends supervisor fontconfig &&\
+    rm -rf /var/lib/apt/lists/*
+
+COPY ./conf/supervisor-phantomjs.conf /etc/supervisor/conf.d/phantomjs.conf
+
+
+######
+# Webserver Setup
+######
+
+COPY --from=frankenphp /usr/local/bin/frankenphp /usr/local/bin/
+
+COPY ./conf/Caddyfile /etc/caddy/
+COPY --chmod=755 ./conf/apache2 /etc/init.d/
+
+RUN set -ex &&\
+	update-rc.d apache2 defaults &&\
+	\
+	for dir in \
+		/var/www/html \
+		/var/www/apc \
+		/var/www/.local/share/caddy \
+	; do \
+		rm -rvf "$dir" \
+		&& mkdir -p "$dir" \
+		&& chown -R "www-data:www-data" "$dir"; \
+	done
+
+ARG PHPIZE_DEPS
+ENV PHPIZE_DEPS=$PHPIZE_DEPS
+
+ARG PHP_CFLAGS
+ARG PHP_LDFLAGS
+ENV PHP_CFLAGS="$PHP_CFLAGS"
+ENV PHP_CPPFLAGS="$PHP_CFLAGS"
+ENV PHP_LDFLAGS="$PHP_LDFLAGS"
+
+ENTRYPOINT ["docker-php-entrypoint"]
+
+ENV CADDY_ADMIN='0.0.0.0:2019'
+ENV SERVER_NAME=':80'
+ENV CADDY_SERVER_EXTRA_DIRECTIVES='root * /var/www/html'
+
+WORKDIR /var/www/html
+
+EXPOSE 80
+CMD ["sudo","-u","www-data","frankenphp","php-server","-v"]
diff --git a/php/8.3-ubuntu-frankenphp/conf/Caddyfile b/php/8.3-ubuntu-frankenphp/conf/Caddyfile
new file mode 100644
index 0000000000000000000000000000000000000000..04125f781ade2865b900f896a3a74ea9b3a03c7f
--- /dev/null
+++ b/php/8.3-ubuntu-frankenphp/conf/Caddyfile
@@ -0,0 +1,47 @@
+# Adapted from https://caddy.community/t/caddyfile-for-drupal-10/21607/5
+{
+    {$CADDY_GLOBAL_OPTIONS}
+
+    frankenphp {
+	{$FRANKENPHP_CONFIG}
+    }
+
+    # https://caddyserver.com/docs/caddyfile/directives#sorting-algorithm
+    order php_server before file_server
+    order php before file_server
+}
+
+{$CADDY_EXTRA_CONFIG}
+
+{$SERVER_NAME:localhost} {
+    root * /var/www/html
+    encode zstd br gzip
+
+    @hiddenPhpFilesRegexp path_regexp \..*/.*\.php$
+    error @hiddenPhpFilesRegexp 403
+
+    @notFoundPhpFiles path_regexp /vendor/.*\.php$
+    error @notFoundPhpFiles 404
+
+    @notFoundPhpFilesRegexp path_regexp ^/sites/[^/]+/files/.*\.php$
+    error @notFoundPhpFilesRegexp 404
+
+    @privateDirRegexp path_regexp ^/sites/.*/private/
+    error @privateDirRegexp 403
+
+    @protectedFilesRegexp {
+	not path /.well-known*
+	path_regexp \.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^/(\..*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config|yarn\.lock|package\.json)$|^\/#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$
+    }
+    error @protectedFilesRegexp 403
+
+    @static {
+	file
+	path *.avif *.css *.eot *.gif *.gz *.ico *.jpg *.jpeg *.js *.otf *.pdf *.png *.svg *.ttf *.webp *.woff *.woff2
+    }
+    header @static Cache-Control "max-age=31536000,public,immutable"
+
+    {$CADDY_SERVER_EXTRA_DIRECTIVES}
+
+    php_server
+}
diff --git a/php/8.3-ubuntu-frankenphp/conf/apache2 b/php/8.3-ubuntu-frankenphp/conf/apache2
new file mode 100644
index 0000000000000000000000000000000000000000..1d88abbe640b2a5e41da713a2176e2903ea39def
--- /dev/null
+++ b/php/8.3-ubuntu-frankenphp/conf/apache2
@@ -0,0 +1,62 @@
+#!/bin/sh
+### BEGIN INIT INFO
+# Provides:          apache2 (actually FrankenPHP)
+# Required-Start:    $network $local_fs
+# Required-Stop:     $network $local_fs
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: Start FrankenPHP as Apache2 replacement
+# Description:       Replaces Apache2 with FrankenPHP running as www-data
+### END INIT INFO
+
+# Path to FrankenPHP binary
+FRANKENPHP_BIN="/usr/local/bin/frankenphp"
+
+# FrankenPHP parameters
+FRANKENPHP_ARGS="php-server -a -d"
+
+# User and group to run the service
+USER="www-data"
+GROUP="www-data"
+
+PIDFILE="/var/run/frankenphp.pid"
+
+start() {
+    echo "Starting FrankenPHP..."
+    start-stop-daemon --start --quiet --background --pidfile $PIDFILE --chuid $USER:$GROUP --exec $FRANKENPHP_BIN -- $FRANKENPHP_ARGS || echo "FrankenPHP already running"
+}
+
+stop() {
+    echo "Stopping FrankenPHP..."
+    start-stop-daemon --stop --quiet --pidfile $PIDFILE --exec $FRANKENPHP_BIN || echo "FrankenPHP not running"
+}
+
+status() {
+    if [ -e $PIDFILE ]; then
+        echo "FrankenPHP is running"
+    else
+        echo "FrankenPHP is not running"
+    fi
+}
+
+case "$1" in
+    start)
+        start
+        ;;
+    stop)
+        stop
+        ;;
+    restart)
+        stop
+        start
+        ;;
+    status)
+        status
+        ;;
+    *)
+        echo "Usage: $0 {start|stop|restart|status}"
+        exit 1
+        ;;
+esac
+
+exit 0
diff --git a/php/8.3-ubuntu-frankenphp/conf/php/php-cli.ini b/php/8.3-ubuntu-frankenphp/conf/php/php-cli.ini
new file mode 100644
index 0000000000000000000000000000000000000000..03d3be0c0216b294c9eb4dd1ab8d032016fc153f
--- /dev/null
+++ b/php/8.3-ubuntu-frankenphp/conf/php/php-cli.ini
@@ -0,0 +1,202 @@
+[PHP]
+engine = On
+short_open_tag = Off
+asp_tags = Off
+precision = 14
+output_buffering = 4096
+zlib.output_compression = Off
+implicit_flush = Off
+unserialize_callback_func =
+serialize_precision = -1
+disable_functions =
+disable_classes =
+zend.enable_gc = On
+expose_php = On
+max_execution_time = 300
+max_input_time = 60
+memory_limit = -1
+error_reporting = E_ALL & ~E_DEPRECATED
+display_errors = Off
+display_startup_errors = Off
+log_errors = On
+log_errors_max_len = 1024
+ignore_repeated_errors = Off
+ignore_repeated_source = Off
+report_memleaks = On
+track_errors = Off
+html_errors = Off
+variables_order = "GPCS"
+request_order = "GP"
+register_argc_argv = Off
+auto_globals_jit = On
+post_max_size = 8M
+auto_prepend_file =
+auto_append_file =
+default_mimetype = "text/html"
+doc_root =
+user_dir =
+enable_dl = Off
+file_uploads = On
+upload_max_filesize = 8M
+max_file_uploads = 20
+allow_url_fopen = On
+allow_url_include = Off
+default_socket_timeout = 60
+assert.exception = 1
+[CLI Server]
+cli_server.color = On
+
+
+[Pdo_mysql]
+pdo_mysql.cache_size = 2000
+pdo_mysql.default_socket=
+[Phar]
+[Syslog]
+define_syslog_variables  = Off
+[mail function]
+SMTP = localhost
+smtp_port = 25
+mail.add_x_header = On
+[SQL]
+sql.safe_mode = Off
+[ODBC]
+odbc.allow_persistent = On
+odbc.check_persistent = On
+odbc.max_persistent = -1
+odbc.max_links = -1
+odbc.defaultlrl = 4096
+odbc.defaultbinmode = 1
+[Interbase]
+ibase.allow_persistent = 1
+ibase.max_persistent = -1
+ibase.max_links = -1
+ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
+ibase.dateformat = "%Y-%m-%d"
+ibase.timeformat = "%H:%M:%S"
+[MySQL]
+mysql.allow_local_infile = On
+mysql.allow_persistent = On
+mysql.cache_size = 2000
+mysql.max_persistent = -1
+mysql.max_links = -1
+mysql.default_port =
+mysql.default_socket =
+mysql.default_host =
+mysql.default_user =
+mysql.default_password =
+mysql.connect_timeout = 60
+mysql.trace_mode = Off
+[MySQLi]
+mysqli.max_persistent = -1
+mysqli.allow_persistent = On
+mysqli.max_links = -1
+mysqli.cache_size = 2000
+mysqli.default_port = 3306
+mysqli.default_socket =
+mysqli.default_host =
+mysqli.default_user =
+mysqli.default_pw =
+mysqli.reconnect = Off
+[mysqlnd]
+mysqlnd.collect_statistics = On
+mysqlnd.collect_memory_statistics = Off
+[OCI8]
+[PostgreSQL]
+pgsql.allow_persistent = On
+pgsql.auto_reset_persistent = Off
+pgsql.max_persistent = -1
+pgsql.max_links = -1
+pgsql.ignore_notice = 0
+pgsql.log_notice = 0
+[Sybase-CT]
+sybct.allow_persistent = On
+sybct.max_persistent = -1
+sybct.max_links = -1
+sybct.min_server_severity = 10
+sybct.min_client_severity = 10
+[bcmath]
+bcmath.scale = 0
+[browscap]
+[Session]
+session.save_handler = files
+session.save_path = "/tmp"
+session.use_strict_mode = 0
+session.use_cookies = 1
+session.use_only_cookies = 1
+session.name = PHPSESSID
+session.auto_start = 0
+session.cookie_lifetime = 0
+session.cookie_path = /
+session.cookie_domain =
+session.cookie_httponly =
+session.serialize_handler = php
+session.gc_probability = 1
+session.gc_divisor = 1000
+session.gc_maxlifetime = 1440
+session.referer_check =
+session.entropy_length = 0
+session.cache_limiter = nocache
+session.cache_expire = 180
+session.use_trans_sid = 0
+session.hash_function = 0
+session.hash_bits_per_character = 5
+url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
+[MSSQL]
+mssql.allow_persistent = On
+mssql.max_persistent = -1
+mssql.max_links = -1
+mssql.min_error_severity = 10
+mssql.min_message_severity = 10
+mssql.compatibility_mode = Off
+mssql.secure_connection = Off
+
+[Tidy]
+tidy.clean_output = Off
+
+[soap]
+soap.wsdl_cache_enabled=1
+soap.wsdl_cache_dir="/tmp"
+soap.wsdl_cache_ttl=86400
+soap.wsdl_cache_limit = 5
+
+[ldap]
+ldap.max_links = -1
+
+[gettext]
+extension="gettext.so"
+
+[opcache]
+zend_extension="opcache.so"
+opcache.enable=1
+opcache.enable_cli=1
+opcache.memory_consumption=1000
+opcache.interned_strings_buffer=4
+opcache.max_accelerated_files=100000
+opcache.max_wasted_percentage=5
+opcache.revalidate_freq=0
+
+[apcu]
+extension="apcu.so"
+apc.enabled = 1
+apc.shm_size = 3000M
+apc.entries_hint = 500000
+apc.enable_cli = 1
+apc.mmap_file_mask = /tmp/apc.XXXXXX
+apc.rfc1867 = 1
+apc.include_once_override = 0
+
+[xdebug]
+html_errors=on
+xdebug.remote_autostart=on
+xdebug.remote_enable=on
+xdebug.remote_log="/tmp/xdebug.log"
+xdebug.default_enable=1
+xdebug.idekey="phpcontainer"
+xdebug.remote_host="172.17.42.1"
+xdebug.remote_port="9000"
+
+[Date]
+date.timezone = UTC
+
+[yaml]
+extension=yaml
diff --git a/php/8.3-ubuntu-frankenphp/conf/php/php.ini b/php/8.3-ubuntu-frankenphp/conf/php/php.ini
new file mode 100644
index 0000000000000000000000000000000000000000..cc9faf73b8116130a411d59fc9877b02852ac0ff
--- /dev/null
+++ b/php/8.3-ubuntu-frankenphp/conf/php/php.ini
@@ -0,0 +1,202 @@
+[PHP]
+engine = On
+short_open_tag = Off
+asp_tags = Off
+precision = 14
+output_buffering = 4096
+zlib.output_compression = Off
+implicit_flush = Off
+unserialize_callback_func =
+serialize_precision = -1
+disable_functions =
+disable_classes =
+zend.enable_gc = On
+expose_php = On
+max_execution_time = 300
+max_input_time = 60
+memory_limit = 320M
+error_reporting = E_ALL & ~E_DEPRECATED
+display_errors = Off
+display_startup_errors = Off
+log_errors = On
+log_errors_max_len = 1024
+ignore_repeated_errors = Off
+ignore_repeated_source = Off
+report_memleaks = On
+track_errors = Off
+html_errors = Off
+variables_order = "GPCS"
+request_order = "GP"
+register_argc_argv = Off
+auto_globals_jit = On
+post_max_size = 8M
+auto_prepend_file =
+auto_append_file =
+default_mimetype = "text/html"
+doc_root =
+user_dir =
+enable_dl = Off
+file_uploads = On
+upload_max_filesize = 8M
+max_file_uploads = 20
+allow_url_fopen = On
+allow_url_include = Off
+default_socket_timeout = 60
+assert.exception = 1
+[CLI Server]
+cli_server.color = On
+
+
+[Pdo_mysql]
+pdo_mysql.cache_size = 2000
+pdo_mysql.default_socket=
+[Phar]
+[Syslog]
+define_syslog_variables  = Off
+[mail function]
+SMTP = localhost
+smtp_port = 25
+mail.add_x_header = On
+[SQL]
+sql.safe_mode = Off
+[ODBC]
+odbc.allow_persistent = On
+odbc.check_persistent = On
+odbc.max_persistent = -1
+odbc.max_links = -1
+odbc.defaultlrl = 4096
+odbc.defaultbinmode = 1
+[Interbase]
+ibase.allow_persistent = 1
+ibase.max_persistent = -1
+ibase.max_links = -1
+ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
+ibase.dateformat = "%Y-%m-%d"
+ibase.timeformat = "%H:%M:%S"
+[MySQL]
+mysql.allow_local_infile = On
+mysql.allow_persistent = On
+mysql.cache_size = 2000
+mysql.max_persistent = -1
+mysql.max_links = -1
+mysql.default_port =
+mysql.default_socket =
+mysql.default_host =
+mysql.default_user =
+mysql.default_password =
+mysql.connect_timeout = 60
+mysql.trace_mode = Off
+[MySQLi]
+mysqli.max_persistent = -1
+mysqli.allow_persistent = On
+mysqli.max_links = -1
+mysqli.cache_size = 2000
+mysqli.default_port = 3306
+mysqli.default_socket =
+mysqli.default_host =
+mysqli.default_user =
+mysqli.default_pw =
+mysqli.reconnect = Off
+[mysqlnd]
+mysqlnd.collect_statistics = On
+mysqlnd.collect_memory_statistics = Off
+[OCI8]
+[PostgreSQL]
+pgsql.allow_persistent = On
+pgsql.auto_reset_persistent = Off
+pgsql.max_persistent = -1
+pgsql.max_links = -1
+pgsql.ignore_notice = 0
+pgsql.log_notice = 0
+[Sybase-CT]
+sybct.allow_persistent = On
+sybct.max_persistent = -1
+sybct.max_links = -1
+sybct.min_server_severity = 10
+sybct.min_client_severity = 10
+[bcmath]
+bcmath.scale = 0
+[browscap]
+[Session]
+session.save_handler = files
+session.save_path = "/tmp"
+session.use_strict_mode = 0
+session.use_cookies = 1
+session.use_only_cookies = 1
+session.name = PHPSESSID
+session.auto_start = 0
+session.cookie_lifetime = 0
+session.cookie_path = /
+session.cookie_domain =
+session.cookie_httponly =
+session.serialize_handler = php
+session.gc_probability = 1
+session.gc_divisor = 1000
+session.gc_maxlifetime = 1440
+session.referer_check =
+session.entropy_length = 0
+session.cache_limiter = nocache
+session.cache_expire = 180
+session.use_trans_sid = 0
+session.hash_function = 0
+session.hash_bits_per_character = 5
+url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
+[MSSQL]
+mssql.allow_persistent = On
+mssql.max_persistent = -1
+mssql.max_links = -1
+mssql.min_error_severity = 10
+mssql.min_message_severity = 10
+mssql.compatibility_mode = Off
+mssql.secure_connection = Off
+
+[Tidy]
+tidy.clean_output = Off
+
+[soap]
+soap.wsdl_cache_enabled=1
+soap.wsdl_cache_dir="/tmp"
+soap.wsdl_cache_ttl=86400
+soap.wsdl_cache_limit = 5
+
+[ldap]
+ldap.max_links = -1
+
+[gettext]
+extension="gettext.so"
+
+[opcache]
+zend_extension="opcache.so"
+opcache.enable=1
+opcache.enable_cli=1
+opcache.memory_consumption=1000
+opcache.interned_strings_buffer=4
+opcache.max_accelerated_files=100000
+opcache.max_wasted_percentage=5
+opcache.revalidate_freq=0
+
+[apcu]
+extension="apcu.so"
+apc.enabled = 1
+apc.shm_size = 3000M
+apc.entries_hint = 500000
+apc.enable_cli = 1
+apc.mmap_file_mask = /tmp/apc.XXXXXX
+apc.rfc1867 = 1
+apc.include_once_override = 0
+
+[xdebug]
+html_errors=on
+xdebug.remote_autostart=on
+xdebug.remote_enable=on
+xdebug.remote_log="/tmp/xdebug.log"
+xdebug.default_enable=1
+xdebug.idekey="phpcontainer"
+xdebug.remote_host="172.17.42.1"
+xdebug.remote_port="9000"
+
+[Date]
+date.timezone = UTC
+
+[yaml]
+extension=yaml
diff --git a/php/8.3-ubuntu-frankenphp/conf/supervisor-phantomjs.conf b/php/8.3-ubuntu-frankenphp/conf/supervisor-phantomjs.conf
new file mode 100644
index 0000000000000000000000000000000000000000..92c1bd774978636e06231329e04c007bd7b10601
--- /dev/null
+++ b/php/8.3-ubuntu-frankenphp/conf/supervisor-phantomjs.conf
@@ -0,0 +1,9 @@
+[program:phantomjs]
+command=/usr/bin/phantomjs --ssl-protocol=any --debug=true --ignore-ssl-errors=true /var/www/html/vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768
+directory=/var/www/html
+autostart=false
+autorestart=true
+startretries=5
+stderr_logfile=/var/log/supervisor/phantomjs.err.log
+stdout_logfile=/var/log/supervisor/phantomjs.out.log
+user=www-data
diff --git a/php/8.3-ubuntu-frankenphp/docker-php-entrypoint b/php/8.3-ubuntu-frankenphp/docker-php-entrypoint
new file mode 100755
index 0000000000000000000000000000000000000000..08c367f52bfa7328be997f170c5904dbaaaea446
--- /dev/null
+++ b/php/8.3-ubuntu-frankenphp/docker-php-entrypoint
@@ -0,0 +1,5 @@
+#!/bin/sh
+set -e
+
+/usr/bin/supervisord -c /etc/supervisor/supervisord.conf
+exec "$@"
diff --git a/php/8.3-ubuntu-frankenphp/docker-php-ext-configure b/php/8.3-ubuntu-frankenphp/docker-php-ext-configure
new file mode 100755
index 0000000000000000000000000000000000000000..93d31601c9dc4c88fac2681d5d35e094e2e5cf52
--- /dev/null
+++ b/php/8.3-ubuntu-frankenphp/docker-php-ext-configure
@@ -0,0 +1,58 @@
+#!/bin/sh
+set -e
+
+# prefer user supplied CFLAGS, but default to our PHP_CFLAGS
+: ${CFLAGS:=$PHP_CFLAGS}
+: ${CPPFLAGS:=$PHP_CPPFLAGS}
+: ${LDFLAGS:=$PHP_LDFLAGS}
+export CFLAGS CPPFLAGS LDFLAGS
+
+srcExists=
+if [ -d /usr/src/php ]; then
+	srcExists=1
+fi
+docker-php-source extract
+if [ -z "$srcExists" ]; then
+	touch /usr/src/php/.docker-delete-me
+fi
+
+cd /usr/src/php/ext
+
+ext="$1"
+if [ -z "$ext" ] || [ ! -d "$ext" ]; then
+	echo >&2 "usage: $0 ext-name [configure flags]"
+	echo >&2 "   ie: $0 gd --with-jpeg-dir=/usr/local/something"
+	echo >&2
+	echo >&2 'Possible values for ext-name:'
+	find /usr/src/php/ext \
+			-mindepth 2 \
+			-maxdepth 2 \
+			-type f \
+			-name 'config.m4' \
+		| xargs -n1 dirname \
+		| xargs -n1 basename \
+		| sort \
+		| xargs
+	exit 1
+fi
+shift
+
+pm='unknown'
+if [ -e /lib/apk/db/installed ]; then
+	pm='apk'
+fi
+
+if [ "$pm" = 'apk' ]; then
+	if \
+		[ -n "$PHPIZE_DEPS" ] \
+		&& ! apk info --installed .phpize-deps > /dev/null \
+		&& ! apk info --installed .phpize-deps-configure > /dev/null \
+	; then
+		apk add --no-cache --virtual .phpize-deps-configure $PHPIZE_DEPS
+	fi
+fi
+
+set -x
+cd "$ext"
+phpize
+./configure "$@"
diff --git a/php/8.3-ubuntu-frankenphp/docker-php-ext-enable b/php/8.3-ubuntu-frankenphp/docker-php-ext-enable
new file mode 100755
index 0000000000000000000000000000000000000000..da303abc38e12ec1281ca8ad6acb043f469b3c86
--- /dev/null
+++ b/php/8.3-ubuntu-frankenphp/docker-php-ext-enable
@@ -0,0 +1,83 @@
+#!/bin/sh
+set -e
+
+cd "$(php -r 'echo ini_get("extension_dir");')"
+
+usage() {
+	echo "usage: $0 [options] module-name [module-name ...]"
+	echo "   ie: $0 gd mysqli"
+	echo "       $0 pdo pdo_mysql"
+	echo "       $0 --ini-name 0-apc.ini apcu apc"
+	echo
+	echo 'Possible values for module-name:'
+	echo $(find -maxdepth 1 -type f -name '*.so' -exec basename '{}' ';' | sort)
+}
+
+opts="$(getopt -o 'h?' --long 'help,ini-name:' -- "$@" || { usage >&2 && false; })"
+eval set -- "$opts"
+
+iniName=
+while true; do
+	flag="$1"
+	shift
+	case "$flag" in
+		--help|-h|'-?') usage && exit 0 ;;
+		--ini-name) iniName="$1" && shift ;;
+		--) break ;;
+		*)
+			{
+				echo "error: unknown flag: $flag"
+				usage
+			} >&2
+			exit 1
+			;;
+	esac
+done
+
+modules=
+for module; do
+	if [ -z "$module" ]; then
+		continue
+	fi
+	if [ -f "$module.so" ] && ! [ -f "$module" ]; then
+		# allow ".so" to be optional
+		module="$module.so"
+	fi
+	if ! [ -f "$module" ]; then
+		echo >&2 "error: $(readlink -f "$module") does not exist"
+		echo >&2
+		usage >&2
+		exit 1
+	fi
+	modules="$modules $module"
+done
+
+if [ -z "$modules" ]; then
+	usage >&2
+	exit 1
+fi
+
+for module in $modules; do
+	if [ -z "$(php -dzend_extension="$module" -v 2>&1 >/dev/null)" ]; then
+		# https://wiki.php.net/internals/extensions#loading_zend_extensions
+		line="zend_extension=$(readlink -f "$module")"
+	else
+		line="extension=$module"
+	fi
+
+	ext="$(basename "$module")"
+	ext="${ext%.*}"
+	if php -r 'exit(extension_loaded("'"$ext"'") ? 0 : 1);'; then
+		# this isn't perfect, but it's better than nothing
+		# (for example, 'opcache.so' presents inside PHP as 'Zend OPcache', not 'opcache')
+		echo >&2
+		echo >&2 "warning: $ext ($module) is already loaded!"
+		echo >&2
+		continue
+	fi
+
+	ini="/usr/local/etc/php/conf.d/${iniName:-"docker-php-ext-$ext.ini"}"
+	if ! grep -q "$line" "$ini" 2>/dev/null; then
+		echo "$line" >> "$ini"
+	fi
+done
diff --git a/php/8.3-ubuntu-frankenphp/docker-php-ext-install b/php/8.3-ubuntu-frankenphp/docker-php-ext-install
new file mode 100755
index 0000000000000000000000000000000000000000..c06602302fb40ef5171b14204d29daaaa8f97db5
--- /dev/null
+++ b/php/8.3-ubuntu-frankenphp/docker-php-ext-install
@@ -0,0 +1,119 @@
+#!/bin/sh
+set -e
+
+# prefer user supplied CFLAGS, but default to our PHP_CFLAGS
+: ${CFLAGS:=$PHP_CFLAGS}
+: ${CPPFLAGS:=$PHP_CPPFLAGS}
+: ${LDFLAGS:=$PHP_LDFLAGS}
+export CFLAGS CPPFLAGS LDFLAGS
+
+srcExists=
+if [ -d /usr/src/php ]; then
+	srcExists=1
+fi
+docker-php-source extract
+if [ -z "$srcExists" ]; then
+	touch /usr/src/php/.docker-delete-me
+fi
+
+cd /usr/src/php/ext
+
+usage() {
+	echo "usage: $0 [-jN] ext-name [ext-name ...]"
+	echo "   ie: $0 gd mysqli"
+	echo "       $0 pdo pdo_mysql"
+	echo "       $0 -j5 gd mbstring mysqli pdo pdo_mysql shmop"
+	echo
+	echo 'if custom ./configure arguments are necessary, see docker-php-ext-configure'
+	echo
+	echo 'Possible values for ext-name:'
+	find . \
+			-mindepth 2 \
+			-maxdepth 2 \
+			-type f \
+			-name 'config.m4' \
+		| xargs -n1 dirname \
+		| xargs -n1 basename \
+		| sort \
+		| xargs
+}
+
+opts="$(getopt -o 'h?j:' --long 'help,jobs:' -- "$@" || { usage >&2 && false; })"
+eval set -- "$opts"
+
+j=1
+while true; do
+	flag="$1"
+	shift
+	case "$flag" in
+		--help|-h|'-?') usage && exit 0 ;;
+		--jobs|-j) j="$1" && shift ;;
+		--) break ;;
+		*)
+			{
+				echo "error: unknown flag: $flag"
+				usage
+			} >&2
+			exit 1
+			;;
+	esac
+done
+
+exts=
+for ext; do
+	if [ -z "$ext" ]; then
+		continue
+	fi
+	if [ ! -d "$ext" ]; then
+		echo >&2 "error: $PWD/$ext does not exist"
+		echo >&2
+		usage >&2
+		exit 1
+	fi
+	exts="$exts $ext"
+done
+
+if [ -z "$exts" ]; then
+	usage >&2
+	exit 1
+fi
+
+pm='unknown'
+if [ -e /lib/apk/db/installed ]; then
+	pm='apk'
+fi
+
+apkDel=
+if [ "$pm" = 'apk' ]; then
+	if [ -n "$PHPIZE_DEPS" ]; then
+		if apk info --installed .phpize-deps-configure > /dev/null; then
+			apkDel='.phpize-deps-configure'
+		elif ! apk info --installed .phpize-deps > /dev/null; then
+			apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS
+			apkDel='.phpize-deps'
+		fi
+	fi
+fi
+
+popDir="$PWD"
+for ext in $exts; do
+	cd "$ext"
+	[ -e Makefile ] || docker-php-ext-configure "$ext"
+	make -j"$j"
+	make -j"$j" install
+	find modules \
+		-maxdepth 1 \
+		-name '*.so' \
+		-exec basename '{}' ';' \
+			| xargs -r docker-php-ext-enable
+	make -j"$j" clean
+	cd "$popDir"
+done
+
+if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then
+	apk del $apkDel
+fi
+
+if [ -e /usr/src/php/.docker-delete-me ]; then
+	docker-php-source delete
+fi
diff --git a/php/8.3-ubuntu-frankenphp/docker-php-ext-pecl-install b/php/8.3-ubuntu-frankenphp/docker-php-ext-pecl-install
new file mode 100755
index 0000000000000000000000000000000000000000..bef41910b51f3c508660746ea715b2ad0913d16c
--- /dev/null
+++ b/php/8.3-ubuntu-frankenphp/docker-php-ext-pecl-install
@@ -0,0 +1,36 @@
+#!/bin/bash
+set -e
+
+usage() {
+  echo "usage: $0 [channel/]<package> ..."
+  echo "   ie: $0 uploadprogress oauth-1.2.3"
+}
+
+if [ $# -eq 0 ]; then
+  usage >&2
+  exit 1
+fi
+
+pecl install "$@"
+
+while [ $# -gt 0 ]; do
+  ext="$1"
+  ext=$(echo "$ext" | cut -d- -f1)
+  ext=$(echo "$ext" | cut -d\/ -f2)
+  shift
+
+  for module in $(find /usr/local/lib/php/extensions -name "$ext.so"); do
+    ini="/usr/local/etc/php/conf.d/docker-php-pecl-$ext.ini"
+    if grep -q zend_extension_entry "$module"; then
+      # https://wiki.php.net/internals/extensions#loading_zend_extensions
+      line="zend_extension=$(readlink -f "$module")"
+    else
+      line="extension=$(basename "$module")"
+    fi
+    if ! grep -q "$line" "$ini" 2>/dev/null; then
+      echo "$line" >> "$ini"
+    fi
+  done
+done
+
+rm -rf /tmp/*
diff --git a/php/8.3-ubuntu-frankenphp/docker-php-source b/php/8.3-ubuntu-frankenphp/docker-php-source
new file mode 100755
index 0000000000000000000000000000000000000000..da7c90bc671883da1a764bf08ea87ec1c806b08c
--- /dev/null
+++ b/php/8.3-ubuntu-frankenphp/docker-php-source
@@ -0,0 +1,35 @@
+#!/bin/sh
+set -e
+
+dir=/usr/src/php
+
+usage() {
+	echo "usage: $0 COMMAND"
+	echo
+	echo "Manage php source tarball lifecycle."
+	echo
+	echo "Commands:"
+	echo "   extract  extract php source tarball into directory $dir if not already done."
+	echo "   delete   delete extracted php source located into $dir if not already done."
+	echo
+}
+
+case "$1" in
+	extract)
+		mkdir -p "$dir"
+
+		if [ ! -f "$dir/.docker-extracted" ]; then
+			tar -Jxf /usr/src/php.tar.xz -C "$dir" --strip-components=1
+			touch "$dir/.docker-extracted"
+		fi
+		;;
+
+	delete)
+		rm -rf /usr/src/php.tar.xz
+		;;
+
+	*)
+		usage
+		exit 1
+		;;
+esac