SlideShare a Scribd company logo
1 of 74
Download to read offline
Building a General Purpose
PHP Docker Image
Robert Lemke
Robert Lemke
Flownative Managing Partner
Neos CMS Project Founder
Robert Lemke
Flownative Managing Partner
Neos CMS Project Founder
Robert Lemke
Co-Founder Flownative
Founder Neos CMS Project
Creating software since 1985
PHP since 1998
Robert Lemke
Flownative Managing Partner
Neos CMS Project Founder
PHP Image
for Development
and Production
Dev Toolbox vs.
Prod Parity
Base Image
Base Image
- standards and tooling for other images
- common tools for application usage
! create your own base image
! reduce to a minimum, but not less
Which OS?
Alpine Linux
- smaller filesystem footprint
- more secure?
- only relevant in container context
- uses musl instead of glibc "
Which OS?
Debian
- larger filesystem footprint
- well-established security team
- wide-spread, therefore more first-hand
experience
- high compatibility due to glibc
Which OS?
! You need to feel comfortable working
with the OS and it must support all the
software you want to install
0
30
60
90
120
ubuntu:jammy debian:bullseye bitnami/minideb:bullseye alpine:latest
5,29 MB
72 MB
118 MB
69 MB
Does the image size
really matter?
Due to layering not so much if most
containers use the same base image
https://github.com/wagoodman/dive
dive
bash:$
Hello World
Base Image
FROM bitnami/minideb:bullseye
COPY root-files /
RUN /build.sh "# rm /build.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD [ "run" ]
FROM bitnami/minideb:bullseye
LABEL org.opencontainers.image.authors="Robert Lemke <robert@flownative.com>"
ARG BUILD_DATE
LABEL com.flownative.base-image-build-date=$BUILD_DATE
COPY root-files /
RUN /build.sh "# rm /build.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD [ "run" ]
FROM bitnami/minideb:bullseye
LABEL org.opencontainers.image.authors="Robert Lemke <robert@flownative.com>"
ARG BUILD_DATE
LABEL com.flownative.base-image-build-date=$BUILD_DATE
ENV FLOWNATIVE_LIB_PATH="/opt/flownative/lib" 
LOG_DEBUG=true
COPY "$from=flownative/bash-library:1.13.5 /lib $FLOWNATIVE_LIB_PATH
COPY root-files /
RUN /build.sh "# rm /build.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD [ "run" ]
!"/bin/bash
# Load helper libraries
. "${FLOWNATIVE_LIB_PATH}/log.sh"
. "${FLOWNATIVE_LIB_PATH}/banner.sh"
. "${FLOWNATIVE_LIB_PATH}/packages.sh"
set -o errexit
set -o nounset
set -o pipefail
# ---------------------------------------------------------------------------------------
# Main routine
export FLOWNATIVE_LOG_PATH_AND_FILENAME=/dev/stdout
banner_flownative 'Demo Base Image'
packages_install dpkg apt-utils ca-certificates syslog-ng logrotate
# Clean up
rm -rf 
/var/cache"% 
/var/log"%
!"/bin/bash
set -o errexit
set -o nounset
set -o pipefail
. "${FLOWNATIVE_LIB_PATH}/banner.sh"
banner_flownative "Demo Base Image"
sleep 3600
Supervisor
FROM flownative/base:bullseye
LABEL org.opencontainers.image.authors="Robert Lemke <robert@flownative.com>"
ENV PHP_BASE_PATH="/opt/flownative/php" 
PATH="/opt/flownative/php/bin:$PATH" 
LOG_DEBUG="false"
COPY root-files /
RUN export FLOWNATIVE_LOG_PATH_AND_FILENAME=/dev/stdout 
"# /build.sh init 
"# /build.sh clean
WORKDIR ${PHP_BASE_PATH}
ENTRYPOINT [ "/entrypoint.sh" ]
CMD [ "run" ]
!"/bin/bash
set -o errexit
set -o nounset
set -o pipefail
# Load lib
. "${FLOWNATIVE_LIB_PATH}/syslog-ng.sh"
. "${FLOWNATIVE_LIB_PATH}/supervisor.sh"
. "${FLOWNATIVE_LIB_PATH}/banner.sh"
banner_flownative "Demo Base Image"
eval "$(syslog_env)"
syslog_initialize
syslog_start
eval "$(supervisor_env)"
supervisor_initialize
supervisor_start
trap 'supervisor_stop; syslog_stop' SIGINT SIGTERM
if [[ "$*" = *"run"* ]]; then
supervisor_pid=$(supervisor_get_pid)
info "Entrypoint: Start up complete"
# We can't use "wait" because supervisord is not a direct child of this shell:
while [ -e "/proc/${supervisor_pid}" ]; do sleep 1.1; done
info "Good bye #"
else
"$@"
fi
Pod
Structure
PHP-FPM Image
FROM flownative/base:bullseye
LABEL org.opencontainers.image.authors="Robert Lemke <robert@flownative.com>"
# -----------------------------------------------------------------------------
# PHP
# Latest versions: https:"#www.php.net/downloads.php
ARG PHP_VERSION
ENV PHP_VERSION ${PHP_VERSION}
ENV PHP_BASE_PATH="/opt/flownative/php" 
PATH="/opt/flownative/php/bin:$PATH" 
LOG_DEBUG="false"
USER root
COPY root-files /
RUN export FLOWNATIVE_LOG_PATH_AND_FILENAME=/dev/stdout 
"# /build.sh init 
"# /build.sh clean
USER 1000
EXPOSE 9000 9001
WORKDIR ${PHP_BASE_PATH}
ENTRYPOINT [ "/entrypoint.sh" ]
CMD [ "run" ]
!"/bin/bash
[…]
# ---------------------------------------------------------------------------------------
# build_create_directories() - Create directories and set access rights accordingly
#
# @global PHP_BASE_PATH
# @global BEACH_APPLICATION_PATH
# @return void
#
build_create_directories() {
mkdir -p 
"${PHP_BASE_PATH}/bin" 
"${PHP_BASE_PATH}/etc/conf.d" 
"${PHP_BASE_PATH}/ext" 
"${PHP_BASE_PATH}/tmp" 
"${PHP_BASE_PATH}/log"
}
# ---------------------------------------------------------------------------------------
# build_adjust_permissions() - Adjust permissions for a few paths and files
#
# @global PHP_BASE_PATH
# @return void
#
build_adjust_permissions() {
chown -R root:root "${PHP_BASE_PATH}"
chmod -R g+rwX "${PHP_BASE_PATH}"
chown -R 1000 
"${PHP_BASE_PATH}/etc" 
"${PHP_BASE_PATH}/tmp"
}
# ---------------------------------------------------------------------------------------
# Main routine
case $1 in
init)
banner_flownative 'PHP'
build_create_directories
"&
clean)
build_adjust_permissions
"&
esac
!"/bin/bash
set -o errexit
set -o nounset
set -o pipefail
# Load lib
. "${FLOWNATIVE_LIB_PATH}/syslog-ng.sh"
. "${FLOWNATIVE_LIB_PATH}/supervisor.sh"
. "${FLOWNATIVE_LIB_PATH}/banner.sh"
banner_flownative PHP
eval "$(syslog_env)"
syslog_initialize
syslog_start
eval "$(supervisor_env)"
supervisor_initialize
supervisor_start
trap 'supervisor_stop; syslog_stop' SIGINT SIGTERM
if [[ "$*" = *"run"* ]]; then
supervisor_pid=$(supervisor_get_pid)
info "Entrypoint: Start up complete"
# We can't use "wait" because supervisord is not a direct child of this shell:
while [ -e "/proc/${supervisor_pid}" ]; do sleep 1.1; done
info "Good bye #"
else
"$@"
fi
# ---------------------------------------------------------------------------------------
# Main routine
case $1 in
init)
banner_flownative 'PHP'
if [[ ! "${PHP_VERSION}" =~ ^8.[0-2] ]]; then
error "$ Unsupported PHP version '${PHP_VERSION}'"
exit 1
fi
build_create_directories
"&
prepare)
packages_install $(build_get_runtime_packages) 1>$(debug_device)
packages_install $(build_get_build_packages) 1>$(debug_device)
"&
build)
build_compile_php
"&
clean)
build_adjust_permissions
packages_remove $(build_get_build_packages) 1>$(debug_device)
packages_remove $(build_get_unnecessary_packages) 1>$(debug_device)
packages_remove_docs_and_caches 1>$(debug_device)
build_clean
"&
esac
# ------------------------------------------------------------------------------------------
# build_get_build_packages() - Returns a list of packages which are only needed for building
#
# @global PHP_BASE_PATH
# @return List of packages
#
build_get_build_packages() {
local packages="
autoconf
bison
build-essential
cmake
curl
file
pkg-config
re2c
unzip
libcurl4-openssl-dev
libfreetype6-dev
libgmp-dev
libicu-dev
libjpeg62-turbo-dev
libltdl-dev
libmariadb-dev
libmcrypt-dev
libonig-dev
libpng-dev
libpspell-dev
libpq-dev
libreadline6-dev
libsqlite3-dev
libssl-dev
libwebp-dev
libxml2-dev
libzip-dev
libbz2-dev
"
echo $packages
}
# ---------------------------------------------------------------------------------------
# build_get_runtime_packages() - Returns a list of packages which are needed during runtime
#
# @return List of packages
#
build_get_runtime_packages() {
local packages="
libcurl4
libjpeg62
libonig5
libpq5
libreadline8
libsodium-dev
libssl1.1
libzip4
libbz2-1.0
libncurses6
libpng16-16
libwebp6
libxml2
libsqlite3-0
"
echo $packages
}
# ---------------------------------------------------------------------------------------
# build_get_unnecessary_packages() - Not needed packages, can be removed
#
# @return List of packages
#
build_get_unnecessary_packages() {
local packages="
cmake
"
echo $packages
}
# ---------------------------------------------------------------------------------------
# Main routine
case $1 in
init)
banner_flownative 'PHP'
if [[ ! "${PHP_VERSION}" =~ ^8.[0-2] ]]; then
error "$ Unsupported PHP version '${PHP_VERSION}'"
exit 1
fi
build_create_directories
"&
prepare)
packages_install $(build_get_runtime_packages) 1>$(debug_device)
packages_install $(build_get_build_packages) 1>$(debug_device)
"&
build)
build_compile_php
"&
clean)
build_adjust_permissions
packages_remove $(build_get_build_packages) 1>$(debug_device)
packages_remove $(build_get_unnecessary_packages) 1>$(debug_device)
packages_remove_docs_and_caches 1>$(debug_device)
build_clean
"&
esac
# ---------------------------------------------------------------------------------------
# Main routine
case $1 in
init)
banner_flownative 'PHP'
if [[ ! "${PHP_VERSION}" =~ ^8.[0-2] ]]; then
error "$ Unsupported PHP version '${PHP_VERSION}'"
exit 1
fi
build_create_directories
"&
prepare)
packages_install $(build_get_runtime_packages) 1>$(debug_device)
packages_install $(build_get_build_packages) 1>$(debug_device)
"&
build)
build_compile_php
"&
clean)
build_adjust_permissions
packages_remove $(build_get_build_packages) 1>$(debug_device)
packages_remove $(build_get_unnecessary_packages) 1>$(debug_device)
packages_remove_docs_and_caches 1>$(debug_device)
build_clean
"&
esac
# ---------------------------------------------------------------------------------------
# build_compile_php() -
#
# @global PHP_BASE_PATH
# @return void
#
build_compile_php() {
local php_source_url
php_source_url="https:"'www.php.net/distributions/php-${PHP_VERSION}.tar.gz"
info "$ Downloading source code for PHP ${PHP_VERSION} from ${php_source_url} ""("
with_backoff "curl -sSL ${php_source_url} -o php.tar.gz" "15" ") (
error "Failed downloading PHP source from ${php_source_url}"
exit 1
)
mkdir -p "${PHP_BASE_PATH}/src"
tar -xf php.tar.gz -C "${PHP_BASE_PATH}/src" "$strip-components=1
rm php.tar.gz*
cd "${PHP_BASE_PATH}/src"
info "$ Generating build configuration ""("
./buildconf "$force >$(debug_device)
if [[ ! -f configure ]]; then
error "$ Failed generating build configuration, 'configure' not found"
# shellcheck disable=SC2012
ls | output
exit 1
fi
…
# ---------------------------------------------------------------------------------------
# build_compile_php() -
#
# @global PHP_BASE_PATH
# @return void
#
build_compile_php() {
local php_source_url
php_source_url="https:"'www.php.net/distributions/php-${PHP_VERSION}.tar.gz"
info "$ Downloading source code for PHP ${PHP_VERSION} from ${php_source_url} ""("
with_backoff "curl -sSL ${php_source_url} -o php.tar.gz" "15" ") (
error "Failed downloading PHP source from ${php_source_url}"
exit 1
)
mkdir -p "${PHP_BASE_PATH}/src"
tar -xf php.tar.gz -C "${PHP_BASE_PATH}/src" "$strip-components=1
rm php.tar.gz*
cd "${PHP_BASE_PATH}/src"
info "$ Generating build configuration ""("
./buildconf "$force >$(debug_device)
if [[ ! -f configure ]]; then
error "$ Failed generating build configuration, 'configure' not found"
# shellcheck disable=SC2012
ls | output
exit 1
fi
…
…
# For GCC warning options see: https:"#gcc.gnu.org/onlinedocs/gcc-3.4.4/gcc/Warning-Options.html
export CFLAGS='-Wno-deprecated-declarations -Wno-stringop-overflow -Wno-implicit-function-declaration'
if [[ "${PHP_VERSION}" =~ ^8.[0-2] ]]; then
./configure 
"$prefix=${PHP_BASE_PATH} 
"$with-config-file-path="${PHP_BASE_PATH}/etc" 
"$with-config-file-scan-dir="${PHP_BASE_PATH}/etc/conf.d" 
"$enable-bcmath 
"$disable-cgi 
"$enable-calendar 
"$enable-exif 
"$enable-fpm 
"$enable-ftp 
"$enable-gd 
"$enable-intl 
"$enable-mbstring 
"$enable-pcntl 
"$enable-soap 
"$enable-sockets 
"$with-curl 
"$with-freetype 
"$with-gmp 
"$with-jpeg 
"$with-mysqli 
"$with-openssl 
"$with-pdo-pgsql 
"$with-pdo-mysql 
"$with-readline 
"$with-sodium 
"$with-system-ciphers 
"$with-webp 
"$with-zip 
"$with-zlib 
"$with-bz2 
"$without-pear 
>$(debug_device)
else
error "$ No configure call available for PHP version ${PHP_VERSION}"
exit 1
fi
…
info "$ Compiling PHP ""("
make -j"$(nproc)" >$(debug_device)
make install >$(debug_device)
info "$ Cleaning up ""("
make clean >$(debug_device)
rm -rf /tmp/pear
}
# ---------------------------------------------------------------------------------------
# Main routine
case $1 in
init)
banner_flownative 'PHP'
if [[ ! "${PHP_VERSION}" =~ ^8.[0-2] ]]; then
error "$ Unsupported PHP version '${PHP_VERSION}'"
exit 1
fi
build_create_directories
"&
prepare)
packages_install $(build_get_runtime_packages) 1>$(debug_device)
packages_install $(build_get_build_packages) 1>$(debug_device)
"&
build)
build_compile_php
"&
clean)
build_adjust_permissions
packages_remove $(build_get_build_packages) 1>$(debug_device)
packages_remove $(build_get_unnecessary_packages) 1>$(debug_device)
packages_remove_docs_and_caches 1>$(debug_device)
build_clean
"&
esac
!"/bin/bash
# shellcheck disable=SC1090
set -o errexit
set -o nounset
set -o pipefail
# Load lib
. "${FLOWNATIVE_LIB_PATH}/syslog-ng.sh"
. "${FLOWNATIVE_LIB_PATH}/supervisor.sh"
. "${FLOWNATIVE_LIB_PATH}/banner.sh"
. "${FLOWNATIVE_LIB_PATH}/php-fpm.sh"
banner_flownative PHP
eval "$(syslog_env)"
syslog_initialize
syslog_start
eval "$(php_fpm_env)"
eval "$(supervisor_env)"
php_fpm_initialize
supervisor_initialize
supervisor_start
trap 'supervisor_stop; syslog_stop' SIGINT SIGTERM
if [[ "$*" = *"run"* ]]; then
supervisor_pid=$(supervisor_get_pid)
info "Entrypoint: Start up complete"
# We can't use "wait" because supervisord is not a direct child of this shell:
while [ -e "/proc/${supervisor_pid}" ]; do sleep 1.1; done
info "Good bye #"
else
"$@"
fi
# ---------------------------------------------------------------------------------------
# php_fpm_env() - Load global environment variables for configuring PHP
#
# @global PHP_* The PHP_ environment variables
# @return "export" statements which can be passed to eval()
#
php_fpm_env() {
cat "*"EOF"
export PHP_BASE_PATH="${PHP_BASE_PATH}"
export PHP_CONF_PATH="${PHP_CONF_PATH:-${PHP_BASE_PATH}/etc}"
export PHP_TMP_PATH="${PHP_TMP_PATH:-${PHP_BASE_PATH}/tmp}"
export PHP_LOG_PATH="${PHP_LOG_PATH:-${PHP_BASE_PATH}/log}"
export PHP_MEMORY_LIMIT="${PHP_MEMORY_LIMIT:-750M}"
export PHP_DATE_TIMEZONE="${PHP_DATE_TIMEZONE:-UTC}"
export PHP_DISPLAY_ERRORS="${PHP_DISPLAY_ERRORS:-off}"
export PHP_ERROR_REPORTING="${PHP_ERROR_REPORTING:-2147483647}"
export PHP_ERROR_LOG="${PHP_ERROR_LOG:-/dev/stderr}"
export PHP_OPCACHE_PRELOAD="${PHP_OPCACHE_PRELOAD:-}"
export PHP_XDEBUG_ENABLE="${PHP_XDEBUG_ENABLE:-false}"
export PHP_XDEBUG_MODE="${PHP_XDEBUG_MODE:-develop}"
export PHP_XDEBUG_DISCOVER_CLIENT_HOST="${PHP_XDEBUG_DISCOVER_CLIENT_HOST:-false}"
export PHP_XDEBUG_CLIENT_HOST="${PHP_XDEBUG_CLIENT_HOST:-}"
export PHP_XDEBUG_CONFIG="${PHP_XDEBUG_CONFIG:-}"
export XDEBUG_CONFIG="${XDEBUG_CONFIG:-${PHP_XDEBUG_CONFIG}}"
export PHP_XDEBUG_MAX_NESTING_LEVEL="${PHP_XDEBUG_MAX_NESTING_LEVEL:-512}"
export PHP_IGBINARY_ENABLE="${PHP_IGBINARY_ENABLE:-false}"
export PHP_FPM_USER="1000"
export PHP_FPM_GROUP="1000"
export PHP_FPM_PORT="${PHP_FPM_PORT:-9000}"
export PHP_FPM_PM_MODE="${PHP_FPM_PM_MODE:-ondemand}"
export PHP_FPM_MAX_CHILDREN="${PHP_FPM_MAX_CHILDREN:-20}"
export PHP_FPM_ERROR_LOG_PATH="${PHP_FPM_ERROR_LOG_PATH:-/opt/flownative/log/php-fpm-error.log}"
export PHP_FPM_ACCESS_LOG_PATH="${PHP_FPM_ACCESS_LOG_PATH:-/opt/flownative/log/php-fpm-access.log}"
EOF
}
[global]
error_log = ${PHP_FPM_ERROR_LOG_PATH}
pid = ${PHP_TMP_PATH}/php-fpm.pid
; don't daemonize, because we want to start PHP as a child process of
; the shell running php-fpm.sh, so we can wait for it with "wait":
daemonize = no
[www]
access.log = ${PHP_FPM_ACCESS_LOG_PATH}
listen = ["+]:${PHP_FPM_PORT}
pm = ${PHP_FPM_PM_MODE}
pm.max_children = ${PHP_FPM_MAX_CHILDREN}
pm.status_path = /php-fpm-status
clear_env = no
# ---------------------------------------------------------------------------------------
# php_fpm_initialize() - Initialize PHP configuration and check required files and dirs
#
# @global PHP_* The PHP_* environment variables
# @return void
#
php_fpm_initialize() {
if [[ $(id "$user) ", 0 ]]; then
error "PHP-FPM: Container is running as root, but only unprivileged users are supported"
exit 1
fi;
info "PHP-FPM: Initializing configuration ""("
envsubst < "${PHP_CONF_PATH}/php-fpm.conf.template" > "${PHP_CONF_PATH}/php-fpm.conf"
if is_boolean_yes "${PHP_XDEBUG_ENABLE}"; then
info "PHP-FPM: Xdebug is enabled"
mv "${PHP_CONF_PATH}/conf.d/php-ext-xdebug.ini.inactive" "${PHP_CONF_PATH}/conf.d/php-ext-xdebug.ini"
else
info "PHP-FPM: Xdebug is disabled"
export PHP_XDEBUG_MODE="off"
fi
if is_boolean_yes "${PHP_IGBINARY_ENABLE}"; then
# igbinary might have been enabled already by scripts in an Docker image which is based on this one
if [ -f "${PHP_CONF_PATH}/conf.d/php-ext-igbinary.ini.inactive" ]; then
info "PHP-FPM: igbinary is enabled"
mv -f "${PHP_CONF_PATH}/conf.d/php-ext-igbinary.ini.inactive" "${PHP_CONF_PATH}/conf.d/php-ext-igbinary.ini"
fi
else
info "PHP-FPM: igbinary is disabled"
fi
# Create a file descriptor for the PHP-FPM log output and clean up the log lines a bit:
exec 4> >(sed -e "s/^([0-9"--]* [0-9:,]*)".1 OUTPUT PHP-FPM:/")
}
# ---------------------------------------------------------------------------------------
# php_fpm_initialize() - Initialize PHP configuration and check required files and dirs
#
# @global PHP_* The PHP_* environment variables
# @return void
#
php_fpm_initialize() {
if [[ $(id "$user) ", 0 ]]; then
error "PHP-FPM: Container is running as root, but only unprivileged users are supported"
exit 1
fi;
info "PHP-FPM: Initializing configuration ""("
envsubst < "${PHP_CONF_PATH}/php-fpm.conf.template" > "${PHP_CONF_PATH}/php-fpm.conf"
if is_boolean_yes "${PHP_XDEBUG_ENABLE}"; then
info "PHP-FPM: Xdebug is enabled"
mv "${PHP_CONF_PATH}/conf.d/php-ext-xdebug.ini.inactive" "${PHP_CONF_PATH}/conf.d/php-ext-xdebug.ini"
else
info "PHP-FPM: Xdebug is disabled"
export PHP_XDEBUG_MODE="off"
fi
if is_boolean_yes "${PHP_IGBINARY_ENABLE}"; then
# igbinary might have been enabled already by scripts in an Docker image which is based on this one
if [ -f "${PHP_CONF_PATH}/conf.d/php-ext-igbinary.ini.inactive" ]; then
info "PHP-FPM: igbinary is enabled"
mv -f "${PHP_CONF_PATH}/conf.d/php-ext-igbinary.ini.inactive" "${PHP_CONF_PATH}/conf.d/php-ext-igbinary.ini"
fi
else
info "PHP-FPM: igbinary is disabled"
fi
# Create a file descriptor for the PHP-FPM log output and clean up the log lines a bit:
exec 4> >(sed -e "s/^([0-9"--]* [0-9:,]*)".1 OUTPUT PHP-FPM:/")
}
[program:php-fpm]
process_name=%(program_name)s
command="%(ENV_PHP_BASE_PATH)s/sbin/php-fpm"
autostart=true
autorestart=true
numprocs=1
Docker Compose
version: '3.7'
services:
webserver:
image: flownative/nginx:latest
container_name: ipc_muc_2023_webserver
ports:
- "8080"
volumes:
- ./:/application
environment:
- BEACH_PHP_FPM_HOST=ipc_muc_2023_php
php:
image: flownative/php:8.2
container_name: ipc_muc_2023_php
ports:
- "9000"
- "9003"
security_opt:
- no-new-privileges
volumes:
- ./:/application
environment:
- PHP_DISPLAY_ERRORS=on
<?php
echo "Hello world!";
Application Image
FROM scratch
MAINTAINER Flownative <support@flownative.com>
VOLUME /build
COPY DistributionPackages /build/DistributionPackages
COPY Packages /build/Packages
COPY bin /build/bin
COPY Web /build/Web
COPY flow /build/flow
COPY composer.json /build/composer.json
COPY composer.lock /build/composer.lock
COPY Configuration /build/Configuration
FROM scratch busybox:latest
MAINTAINER Flownative <support@flownative.com>
VOLUME /build
COPY DistributionPackages /build/DistributionPackages
COPY Packages /build/Packages
COPY bin /build/bin
COPY Web /build/Web
COPY flow /build/flow
COPY composer.json /build/composer.json
COPY composer.lock /build/composer.lock
COPY Configuration /build/Configuration
Google Cloud
https://cloud.google.com/artifact-registry/
Harbor
https://goharbor.io
GitLab Container Registry
https://gitlab.com
Builds
%
Nightly Rebuilds
&
Nightly Rebuilds
announce:
runs-on: ubuntu-latest
needs: build
steps:
- name: Dispatch to beach-php
uses: peter-evans/repository-dispatch@v1
with:
token: ${{ secrets.FLOWNATIVE_BOT_TOKEN }}
repository: flownative/docker-beach-php
event-type: php-images-built
client-payload: '{"image_name": "flownative/docker-php/php"}'
Build Cascade
name: Build Docker images
on:
repository_dispatch:
types: [php-images-built]
push:
branches-ignore:
- '**'
tags:
- 'v*.*.*'
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
Build Cascade
Image Security
- don't run as root (use SecurityContext)
- disable privilege escalation
- automatically scan images
- redeploy automatically, frequently
- only include minimal amount of
software – do you really need a shell?
https://github.com/robertlemke/ipc-muc-2023
Demo Repository
https://github.com/flownative/?q=docker-
flownative/docker-php
https://github.com/flownative/?q=docker-
flownative/bash-library
And what about …?
ddev
performance
Mutagen
SSH
TLS
Xdebug
extensions
Kubernetes
Colima
logging
Your thoughts?
slideshare.net/robertlemke
robert@flownative.com
www.flownative.com
@robert@flownative.social
@lem.ke

More Related Content

Similar to A General Purpose Docker Image for PHP

Chef - industrialize and automate your infrastructure
Chef - industrialize and automate your infrastructureChef - industrialize and automate your infrastructure
Chef - industrialize and automate your infrastructureMichaël Lopez
 
Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !
Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !
Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !Pierre-jean Texier
 
Automate Yo'self -- SeaGL
Automate Yo'self -- SeaGL Automate Yo'self -- SeaGL
Automate Yo'self -- SeaGL John Anderson
 
Website releases made easy with the PEAR installer, OSCON 2009
Website releases made easy with the PEAR installer, OSCON 2009Website releases made easy with the PEAR installer, OSCON 2009
Website releases made easy with the PEAR installer, OSCON 2009Helgi Þormar Þorbjörnsson
 
Composer for Busy Developers - php|tek13
Composer for Busy Developers - php|tek13Composer for Busy Developers - php|tek13
Composer for Busy Developers - php|tek13Rafael Dohms
 
Ruby and Rails Packaging to Production
Ruby and Rails Packaging to ProductionRuby and Rails Packaging to Production
Ruby and Rails Packaging to ProductionFabio Kung
 
Deployment Tactics
Deployment TacticsDeployment Tactics
Deployment TacticsIan Barber
 
2012 coscup - Build your PHP application on Heroku
2012 coscup - Build your PHP application on Heroku2012 coscup - Build your PHP application on Heroku
2012 coscup - Build your PHP application on Herokuronnywang_tw
 
OSDC 2014: Ole Michaelis & Sönke Rümpler: Make it SOLID - Software Architectu...
OSDC 2014: Ole Michaelis & Sönke Rümpler: Make it SOLID - Software Architectu...OSDC 2014: Ole Michaelis & Sönke Rümpler: Make it SOLID - Software Architectu...
OSDC 2014: Ole Michaelis & Sönke Rümpler: Make it SOLID - Software Architectu...NETWAYS
 
DevOps in PHP environment
DevOps in PHP environment DevOps in PHP environment
DevOps in PHP environment Evaldo Felipe
 
Ansible tips & tricks
Ansible tips & tricksAnsible tips & tricks
Ansible tips & tricksbcoca
 
Puppet Troubleshooting
Puppet TroubleshootingPuppet Troubleshooting
Puppet TroubleshootingPuppet
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppSmartLogic
 
Composer for busy developers - DPC13
Composer for busy developers - DPC13Composer for busy developers - DPC13
Composer for busy developers - DPC13Rafael Dohms
 

Similar to A General Purpose Docker Image for PHP (20)

Chef - industrialize and automate your infrastructure
Chef - industrialize and automate your infrastructureChef - industrialize and automate your infrastructure
Chef - industrialize and automate your infrastructure
 
Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !
Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !
Diving into SWUpdate: adding new platform support in 30minutes with Yocto/OE !
 
Automate Yo'self -- SeaGL
Automate Yo'self -- SeaGL Automate Yo'self -- SeaGL
Automate Yo'self -- SeaGL
 
Php task runners
Php task runnersPhp task runners
Php task runners
 
Website releases made easy with the PEAR installer, OSCON 2009
Website releases made easy with the PEAR installer, OSCON 2009Website releases made easy with the PEAR installer, OSCON 2009
Website releases made easy with the PEAR installer, OSCON 2009
 
PHP selber bauen
PHP selber bauenPHP selber bauen
PHP selber bauen
 
Composer for Busy Developers - php|tek13
Composer for Busy Developers - php|tek13Composer for Busy Developers - php|tek13
Composer for Busy Developers - php|tek13
 
Ruby and Rails Packaging to Production
Ruby and Rails Packaging to ProductionRuby and Rails Packaging to Production
Ruby and Rails Packaging to Production
 
Lumen
LumenLumen
Lumen
 
Deployment Tactics
Deployment TacticsDeployment Tactics
Deployment Tactics
 
Self revisor
Self revisorSelf revisor
Self revisor
 
Docker, c'est bonheur !
Docker, c'est bonheur !Docker, c'est bonheur !
Docker, c'est bonheur !
 
2012 coscup - Build your PHP application on Heroku
2012 coscup - Build your PHP application on Heroku2012 coscup - Build your PHP application on Heroku
2012 coscup - Build your PHP application on Heroku
 
OSDC 2014: Ole Michaelis & Sönke Rümpler: Make it SOLID - Software Architectu...
OSDC 2014: Ole Michaelis & Sönke Rümpler: Make it SOLID - Software Architectu...OSDC 2014: Ole Michaelis & Sönke Rümpler: Make it SOLID - Software Architectu...
OSDC 2014: Ole Michaelis & Sönke Rümpler: Make it SOLID - Software Architectu...
 
DevOps in PHP environment
DevOps in PHP environment DevOps in PHP environment
DevOps in PHP environment
 
Ansible tips & tricks
Ansible tips & tricksAnsible tips & tricks
Ansible tips & tricks
 
Puppet Troubleshooting
Puppet TroubleshootingPuppet Troubleshooting
Puppet Troubleshooting
 
Troubleshooting Puppet
Troubleshooting PuppetTroubleshooting Puppet
Troubleshooting Puppet
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails App
 
Composer for busy developers - DPC13
Composer for busy developers - DPC13Composer for busy developers - DPC13
Composer for busy developers - DPC13
 

More from Robert Lemke

Neos Content Repository – Git for content
Neos Content Repository – Git for contentNeos Content Repository – Git for content
Neos Content Repository – Git for contentRobert Lemke
 
Scaleable PHP Applications in Kubernetes
Scaleable PHP Applications in KubernetesScaleable PHP Applications in Kubernetes
Scaleable PHP Applications in KubernetesRobert Lemke
 
Flownative Beach - Neos Meetup Hamburg 2022
Flownative Beach - Neos Meetup Hamburg 2022Flownative Beach - Neos Meetup Hamburg 2022
Flownative Beach - Neos Meetup Hamburg 2022Robert Lemke
 
GitOps with Flux - IPC Munich 2022
GitOps with Flux - IPC Munich 2022GitOps with Flux - IPC Munich 2022
GitOps with Flux - IPC Munich 2022Robert Lemke
 
OpenID Connect with Neos and Flow
OpenID Connect with Neos and FlowOpenID Connect with Neos and Flow
OpenID Connect with Neos and FlowRobert Lemke
 
Neos Conference 2019 Keynote
Neos Conference 2019 KeynoteNeos Conference 2019 Keynote
Neos Conference 2019 KeynoteRobert Lemke
 
A practical introduction to Kubernetes (IPC 2018)
A practical introduction to Kubernetes (IPC 2018)A practical introduction to Kubernetes (IPC 2018)
A practical introduction to Kubernetes (IPC 2018)Robert Lemke
 
Neos Conference 2018 Welcome Keynote
Neos Conference 2018 Welcome KeynoteNeos Conference 2018 Welcome Keynote
Neos Conference 2018 Welcome KeynoteRobert Lemke
 
A practical introduction to Event Sourcing and CQRS
A practical introduction to Event Sourcing and CQRSA practical introduction to Event Sourcing and CQRS
A practical introduction to Event Sourcing and CQRSRobert Lemke
 
Neos Conference 2017 Welcome Keynote
Neos Conference 2017 Welcome KeynoteNeos Conference 2017 Welcome Keynote
Neos Conference 2017 Welcome KeynoteRobert Lemke
 
IPC16: A Practical Introduction to Kubernetes
IPC16: A Practical Introduction to Kubernetes IPC16: A Practical Introduction to Kubernetes
IPC16: A Practical Introduction to Kubernetes Robert Lemke
 
IPC 2016: Content Strategy for Developers
IPC 2016: Content Strategy for DevelopersIPC 2016: Content Strategy for Developers
IPC 2016: Content Strategy for DevelopersRobert Lemke
 
Docker in Production - IPC 2016
Docker in Production - IPC 2016Docker in Production - IPC 2016
Docker in Production - IPC 2016Robert Lemke
 
Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)
Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)
Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)Robert Lemke
 
The Neos Brand (Inspiring Conference 2016)
The Neos Brand (Inspiring Conference 2016)The Neos Brand (Inspiring Conference 2016)
The Neos Brand (Inspiring Conference 2016)Robert Lemke
 
Neos - past, present, future (Inspiring Conference 2016)
Neos - past, present, future (Inspiring Conference 2016)Neos - past, present, future (Inspiring Conference 2016)
Neos - past, present, future (Inspiring Conference 2016)Robert Lemke
 
Meet Neos Nürnberg 2016: Ja ich will!
Meet Neos Nürnberg 2016: Ja ich will!Meet Neos Nürnberg 2016: Ja ich will!
Meet Neos Nürnberg 2016: Ja ich will!Robert Lemke
 
Meet Neos Nürnberg 2016: Hallo Neos!
Meet Neos Nürnberg 2016: Hallo Neos!Meet Neos Nürnberg 2016: Hallo Neos!
Meet Neos Nürnberg 2016: Hallo Neos!Robert Lemke
 
Turning Neos inside out / React.js HH
Turning Neos inside out / React.js HHTurning Neos inside out / React.js HH
Turning Neos inside out / React.js HHRobert Lemke
 
Docker in Production - IPC 15 München
Docker in Production - IPC 15 MünchenDocker in Production - IPC 15 München
Docker in Production - IPC 15 MünchenRobert Lemke
 

More from Robert Lemke (20)

Neos Content Repository – Git for content
Neos Content Repository – Git for contentNeos Content Repository – Git for content
Neos Content Repository – Git for content
 
Scaleable PHP Applications in Kubernetes
Scaleable PHP Applications in KubernetesScaleable PHP Applications in Kubernetes
Scaleable PHP Applications in Kubernetes
 
Flownative Beach - Neos Meetup Hamburg 2022
Flownative Beach - Neos Meetup Hamburg 2022Flownative Beach - Neos Meetup Hamburg 2022
Flownative Beach - Neos Meetup Hamburg 2022
 
GitOps with Flux - IPC Munich 2022
GitOps with Flux - IPC Munich 2022GitOps with Flux - IPC Munich 2022
GitOps with Flux - IPC Munich 2022
 
OpenID Connect with Neos and Flow
OpenID Connect with Neos and FlowOpenID Connect with Neos and Flow
OpenID Connect with Neos and Flow
 
Neos Conference 2019 Keynote
Neos Conference 2019 KeynoteNeos Conference 2019 Keynote
Neos Conference 2019 Keynote
 
A practical introduction to Kubernetes (IPC 2018)
A practical introduction to Kubernetes (IPC 2018)A practical introduction to Kubernetes (IPC 2018)
A practical introduction to Kubernetes (IPC 2018)
 
Neos Conference 2018 Welcome Keynote
Neos Conference 2018 Welcome KeynoteNeos Conference 2018 Welcome Keynote
Neos Conference 2018 Welcome Keynote
 
A practical introduction to Event Sourcing and CQRS
A practical introduction to Event Sourcing and CQRSA practical introduction to Event Sourcing and CQRS
A practical introduction to Event Sourcing and CQRS
 
Neos Conference 2017 Welcome Keynote
Neos Conference 2017 Welcome KeynoteNeos Conference 2017 Welcome Keynote
Neos Conference 2017 Welcome Keynote
 
IPC16: A Practical Introduction to Kubernetes
IPC16: A Practical Introduction to Kubernetes IPC16: A Practical Introduction to Kubernetes
IPC16: A Practical Introduction to Kubernetes
 
IPC 2016: Content Strategy for Developers
IPC 2016: Content Strategy for DevelopersIPC 2016: Content Strategy for Developers
IPC 2016: Content Strategy for Developers
 
Docker in Production - IPC 2016
Docker in Production - IPC 2016Docker in Production - IPC 2016
Docker in Production - IPC 2016
 
Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)
Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)
Is this Open Source Thing Really Worth it? (IPC 2016 Berlin)
 
The Neos Brand (Inspiring Conference 2016)
The Neos Brand (Inspiring Conference 2016)The Neos Brand (Inspiring Conference 2016)
The Neos Brand (Inspiring Conference 2016)
 
Neos - past, present, future (Inspiring Conference 2016)
Neos - past, present, future (Inspiring Conference 2016)Neos - past, present, future (Inspiring Conference 2016)
Neos - past, present, future (Inspiring Conference 2016)
 
Meet Neos Nürnberg 2016: Ja ich will!
Meet Neos Nürnberg 2016: Ja ich will!Meet Neos Nürnberg 2016: Ja ich will!
Meet Neos Nürnberg 2016: Ja ich will!
 
Meet Neos Nürnberg 2016: Hallo Neos!
Meet Neos Nürnberg 2016: Hallo Neos!Meet Neos Nürnberg 2016: Hallo Neos!
Meet Neos Nürnberg 2016: Hallo Neos!
 
Turning Neos inside out / React.js HH
Turning Neos inside out / React.js HHTurning Neos inside out / React.js HH
Turning Neos inside out / React.js HH
 
Docker in Production - IPC 15 München
Docker in Production - IPC 15 MünchenDocker in Production - IPC 15 München
Docker in Production - IPC 15 München
 

Recently uploaded

Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls KolkataLow Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkataanamikaraghav4
 
Sushant Golf City / best call girls in Lucknow | Service-oriented sexy call g...
Sushant Golf City / best call girls in Lucknow | Service-oriented sexy call g...Sushant Golf City / best call girls in Lucknow | Service-oriented sexy call g...
Sushant Golf City / best call girls in Lucknow | Service-oriented sexy call g...akbard9823
 
The Intriguing World of CDR Analysis by Police: What You Need to Know.pdf
The Intriguing World of CDR Analysis by Police: What You Need to Know.pdfThe Intriguing World of CDR Analysis by Police: What You Need to Know.pdf
The Intriguing World of CDR Analysis by Police: What You Need to Know.pdfMilind Agarwal
 
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Chennai Call Girls Alwarpet Phone 🍆 8250192130 👅 celebrity escorts service
Chennai Call Girls Alwarpet Phone 🍆 8250192130 👅 celebrity escorts serviceChennai Call Girls Alwarpet Phone 🍆 8250192130 👅 celebrity escorts service
Chennai Call Girls Alwarpet Phone 🍆 8250192130 👅 celebrity escorts servicevipmodelshub1
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作ys8omjxb
 
Chennai Call Girls Porur Phone 🍆 8250192130 👅 celebrity escorts service
Chennai Call Girls Porur Phone 🍆 8250192130 👅 celebrity escorts serviceChennai Call Girls Porur Phone 🍆 8250192130 👅 celebrity escorts service
Chennai Call Girls Porur Phone 🍆 8250192130 👅 celebrity escorts servicesonalikaur4
 
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Lucknow
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一z xss
 
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一Fs
 
Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITMgdsc13
 
VIP Kolkata Call Girl Alambazar 👉 8250192130 Available With Room
VIP Kolkata Call Girl Alambazar 👉 8250192130  Available With RoomVIP Kolkata Call Girl Alambazar 👉 8250192130  Available With Room
VIP Kolkata Call Girl Alambazar 👉 8250192130 Available With Roomdivyansh0kumar0
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Dana Luther
 
VIP Kolkata Call Girl Dum Dum 👉 8250192130 Available With Room
VIP Kolkata Call Girl Dum Dum 👉 8250192130  Available With RoomVIP Kolkata Call Girl Dum Dum 👉 8250192130  Available With Room
VIP Kolkata Call Girl Dum Dum 👉 8250192130 Available With Roomdivyansh0kumar0
 
VIP Call Girls Kolkata Ananya 🤌 8250192130 🚀 Vip Call Girls Kolkata
VIP Call Girls Kolkata Ananya 🤌  8250192130 🚀 Vip Call Girls KolkataVIP Call Girls Kolkata Ananya 🤌  8250192130 🚀 Vip Call Girls Kolkata
VIP Call Girls Kolkata Ananya 🤌 8250192130 🚀 Vip Call Girls Kolkataanamikaraghav4
 
Complet Documnetation for Smart Assistant Application for Disabled Person
Complet Documnetation   for Smart Assistant Application for Disabled PersonComplet Documnetation   for Smart Assistant Application for Disabled Person
Complet Documnetation for Smart Assistant Application for Disabled Personfurqan222004
 
Denver Web Design brochure for public viewing
Denver Web Design brochure for public viewingDenver Web Design brochure for public viewing
Denver Web Design brochure for public viewingbigorange77
 

Recently uploaded (20)

Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls KolkataLow Rate Call Girls Kolkata Avani 🤌  8250192130 🚀 Vip Call Girls Kolkata
Low Rate Call Girls Kolkata Avani 🤌 8250192130 🚀 Vip Call Girls Kolkata
 
Sushant Golf City / best call girls in Lucknow | Service-oriented sexy call g...
Sushant Golf City / best call girls in Lucknow | Service-oriented sexy call g...Sushant Golf City / best call girls in Lucknow | Service-oriented sexy call g...
Sushant Golf City / best call girls in Lucknow | Service-oriented sexy call g...
 
The Intriguing World of CDR Analysis by Police: What You Need to Know.pdf
The Intriguing World of CDR Analysis by Police: What You Need to Know.pdfThe Intriguing World of CDR Analysis by Police: What You Need to Know.pdf
The Intriguing World of CDR Analysis by Police: What You Need to Know.pdf
 
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in  Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Jamuna Vihar Delhi reach out to us at 🔝9953056974🔝
 
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Uttam Nagar Delhi 💯Call Us 🔝8264348440🔝
 
Chennai Call Girls Alwarpet Phone 🍆 8250192130 👅 celebrity escorts service
Chennai Call Girls Alwarpet Phone 🍆 8250192130 👅 celebrity escorts serviceChennai Call Girls Alwarpet Phone 🍆 8250192130 👅 celebrity escorts service
Chennai Call Girls Alwarpet Phone 🍆 8250192130 👅 celebrity escorts service
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
 
Chennai Call Girls Porur Phone 🍆 8250192130 👅 celebrity escorts service
Chennai Call Girls Porur Phone 🍆 8250192130 👅 celebrity escorts serviceChennai Call Girls Porur Phone 🍆 8250192130 👅 celebrity escorts service
Chennai Call Girls Porur Phone 🍆 8250192130 👅 celebrity escorts service
 
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja VipCall Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
Call Girls Service Adil Nagar 7001305949 Need escorts Service Pooja Vip
 
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
 
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
办理(UofR毕业证书)罗切斯特大学毕业证成绩单原版一比一
 
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
定制(UAL学位证)英国伦敦艺术大学毕业证成绩单原版一比一
 
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
 
Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITM
 
VIP Kolkata Call Girl Alambazar 👉 8250192130 Available With Room
VIP Kolkata Call Girl Alambazar 👉 8250192130  Available With RoomVIP Kolkata Call Girl Alambazar 👉 8250192130  Available With Room
VIP Kolkata Call Girl Alambazar 👉 8250192130 Available With Room
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
 
VIP Kolkata Call Girl Dum Dum 👉 8250192130 Available With Room
VIP Kolkata Call Girl Dum Dum 👉 8250192130  Available With RoomVIP Kolkata Call Girl Dum Dum 👉 8250192130  Available With Room
VIP Kolkata Call Girl Dum Dum 👉 8250192130 Available With Room
 
VIP Call Girls Kolkata Ananya 🤌 8250192130 🚀 Vip Call Girls Kolkata
VIP Call Girls Kolkata Ananya 🤌  8250192130 🚀 Vip Call Girls KolkataVIP Call Girls Kolkata Ananya 🤌  8250192130 🚀 Vip Call Girls Kolkata
VIP Call Girls Kolkata Ananya 🤌 8250192130 🚀 Vip Call Girls Kolkata
 
Complet Documnetation for Smart Assistant Application for Disabled Person
Complet Documnetation   for Smart Assistant Application for Disabled PersonComplet Documnetation   for Smart Assistant Application for Disabled Person
Complet Documnetation for Smart Assistant Application for Disabled Person
 
Denver Web Design brochure for public viewing
Denver Web Design brochure for public viewingDenver Web Design brochure for public viewing
Denver Web Design brochure for public viewing
 

A General Purpose Docker Image for PHP

  • 1. Building a General Purpose PHP Docker Image Robert Lemke
  • 2. Robert Lemke Flownative Managing Partner Neos CMS Project Founder
  • 3. Robert Lemke Flownative Managing Partner Neos CMS Project Founder
  • 4.
  • 5. Robert Lemke Co-Founder Flownative Founder Neos CMS Project Creating software since 1985 PHP since 1998
  • 6. Robert Lemke Flownative Managing Partner Neos CMS Project Founder
  • 7.
  • 11. Base Image - standards and tooling for other images - common tools for application usage ! create your own base image ! reduce to a minimum, but not less
  • 12. Which OS? Alpine Linux - smaller filesystem footprint - more secure? - only relevant in container context - uses musl instead of glibc "
  • 13. Which OS? Debian - larger filesystem footprint - well-established security team - wide-spread, therefore more first-hand experience - high compatibility due to glibc
  • 14. Which OS? ! You need to feel comfortable working with the OS and it must support all the software you want to install
  • 16. Does the image size really matter? Due to layering not so much if most containers use the same base image
  • 20. FROM bitnami/minideb:bullseye COPY root-files / RUN /build.sh "# rm /build.sh ENTRYPOINT ["/entrypoint.sh"] CMD [ "run" ]
  • 21. FROM bitnami/minideb:bullseye LABEL org.opencontainers.image.authors="Robert Lemke <robert@flownative.com>" ARG BUILD_DATE LABEL com.flownative.base-image-build-date=$BUILD_DATE COPY root-files / RUN /build.sh "# rm /build.sh ENTRYPOINT ["/entrypoint.sh"] CMD [ "run" ]
  • 22. FROM bitnami/minideb:bullseye LABEL org.opencontainers.image.authors="Robert Lemke <robert@flownative.com>" ARG BUILD_DATE LABEL com.flownative.base-image-build-date=$BUILD_DATE ENV FLOWNATIVE_LIB_PATH="/opt/flownative/lib" LOG_DEBUG=true COPY "$from=flownative/bash-library:1.13.5 /lib $FLOWNATIVE_LIB_PATH COPY root-files / RUN /build.sh "# rm /build.sh ENTRYPOINT ["/entrypoint.sh"] CMD [ "run" ]
  • 23. !"/bin/bash # Load helper libraries . "${FLOWNATIVE_LIB_PATH}/log.sh" . "${FLOWNATIVE_LIB_PATH}/banner.sh" . "${FLOWNATIVE_LIB_PATH}/packages.sh" set -o errexit set -o nounset set -o pipefail # --------------------------------------------------------------------------------------- # Main routine export FLOWNATIVE_LOG_PATH_AND_FILENAME=/dev/stdout banner_flownative 'Demo Base Image' packages_install dpkg apt-utils ca-certificates syslog-ng logrotate # Clean up rm -rf /var/cache"% /var/log"%
  • 24. !"/bin/bash set -o errexit set -o nounset set -o pipefail . "${FLOWNATIVE_LIB_PATH}/banner.sh" banner_flownative "Demo Base Image" sleep 3600
  • 25.
  • 26.
  • 28. FROM flownative/base:bullseye LABEL org.opencontainers.image.authors="Robert Lemke <robert@flownative.com>" ENV PHP_BASE_PATH="/opt/flownative/php" PATH="/opt/flownative/php/bin:$PATH" LOG_DEBUG="false" COPY root-files / RUN export FLOWNATIVE_LOG_PATH_AND_FILENAME=/dev/stdout "# /build.sh init "# /build.sh clean WORKDIR ${PHP_BASE_PATH} ENTRYPOINT [ "/entrypoint.sh" ] CMD [ "run" ]
  • 29. !"/bin/bash set -o errexit set -o nounset set -o pipefail # Load lib . "${FLOWNATIVE_LIB_PATH}/syslog-ng.sh" . "${FLOWNATIVE_LIB_PATH}/supervisor.sh" . "${FLOWNATIVE_LIB_PATH}/banner.sh" banner_flownative "Demo Base Image" eval "$(syslog_env)" syslog_initialize syslog_start eval "$(supervisor_env)" supervisor_initialize supervisor_start trap 'supervisor_stop; syslog_stop' SIGINT SIGTERM if [[ "$*" = *"run"* ]]; then supervisor_pid=$(supervisor_get_pid) info "Entrypoint: Start up complete" # We can't use "wait" because supervisord is not a direct child of this shell: while [ -e "/proc/${supervisor_pid}" ]; do sleep 1.1; done info "Good bye #" else "$@" fi
  • 32. FROM flownative/base:bullseye LABEL org.opencontainers.image.authors="Robert Lemke <robert@flownative.com>" # ----------------------------------------------------------------------------- # PHP # Latest versions: https:"#www.php.net/downloads.php ARG PHP_VERSION ENV PHP_VERSION ${PHP_VERSION} ENV PHP_BASE_PATH="/opt/flownative/php" PATH="/opt/flownative/php/bin:$PATH" LOG_DEBUG="false" USER root COPY root-files / RUN export FLOWNATIVE_LOG_PATH_AND_FILENAME=/dev/stdout "# /build.sh init "# /build.sh clean USER 1000 EXPOSE 9000 9001 WORKDIR ${PHP_BASE_PATH} ENTRYPOINT [ "/entrypoint.sh" ] CMD [ "run" ]
  • 33. !"/bin/bash […] # --------------------------------------------------------------------------------------- # build_create_directories() - Create directories and set access rights accordingly # # @global PHP_BASE_PATH # @global BEACH_APPLICATION_PATH # @return void # build_create_directories() { mkdir -p "${PHP_BASE_PATH}/bin" "${PHP_BASE_PATH}/etc/conf.d" "${PHP_BASE_PATH}/ext" "${PHP_BASE_PATH}/tmp" "${PHP_BASE_PATH}/log" } # --------------------------------------------------------------------------------------- # build_adjust_permissions() - Adjust permissions for a few paths and files # # @global PHP_BASE_PATH # @return void # build_adjust_permissions() { chown -R root:root "${PHP_BASE_PATH}" chmod -R g+rwX "${PHP_BASE_PATH}" chown -R 1000 "${PHP_BASE_PATH}/etc" "${PHP_BASE_PATH}/tmp" } # --------------------------------------------------------------------------------------- # Main routine case $1 in init) banner_flownative 'PHP' build_create_directories "& clean) build_adjust_permissions "& esac
  • 34. !"/bin/bash set -o errexit set -o nounset set -o pipefail # Load lib . "${FLOWNATIVE_LIB_PATH}/syslog-ng.sh" . "${FLOWNATIVE_LIB_PATH}/supervisor.sh" . "${FLOWNATIVE_LIB_PATH}/banner.sh" banner_flownative PHP eval "$(syslog_env)" syslog_initialize syslog_start eval "$(supervisor_env)" supervisor_initialize supervisor_start trap 'supervisor_stop; syslog_stop' SIGINT SIGTERM if [[ "$*" = *"run"* ]]; then supervisor_pid=$(supervisor_get_pid) info "Entrypoint: Start up complete" # We can't use "wait" because supervisord is not a direct child of this shell: while [ -e "/proc/${supervisor_pid}" ]; do sleep 1.1; done info "Good bye #" else "$@" fi
  • 35.
  • 36. # --------------------------------------------------------------------------------------- # Main routine case $1 in init) banner_flownative 'PHP' if [[ ! "${PHP_VERSION}" =~ ^8.[0-2] ]]; then error "$ Unsupported PHP version '${PHP_VERSION}'" exit 1 fi build_create_directories "& prepare) packages_install $(build_get_runtime_packages) 1>$(debug_device) packages_install $(build_get_build_packages) 1>$(debug_device) "& build) build_compile_php "& clean) build_adjust_permissions packages_remove $(build_get_build_packages) 1>$(debug_device) packages_remove $(build_get_unnecessary_packages) 1>$(debug_device) packages_remove_docs_and_caches 1>$(debug_device) build_clean "& esac
  • 37. # ------------------------------------------------------------------------------------------ # build_get_build_packages() - Returns a list of packages which are only needed for building # # @global PHP_BASE_PATH # @return List of packages # build_get_build_packages() { local packages=" autoconf bison build-essential cmake curl file pkg-config re2c unzip libcurl4-openssl-dev libfreetype6-dev libgmp-dev libicu-dev libjpeg62-turbo-dev libltdl-dev libmariadb-dev libmcrypt-dev libonig-dev libpng-dev libpspell-dev libpq-dev libreadline6-dev libsqlite3-dev libssl-dev libwebp-dev libxml2-dev libzip-dev libbz2-dev " echo $packages }
  • 38. # --------------------------------------------------------------------------------------- # build_get_runtime_packages() - Returns a list of packages which are needed during runtime # # @return List of packages # build_get_runtime_packages() { local packages=" libcurl4 libjpeg62 libonig5 libpq5 libreadline8 libsodium-dev libssl1.1 libzip4 libbz2-1.0 libncurses6 libpng16-16 libwebp6 libxml2 libsqlite3-0 " echo $packages }
  • 39. # --------------------------------------------------------------------------------------- # build_get_unnecessary_packages() - Not needed packages, can be removed # # @return List of packages # build_get_unnecessary_packages() { local packages=" cmake " echo $packages }
  • 40. # --------------------------------------------------------------------------------------- # Main routine case $1 in init) banner_flownative 'PHP' if [[ ! "${PHP_VERSION}" =~ ^8.[0-2] ]]; then error "$ Unsupported PHP version '${PHP_VERSION}'" exit 1 fi build_create_directories "& prepare) packages_install $(build_get_runtime_packages) 1>$(debug_device) packages_install $(build_get_build_packages) 1>$(debug_device) "& build) build_compile_php "& clean) build_adjust_permissions packages_remove $(build_get_build_packages) 1>$(debug_device) packages_remove $(build_get_unnecessary_packages) 1>$(debug_device) packages_remove_docs_and_caches 1>$(debug_device) build_clean "& esac
  • 41. # --------------------------------------------------------------------------------------- # Main routine case $1 in init) banner_flownative 'PHP' if [[ ! "${PHP_VERSION}" =~ ^8.[0-2] ]]; then error "$ Unsupported PHP version '${PHP_VERSION}'" exit 1 fi build_create_directories "& prepare) packages_install $(build_get_runtime_packages) 1>$(debug_device) packages_install $(build_get_build_packages) 1>$(debug_device) "& build) build_compile_php "& clean) build_adjust_permissions packages_remove $(build_get_build_packages) 1>$(debug_device) packages_remove $(build_get_unnecessary_packages) 1>$(debug_device) packages_remove_docs_and_caches 1>$(debug_device) build_clean "& esac
  • 42. # --------------------------------------------------------------------------------------- # build_compile_php() - # # @global PHP_BASE_PATH # @return void # build_compile_php() { local php_source_url php_source_url="https:"'www.php.net/distributions/php-${PHP_VERSION}.tar.gz" info "$ Downloading source code for PHP ${PHP_VERSION} from ${php_source_url} ""(" with_backoff "curl -sSL ${php_source_url} -o php.tar.gz" "15" ") ( error "Failed downloading PHP source from ${php_source_url}" exit 1 ) mkdir -p "${PHP_BASE_PATH}/src" tar -xf php.tar.gz -C "${PHP_BASE_PATH}/src" "$strip-components=1 rm php.tar.gz* cd "${PHP_BASE_PATH}/src" info "$ Generating build configuration ""(" ./buildconf "$force >$(debug_device) if [[ ! -f configure ]]; then error "$ Failed generating build configuration, 'configure' not found" # shellcheck disable=SC2012 ls | output exit 1 fi …
  • 43. # --------------------------------------------------------------------------------------- # build_compile_php() - # # @global PHP_BASE_PATH # @return void # build_compile_php() { local php_source_url php_source_url="https:"'www.php.net/distributions/php-${PHP_VERSION}.tar.gz" info "$ Downloading source code for PHP ${PHP_VERSION} from ${php_source_url} ""(" with_backoff "curl -sSL ${php_source_url} -o php.tar.gz" "15" ") ( error "Failed downloading PHP source from ${php_source_url}" exit 1 ) mkdir -p "${PHP_BASE_PATH}/src" tar -xf php.tar.gz -C "${PHP_BASE_PATH}/src" "$strip-components=1 rm php.tar.gz* cd "${PHP_BASE_PATH}/src" info "$ Generating build configuration ""(" ./buildconf "$force >$(debug_device) if [[ ! -f configure ]]; then error "$ Failed generating build configuration, 'configure' not found" # shellcheck disable=SC2012 ls | output exit 1 fi …
  • 44. … # For GCC warning options see: https:"#gcc.gnu.org/onlinedocs/gcc-3.4.4/gcc/Warning-Options.html export CFLAGS='-Wno-deprecated-declarations -Wno-stringop-overflow -Wno-implicit-function-declaration' if [[ "${PHP_VERSION}" =~ ^8.[0-2] ]]; then ./configure "$prefix=${PHP_BASE_PATH} "$with-config-file-path="${PHP_BASE_PATH}/etc" "$with-config-file-scan-dir="${PHP_BASE_PATH}/etc/conf.d" "$enable-bcmath "$disable-cgi "$enable-calendar "$enable-exif "$enable-fpm "$enable-ftp "$enable-gd "$enable-intl "$enable-mbstring "$enable-pcntl "$enable-soap "$enable-sockets "$with-curl "$with-freetype "$with-gmp "$with-jpeg "$with-mysqli "$with-openssl "$with-pdo-pgsql "$with-pdo-mysql "$with-readline "$with-sodium "$with-system-ciphers "$with-webp "$with-zip "$with-zlib "$with-bz2 "$without-pear >$(debug_device) else error "$ No configure call available for PHP version ${PHP_VERSION}" exit 1 fi …
  • 45. info "$ Compiling PHP ""(" make -j"$(nproc)" >$(debug_device) make install >$(debug_device) info "$ Cleaning up ""(" make clean >$(debug_device) rm -rf /tmp/pear }
  • 46. # --------------------------------------------------------------------------------------- # Main routine case $1 in init) banner_flownative 'PHP' if [[ ! "${PHP_VERSION}" =~ ^8.[0-2] ]]; then error "$ Unsupported PHP version '${PHP_VERSION}'" exit 1 fi build_create_directories "& prepare) packages_install $(build_get_runtime_packages) 1>$(debug_device) packages_install $(build_get_build_packages) 1>$(debug_device) "& build) build_compile_php "& clean) build_adjust_permissions packages_remove $(build_get_build_packages) 1>$(debug_device) packages_remove $(build_get_unnecessary_packages) 1>$(debug_device) packages_remove_docs_and_caches 1>$(debug_device) build_clean "& esac
  • 47.
  • 48. !"/bin/bash # shellcheck disable=SC1090 set -o errexit set -o nounset set -o pipefail # Load lib . "${FLOWNATIVE_LIB_PATH}/syslog-ng.sh" . "${FLOWNATIVE_LIB_PATH}/supervisor.sh" . "${FLOWNATIVE_LIB_PATH}/banner.sh" . "${FLOWNATIVE_LIB_PATH}/php-fpm.sh" banner_flownative PHP eval "$(syslog_env)" syslog_initialize syslog_start eval "$(php_fpm_env)" eval "$(supervisor_env)" php_fpm_initialize supervisor_initialize supervisor_start trap 'supervisor_stop; syslog_stop' SIGINT SIGTERM if [[ "$*" = *"run"* ]]; then supervisor_pid=$(supervisor_get_pid) info "Entrypoint: Start up complete" # We can't use "wait" because supervisord is not a direct child of this shell: while [ -e "/proc/${supervisor_pid}" ]; do sleep 1.1; done info "Good bye #" else "$@" fi
  • 49. # --------------------------------------------------------------------------------------- # php_fpm_env() - Load global environment variables for configuring PHP # # @global PHP_* The PHP_ environment variables # @return "export" statements which can be passed to eval() # php_fpm_env() { cat "*"EOF" export PHP_BASE_PATH="${PHP_BASE_PATH}" export PHP_CONF_PATH="${PHP_CONF_PATH:-${PHP_BASE_PATH}/etc}" export PHP_TMP_PATH="${PHP_TMP_PATH:-${PHP_BASE_PATH}/tmp}" export PHP_LOG_PATH="${PHP_LOG_PATH:-${PHP_BASE_PATH}/log}" export PHP_MEMORY_LIMIT="${PHP_MEMORY_LIMIT:-750M}" export PHP_DATE_TIMEZONE="${PHP_DATE_TIMEZONE:-UTC}" export PHP_DISPLAY_ERRORS="${PHP_DISPLAY_ERRORS:-off}" export PHP_ERROR_REPORTING="${PHP_ERROR_REPORTING:-2147483647}" export PHP_ERROR_LOG="${PHP_ERROR_LOG:-/dev/stderr}" export PHP_OPCACHE_PRELOAD="${PHP_OPCACHE_PRELOAD:-}" export PHP_XDEBUG_ENABLE="${PHP_XDEBUG_ENABLE:-false}" export PHP_XDEBUG_MODE="${PHP_XDEBUG_MODE:-develop}" export PHP_XDEBUG_DISCOVER_CLIENT_HOST="${PHP_XDEBUG_DISCOVER_CLIENT_HOST:-false}" export PHP_XDEBUG_CLIENT_HOST="${PHP_XDEBUG_CLIENT_HOST:-}" export PHP_XDEBUG_CONFIG="${PHP_XDEBUG_CONFIG:-}" export XDEBUG_CONFIG="${XDEBUG_CONFIG:-${PHP_XDEBUG_CONFIG}}" export PHP_XDEBUG_MAX_NESTING_LEVEL="${PHP_XDEBUG_MAX_NESTING_LEVEL:-512}" export PHP_IGBINARY_ENABLE="${PHP_IGBINARY_ENABLE:-false}" export PHP_FPM_USER="1000" export PHP_FPM_GROUP="1000" export PHP_FPM_PORT="${PHP_FPM_PORT:-9000}" export PHP_FPM_PM_MODE="${PHP_FPM_PM_MODE:-ondemand}" export PHP_FPM_MAX_CHILDREN="${PHP_FPM_MAX_CHILDREN:-20}" export PHP_FPM_ERROR_LOG_PATH="${PHP_FPM_ERROR_LOG_PATH:-/opt/flownative/log/php-fpm-error.log}" export PHP_FPM_ACCESS_LOG_PATH="${PHP_FPM_ACCESS_LOG_PATH:-/opt/flownative/log/php-fpm-access.log}" EOF }
  • 50. [global] error_log = ${PHP_FPM_ERROR_LOG_PATH} pid = ${PHP_TMP_PATH}/php-fpm.pid ; don't daemonize, because we want to start PHP as a child process of ; the shell running php-fpm.sh, so we can wait for it with "wait": daemonize = no [www] access.log = ${PHP_FPM_ACCESS_LOG_PATH} listen = ["+]:${PHP_FPM_PORT} pm = ${PHP_FPM_PM_MODE} pm.max_children = ${PHP_FPM_MAX_CHILDREN} pm.status_path = /php-fpm-status clear_env = no
  • 51. # --------------------------------------------------------------------------------------- # php_fpm_initialize() - Initialize PHP configuration and check required files and dirs # # @global PHP_* The PHP_* environment variables # @return void # php_fpm_initialize() { if [[ $(id "$user) ", 0 ]]; then error "PHP-FPM: Container is running as root, but only unprivileged users are supported" exit 1 fi; info "PHP-FPM: Initializing configuration ""(" envsubst < "${PHP_CONF_PATH}/php-fpm.conf.template" > "${PHP_CONF_PATH}/php-fpm.conf" if is_boolean_yes "${PHP_XDEBUG_ENABLE}"; then info "PHP-FPM: Xdebug is enabled" mv "${PHP_CONF_PATH}/conf.d/php-ext-xdebug.ini.inactive" "${PHP_CONF_PATH}/conf.d/php-ext-xdebug.ini" else info "PHP-FPM: Xdebug is disabled" export PHP_XDEBUG_MODE="off" fi if is_boolean_yes "${PHP_IGBINARY_ENABLE}"; then # igbinary might have been enabled already by scripts in an Docker image which is based on this one if [ -f "${PHP_CONF_PATH}/conf.d/php-ext-igbinary.ini.inactive" ]; then info "PHP-FPM: igbinary is enabled" mv -f "${PHP_CONF_PATH}/conf.d/php-ext-igbinary.ini.inactive" "${PHP_CONF_PATH}/conf.d/php-ext-igbinary.ini" fi else info "PHP-FPM: igbinary is disabled" fi # Create a file descriptor for the PHP-FPM log output and clean up the log lines a bit: exec 4> >(sed -e "s/^([0-9"--]* [0-9:,]*)".1 OUTPUT PHP-FPM:/") }
  • 52. # --------------------------------------------------------------------------------------- # php_fpm_initialize() - Initialize PHP configuration and check required files and dirs # # @global PHP_* The PHP_* environment variables # @return void # php_fpm_initialize() { if [[ $(id "$user) ", 0 ]]; then error "PHP-FPM: Container is running as root, but only unprivileged users are supported" exit 1 fi; info "PHP-FPM: Initializing configuration ""(" envsubst < "${PHP_CONF_PATH}/php-fpm.conf.template" > "${PHP_CONF_PATH}/php-fpm.conf" if is_boolean_yes "${PHP_XDEBUG_ENABLE}"; then info "PHP-FPM: Xdebug is enabled" mv "${PHP_CONF_PATH}/conf.d/php-ext-xdebug.ini.inactive" "${PHP_CONF_PATH}/conf.d/php-ext-xdebug.ini" else info "PHP-FPM: Xdebug is disabled" export PHP_XDEBUG_MODE="off" fi if is_boolean_yes "${PHP_IGBINARY_ENABLE}"; then # igbinary might have been enabled already by scripts in an Docker image which is based on this one if [ -f "${PHP_CONF_PATH}/conf.d/php-ext-igbinary.ini.inactive" ]; then info "PHP-FPM: igbinary is enabled" mv -f "${PHP_CONF_PATH}/conf.d/php-ext-igbinary.ini.inactive" "${PHP_CONF_PATH}/conf.d/php-ext-igbinary.ini" fi else info "PHP-FPM: igbinary is disabled" fi # Create a file descriptor for the PHP-FPM log output and clean up the log lines a bit: exec 4> >(sed -e "s/^([0-9"--]* [0-9:,]*)".1 OUTPUT PHP-FPM:/") }
  • 55. version: '3.7' services: webserver: image: flownative/nginx:latest container_name: ipc_muc_2023_webserver ports: - "8080" volumes: - ./:/application environment: - BEACH_PHP_FPM_HOST=ipc_muc_2023_php php: image: flownative/php:8.2 container_name: ipc_muc_2023_php ports: - "9000" - "9003" security_opt: - no-new-privileges volumes: - ./:/application environment: - PHP_DISPLAY_ERRORS=on
  • 57.
  • 59. FROM scratch MAINTAINER Flownative <support@flownative.com> VOLUME /build COPY DistributionPackages /build/DistributionPackages COPY Packages /build/Packages COPY bin /build/bin COPY Web /build/Web COPY flow /build/flow COPY composer.json /build/composer.json COPY composer.lock /build/composer.lock COPY Configuration /build/Configuration
  • 60. FROM scratch busybox:latest MAINTAINER Flownative <support@flownative.com> VOLUME /build COPY DistributionPackages /build/DistributionPackages COPY Packages /build/Packages COPY bin /build/bin COPY Web /build/Web COPY flow /build/flow COPY composer.json /build/composer.json COPY composer.lock /build/composer.lock COPY Configuration /build/Configuration
  • 67. announce: runs-on: ubuntu-latest needs: build steps: - name: Dispatch to beach-php uses: peter-evans/repository-dispatch@v1 with: token: ${{ secrets.FLOWNATIVE_BOT_TOKEN }} repository: flownative/docker-beach-php event-type: php-images-built client-payload: '{"image_name": "flownative/docker-php/php"}' Build Cascade
  • 68. name: Build Docker images on: repository_dispatch: types: [php-images-built] push: branches-ignore: - '**' tags: - 'v*.*.*' jobs: build: runs-on: ubuntu-latest strategy: matrix: Build Cascade
  • 69. Image Security - don't run as root (use SecurityContext) - disable privilege escalation - automatically scan images - redeploy automatically, frequently - only include minimal amount of software – do you really need a shell?
  • 73. And what about …? ddev performance Mutagen SSH TLS Xdebug extensions Kubernetes Colima logging