From 58c5b6b087f345e44d7b02faca824c27b25b54b3 Mon Sep 17 00:00:00 2001 From: Muhammed Hussein Karimi Date: Sat, 26 Oct 2024 19:38:42 +0330 Subject: [PATCH] :tada: Add PHP Image Signed-off-by: Muhammed Hussein Karimi --- README.md | 3 + php/Containerfile | 214 +++++++++++++++++++++++++++++++++++++ php/README.md | 13 +++ php/index.php | 16 +++ php/nginx-supervisord.conf | 34 ++++++ php/nginx.conf | 52 +++++++++ php/start.sh | 42 ++++++++ 7 files changed, 374 insertions(+) create mode 100644 README.md create mode 100644 php/Containerfile create mode 100644 php/README.md create mode 100644 php/index.php create mode 100644 php/nginx-supervisord.conf create mode 100644 php/nginx.conf create mode 100644 php/start.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..9abf9d7 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Containers + +Publicly available Container Images (published on `ghcr.io`) diff --git a/php/Containerfile b/php/Containerfile new file mode 100644 index 0000000..5c44c45 --- /dev/null +++ b/php/Containerfile @@ -0,0 +1,214 @@ +ARG PHP_VERSION +ARG DEBIAN_VERSION +ARG PHP_RUNTIME +ARG START_RUNTIME=${PHP_RUNTIME} +FROM docker.io/library/php:${PHP_VERSION}-${PHP_RUNTIME}-${DEBIAN_VERSION} AS builder + +WORKDIR /var/www/html/ + +ENV DEBIAN_FRONTEND=noninteractive +ENV LC_ALL=C.UTF-8 +ENV TERM=xterm-color +ENV COMPOSER_ALLOW_SUPERUSER 1 +ENV PATH /var/www/html/vendor/bin:/composer/vendor/bin:$PATH + +RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache +RUN pecl channel-update pecl.php.net + +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + set -eux; \ + apt-get update; \ + apt-get install --no-install-recommends -y apt-transport-https && \ + apt-get install -y --no-install-recommends \ + apt-utils \ + gnupg \ + gosu \ + git \ + curl \ + ca-certificates \ + supervisor \ + libmemcached-dev \ + libz-dev \ + libbrotli-dev \ + libc-ares-dev \ + libpq-dev \ + libjpeg-dev \ + libpng-dev \ + libfreetype6-dev \ + libssl-dev \ + libwebp-dev \ + libmcrypt-dev \ + libonig-dev \ + libzip-dev zip \ + unzip \ + libargon2-1 \ + libidn2-0 \ + libpcre2-8-0 \ + libpcre3 \ + libxml2 \ + libzstd1 \ + procps \ + libcurl4-openssl-dev \ + vim \ + nano \ + net-tools \ + libmagickwand-dev \ + libgmp-dev \ + libxslt1-dev \ + zlib1g-dev \ + libicu-dev \ + g++ \ + libffi-dev + +RUN export MAKE="make -j$(nproc)" && \ + docker-php-source extract && \ + pecl install -f \ + igbinary \ + redis \ + grpc \ + protobuf \ + opentelemetry && \ + rm -rf /tmp/pear && \ + docker-php-ext-enable \ + igbinary \ + redis \ + grpc \ + protobuf \ + opentelemetry && \ + docker-php-ext-install -j$(nproc) \ + bz2 \ + calendar \ + curl \ + exif \ + gettext \ + gmp \ + iconv \ + pdo \ + pdo_pgsql \ + shmop \ + soap \ + sysvmsg \ + sysvsem \ + sysvshm \ + xml \ + xsl \ + pdo_mysql \ + mbstring \ + opcache \ + pcntl \ + bcmath \ + sockets && \ + set -xe; \ + docker-php-ext-configure zip && \ + docker-php-ext-install -j$(nproc) zip && \ + docker-php-ext-configure gd \ + --prefix=/usr \ + --with-jpeg \ + --with-webp \ + --with-freetype && \ + docker-php-ext-install -j$(nproc) gd && \ + docker-php-ext-install -j$(nproc) ffi && \ + pecl install \ + -D 'enable-openssl="yes" enable-http2="yes" enable-swoole-curl="yes" enable-cares="yes" enable-mysqlnd="yes" enable-swoole-pgsql="yes" enable-brotli="yes" enable-sockets="yes"' \ + swoole && \ + docker-php-ext-enable \ + swoole && \ + rm -rf /tmp/pear && \ + docker-php-ext-configure intl && \ + docker-php-ext-install -j$(nproc) intl && \ + set -eux; \ + docker-php-source delete; \ + rm -rf /usr/local/bin/phpdbg; \ + rm -rf /usr/local/lib/php/test && \ + find /usr/local/bin /usr/local/sbin /usr/local/lib -type f -perm /0111 -exec strip --strip-all '{}' + || true + +RUN set -eux; \ + find /usr/local/lib/php /usr/local/bin /usr/local/sbin /usr/lib/x86_64-linux-gnu/ -type f -executable -exec ldd '{}' ';' \ + | awk '/=>/ { print $(NF-1) }' \ + | xargs -P $(nproc) -I {} dpkg-query --search {} | awk -F ":" '{print $1}' \ + | uniq >> /PACKAGES +RUN find /usr/lib/x86_64-linux-gnu/ -type f \ + | xargs -P $(nproc) -I {} dpkg-query --search {} | awk -F ":" '{print $1}' \ + | uniq >> /PACKAGES + +RUN mkdir -p /etc/apache2 /usr/lib/apache2 + +FROM docker.io/library/debian:${DEBIAN_VERSION}-slim +ARG START_RUNTIME + +ENV DEBIAN_FRONTEND=noninteractive +ENV LC_ALL=C.UTF-8 +ENV TERM=xterm-color +ENV COMPOSER_ALLOW_SUPERUSER 1 +ENV PATH /var/www/html/vendor/bin:/composer/vendor/bin:$PATH +ENV PHP_INI_DIR /usr/local/etc/php +ENV START_RUNTIME ${START_RUNTIME} +ENV DOCUMENT_ROOT=/var/www/html + +COPY --from=builder /usr/local/include/ /usr/local/include/ +COPY --from=builder /usr/local/lib/php/ /usr/local/lib/php/ +COPY --from=builder /usr/local/bin /usr/local/bin +COPY --from=builder /usr/local/sbin /usr/local/sbin +COPY --from=builder /usr/local/etc /usr/local/etc +COPY --from=builder /PACKAGES / + +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt-get update && \ + apt-get install --no-install-recommends \ + -y $(cat PACKAGES | sort | uniq) \ + ca-certificates \ + nginx \ + vim \ + tmux \ + net-tools \ + curl \ + git \ + gnupg2 \ + supervisor \ + unzip \ + procps + +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + if [ ${START_RUNTIME} = "apache" ]; then \ + apt-get update && \ + apt-get install -y apache2; \ + fi + +COPY --from=builder /etc/apache2 /etc/apache2 +COPY --from=builder /usr/lib/apache2 /usr/lib/apache2 + +COPY --from=docker.io/library/composer:2 /usr/bin/composer /usr/local/bin/composer +RUN composer global require bamarni/symfony-console-autocomplete + +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt-get update \ + && . /etc/os-release \ + && echo "deb http://apt.postgresql.org/pub/repos/apt $VERSION_CODENAME-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ + && curl -sL https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ + && apt-get update -y \ + && apt-get install -y --no-install-recommends --show-progress postgresql-client-16 postgis \ + && curl -sL https://deb.nodesource.com/setup_20.x | bash - \ + && apt-get install -y nodejs \ + && npm install -g npm \ + && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ + && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && apt-get update \ + && apt-get install --no-install-recommends -y yarn + +WORKDIR /var/www/html/ + +RUN mkdir -p /opt/parmincloud/php && \ + rm -rf /var/www/html/* +COPY --chmod=0775 ./start.sh /opt/parmincloud/php/start-container +COPY nginx.conf /etc/nginx/nginx.conf +COPY nginx-supervisord.conf /opt/parmincloud/php/nginx-supervisord.conf +COPY index.php /var/www/html/index.php + +EXPOSE 80 +STOPSIGNAL SIGQUIT + +CMD ["/opt/parmincloud/php/start-container"] diff --git a/php/README.md b/php/README.md new file mode 100644 index 0000000..065752a --- /dev/null +++ b/php/README.md @@ -0,0 +1,13 @@ +# All in One PHP Container + +## Variants + +* apache: Based on Apache and serves your code using Apache2 +* nginx: Based on PHP FPM and NGINX +* fpm: Based on PHP FPM can be used as FactCGI server +* cli: Contains no builtin webserver (Swoole is pre-installed) + +## ENVs + +* `DOCUMENT_ROOT`: Defaults to `/var/www/html` and sets root dir of servers (works on apache and nginx) + > In laravel you might set it to `/var/www/html/public` diff --git a/php/index.php b/php/index.php new file mode 100644 index 0000000..54f0635 --- /dev/null +++ b/php/index.php @@ -0,0 +1,16 @@ + + + + ParminCloud PHP Container Image + + +

ParminCloud PHP Container Image

+

+ If you see this page it means that you have not copied the source code at . +
+
+ Running PHP with +

+ + + diff --git a/php/nginx-supervisord.conf b/php/nginx-supervisord.conf new file mode 100644 index 0000000..b47da72 --- /dev/null +++ b/php/nginx-supervisord.conf @@ -0,0 +1,34 @@ +[supervisord] +nodaemon=true +user=root +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:fpm] +command=php-fpm +autostart=true +stderr_logfile=/dev/stderr +stdout_logfile=/dev/stdout +autorestart=true +priority=999 +exitcodes=0 +startretries=3 +stdout_maxbytes=0 +stderr_maxbytes=0 +stdout_logfile_maxbytes=0 +stderr_logfile_maxbytes=0 + +[program:nginx] +command=nginx +autostart=true +stderr_logfile=/dev/stderr +stdout_logfile=/dev/stdout +autorestart=true +priority=999 +exitcodes=0 +startretries=3 +stdout_maxbytes=0 +stderr_maxbytes=0 +stdout_logfile_maxbytes=0 +stderr_logfile_maxbytes=0 + diff --git a/php/nginx.conf b/php/nginx.conf new file mode 100644 index 0000000..9231a24 --- /dev/null +++ b/php/nginx.conf @@ -0,0 +1,52 @@ +worker_processes auto; +daemon off; + +error_log /dev/stderr; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + server_tokens off; + + log_format main $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" "$http_x_real_ip" "$http_x_client_ip"; + + access_log /dev/stdout main; + + sendfile on; + keepalive_timeout 65; + server { + listen 80; + + access_log /dev/stdout main; + error_log /dev/stderr; + + charset utf-8; + client_max_body_size 0; + + error_page 404 /index.php; + root /var/www/html; + + index index.php index.html index.htm; + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location ~* ^/.+\.(jpg|jpeg|png|gif|ico|css|js|otf|ttf|eot|woff|svg|json|yml|yaml|woff2)$ { + expires max; + } + + location ~ \.php { + fastcgi_pass 127.0.0.1:9000; + fastcgi_index index.php; + fastcgi_split_path_info ^(.+\.php)(.*)$; + include /etc/nginx/fastcgi_params; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + fastcgi_param X-Real-IP $http_x_real_ip; + fastcgi_param X-Forwarded-For $http_x_forwarded_for; + } + } +} diff --git a/php/start.sh b/php/start.sh new file mode 100644 index 0000000..53f4e9b --- /dev/null +++ b/php/start.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +case ${START_RUNTIME} in + fpm) + exec php-fpm + ;; + + cli) + exec php -a + ;; + + apache) + sed -ri -e "s!/var/www/html!${DOCUMENT_ROOT}!g" /etc/apache2/sites-available/*.conf + sed -ri -e "s!/var/www/!${DOCUMENT_ROOT}!g" /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf + export APACHE_ENVVARS=/etc/apache2/envvars + . "$APACHE_ENVVARS" + for dir in "$APACHE_LOCK_DIR" "$APACHE_RUN_DIR" "$APACHE_LOG_DIR" "$APACHE_RUN_DIR/socks"; do + rm -rvf "$dir" + mkdir -p "$dir" + chown "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$dir" + chmod 1777 "$dir" + done + ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log" + ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log" + ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log" + rm -f /var/run/apache2/apache2.pid + a2dismod mpm_event + a2enmod mpm_prefork + a2enconf docker-php + exec apache2 -DFOREGROUND + ;; + + nginx) + sed -ri -e "s!/var/www/html!${DOCUMENT_ROOT}!g" /etc/nginx/nginx.conf + exec /usr/bin/supervisord -c /opt/parmincloud/php/nginx-supervisord.conf + ;; + + *) + exec "$@" + ;; +esac +