Skip to content

Commit 473c61e

Browse files
Add Dockerfile for phpfpm base image with version
and file copies Signed-off-by: Mario Vejlupek <[email protected]>
1 parent 7112c59 commit 473c61e

File tree

6 files changed

+320
-0
lines changed

6 files changed

+320
-0
lines changed

.github/workflows/build.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# NOTES:
2+
# 1. Create PAT with `read:packages` and `write:packages` see https://docs.github.com/en/free-pro-team@latest/packages/guides/migrating-to-github-container-registry-for-docker-images#authenticating-with-the-container-registry
3+
# 2. Create CR_PAT variable under Settings / Secrets
4+
5+
name: BUILD
6+
7+
on:
8+
push:
9+
# Publish `v1.2.3` tags as releases.
10+
tags:
11+
- v*
12+
13+
env:
14+
FETCHER_IMAGE_VERSION: ""
15+
BASE_IMAGE_VERSION: ""
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- uses: actions/checkout@v2
23+
24+
- name: Run build
25+
run: |
26+
IMAGE_NAME=ghcr.io/$(echo "${{ github.repository }}" | tr '[A-Z]' '[a-z]' )
27+
# Strip git ref prefix from version
28+
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
29+
docker build . \
30+
--build-arg FETCHER_IMAGE_VERSION=${FETCHER_IMAGE_VERSION} \
31+
--build-arg BASE_IMAGE_VERSION=${BASE_IMAGE_VERSION} \
32+
--file Dockerfile --tag $IMAGE_NAME:$VERSION
33+
34+
- name: Log into GitHub Container Registry
35+
run: echo "${{ secrets.CR_PAT }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
36+
37+
- name: Push image to GitHub Container Registry
38+
run: |
39+
IMAGE_NAME=ghcr.io/$(echo "${{ github.repository }}" | tr '[A-Z]' '[a-z]' )
40+
# Strip git ref prefix from version
41+
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
42+
echo IMAGE_NAME=$IMAGE_NAME
43+
echo VERSION=$VERSION
44+
docker push $IMAGE_NAME:$VERSION
45+
# Push latest as well for caching purposes
46+
docker tag $IMAGE_NAME:$VERSION $IMAGE_NAME:latest
47+
docker push $IMAGE_NAME:latest

.github/workflows/test.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# TODO:
2+
# 1. Create PAT with `read:packages` and `write:packages` see https://docs.github.com/en/free-pro-team@latest/packages/guides/migrating-to-github-container-registry-for-docker-images#authenticating-with-the-container-registry
3+
# 2. Create CR_PAT variable under Settings / Secrets
4+
5+
name: TEST
6+
7+
on:
8+
push:
9+
branches:
10+
- main
11+
12+
env:
13+
FETCHER_IMAGE_VERSION: ""
14+
BASE_IMAGE_VERSION: ""
15+
16+
# NOTE: DO NOT CHANGE THIS THIS IS TMP IMAGE NAME
17+
IMAGE_NAME: image
18+
19+
jobs:
20+
test:
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- uses: actions/checkout@v2
25+
26+
- name: Run tests
27+
run: |
28+
docker build . \
29+
--build-arg FETCHER_IMAGE_VERSION=${FETCHER_IMAGE_VERSION} \
30+
--build-arg BASE_IMAGE_VERSION=${BASE_IMAGE_VERSION} \
31+
--file Dockerfile --tag $IMAGE_NAME

Dockerfile

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# https://hub.docker.com/_/php/tags?page=1&name=fpm-bullseye
2+
FROM php:8.1.22-fpm-bullseye
3+
4+
LABEL org.opencontainers.image.source https://github.com/Container-Driven-Development/PHPfpm-Base
5+
LABEL org.opencontainers.image.description "Base image for PHPfpm server"
6+
7+
WORKDIR /srv
8+
ENV NETTE_ENV "prod"
9+
ARG APP_VERSION
10+
ENV APP_VERSION $APP_VERSION
11+
ARG PHP_ENV=production
12+
ENV TZ "Europe/Prague"
13+
14+
RUN curl -o /usr/local/bin/composer https://getcomposer.org/download/2.6.5/composer.phar && \
15+
chmod +x /usr/local/bin/composer
16+
17+
RUN apt-get update && apt-get install -y \
18+
libfcgi-bin \
19+
screen \
20+
unzip \
21+
mc \
22+
telnet \
23+
htop \
24+
default-mysql-client \
25+
iputils-ping \
26+
dnsutils \
27+
locales \
28+
sendmail \
29+
&& rm -rf /var/lib/apt/lists/*
30+
31+
RUN echo -e "export LC_ALL=cs_CZ.UTF-8\nexport LANG=cs_CZ.UTF-8\nexport LANGUAGE=cs_CZ.UTF-8" >> /root/.bashrc
32+
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
33+
sed -i -e 's/# cs_CZ.UTF-8 UTF-8/cs_CZ.UTF-8 UTF-8/' /etc/locale.gen && \
34+
echo 'LANG="cs_CZ.UTF-8"'>/etc/default/locale && \
35+
dpkg-reconfigure --frontend=noninteractive locales && \
36+
update-locale LANG=cs_CZ.UTF-8
37+
38+
RUN set -xe && echo "pm.status_path = /status" >> /usr/local/etc/php-fpm.d/zz-docker.conf
39+
COPY php-fpm-healthcheck.sh /usr/local/bin/
40+
41+
RUN mv "$PHP_INI_DIR/php.ini-${PHP_ENV}" "$PHP_INI_DIR/php.ini"
42+
COPY app.ini $PHP_INI_DIR/conf.d/app.ini
43+
44+
# https://hub.docker.com/r/mlocati/php-extension-installer/tags
45+
COPY --from=mlocati/php-extension-installer:1.5.37 /usr/bin/install-php-extensions /usr/local/bin/
46+
47+
# See https://github.com/mlocati/docker-php-extension-installer
48+
# Always use exact version to avoid mystery issues on lib upgrade
49+
# Run this for getting installed extension version
50+
# php -r 'foreach (get_loaded_extensions() as $extension) echo "$extension: " . phpversion($extension) . "\n";'
51+
RUN install-php-extensions pdo-8.1.10 pdo_mysql-8.1.10 intl-8.1.10 redis-5.3.7 mysqli-8.1.10 opcache-8.1.10 gd-2.1.0 ssh2-1.3.1
52+
53+
RUN mkdir -p /srv/var/log && \
54+
mkdir -p /srv/var/tmp/cache && \
55+
chmod -R 777 /srv/var && \
56+
chown -R www-data:www-data /srv/var && \
57+
mkdir -p /srv/.xml && \
58+
chmod -R 777 /srv/.xml && \
59+
chown -R www-data:www-data /srv/.xml && \
60+
mkdir -p /srv/log && \
61+
chmod -R 777 /srv/log && \
62+
chown -R www-data:www-data /srv/log && \
63+
mkdir -p /srv/sitemap && \
64+
chmod -R 777 /srv/sitemap && \
65+
chown -R www-data:www-data /srv/sitemap
66+
67+
68+
69+
# Example see https://github.com/Container-Driven-Development/PHPfpm-Base
70+
# FROM ghcr.io/container-driven-development/phpfpm-base:vX.X
71+
72+
# ARG APP_VERSION
73+
# ENV APP_VERSION $APP_VERSION
74+
75+
# COPY --from=BUILDER /app/vendor /srv/vendor
76+
# COPY --from=BUILDER-NODE /app/var/tmp/manifest.json /srv/var/tmp/manifest.json
77+
# COPY ./www /srv/www
78+
# COPY ./config /srv/config
79+
# COPY ./app /srv/app
80+
# COPY ./bin /srv/bin
81+
# COPY ./migrations /srv/migrations

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,18 @@
11
# PHPfpm-Base
2+
23
Base phpfpm image
4+
5+
```Dockerfile
6+
FROM ghcr.io/container-driven-development/phpfpm-base:vX.X
7+
8+
ARG APP_VERSION
9+
ENV APP_VERSION $APP_VERSION
10+
11+
COPY --from=BUILDER /app/vendor /srv/vendor
12+
COPY --from=BUILDER-NODE /app/var/tmp/manifest.json /srv/var/tmp/manifest.json
13+
COPY ./www /srv/www
14+
COPY ./config /srv/config
15+
COPY ./app /srv/app
16+
COPY ./bin /srv/bin
17+
COPY ./migrations /srv/migrations
18+
```

app.ini

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
; App specific configuration
2+
session.gc_maxlifetime = 28800
3+
variables_order = "EGPCS"
4+
upload_max_filesize = 512M
5+
post_max_size = 512M
6+
memory_limit = -1

php-fpm-healthcheck.sh

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#!/bin/sh
2+
# vim: set filetype=sh :
3+
4+
# Author: <Renato Mefi [email protected]> https://github.com/renatomefi
5+
# The original code lives in https://github.com/renatomefi/php-fpm-healthcheck
6+
#
7+
# A POSIX compliant shell script to healthcheck PHP fpm status, can be used only for pinging the status page
8+
# or check for specific metrics
9+
#
10+
# i.e.: ./php-fpm-healthcheck --verbose --active-processes=6
11+
# The script will fail in case the 'active processes' is bigger than 6.
12+
#
13+
# You can combine multiple options as well, the first one to fail will fail the healthcheck
14+
# i.e.: ./php-fpm-healthcheck --listen-queue-len=10 --active-processes=6
15+
#
16+
# Ping mode (exit 0 if php-fpm returned data): ./php-fpm-healthcheck
17+
#
18+
# Ping mode with data (outputs php-fpm status text): ./php-fpm-healthcheck -v
19+
#
20+
# Exit status codes:
21+
# 2,9,111 - Couldn't connect to PHP fpm, is it running?
22+
# 8 - Couldn't reach PHP fpm status page, have you configured it with `pm.status_path = /status`?
23+
# 1 - A healthcheck condition has failed
24+
# 3 - Invalid option given
25+
# 4 - One or more required softwares are missing
26+
#
27+
# Available options:
28+
# -v|--verbose
29+
#
30+
# Metric options, fails in case the CURRENT VALUE is bigger than the GIVEN VALUE
31+
# --accepted-conn=n
32+
# --listen-queue=n
33+
# --max-listen-queue=n
34+
# --idle-processes=n
35+
# --active-processes=n
36+
# --total-processes=n
37+
# --max-active-processes=n
38+
# --max-children-reached=n
39+
# --slow-requests=n
40+
#
41+
42+
set -eu
43+
44+
OPTIND=1 # Reset getopt in case it has been used previously in the shell
45+
46+
# Required software
47+
FCGI_CMD_PATH=$(command -v cgi-fcgi) || { >&2 echo "Make sure fcgi is installed (i.e. apk add --no-cache fcgi). Aborting."; exit 4; }
48+
command -v sed 1> /dev/null || { >&2 echo "Make sure sed is installed (i.e. apk add --no-cache busybox). Aborting."; exit 4; }
49+
command -v tail 1> /dev/null || { >&2 echo "Make sure tail is installed (i.e. apk add --no-cache busybox). Aborting."; exit 4; }
50+
command -v grep 1> /dev/null || { >&2 echo "Make sure grep is installed (i.e. apk add --no-cache grep). Aborting."; exit 4; }
51+
52+
# Get status from fastcgi connection
53+
# $1 - cgi-fcgi connect argument
54+
get_fpm_status() {
55+
if test "$VERBOSE" = 1; then printf "Trying to connect to php-fpm via: %s%s\\n" "$1" "$SCRIPT_NAME"; fi;
56+
57+
# Since I cannot use pipefail I'll just split these in two commands
58+
FPM_STATUS=$(env -i REQUEST_METHOD="$REQUEST_METHOD" SCRIPT_NAME="$SCRIPT_NAME" SCRIPT_FILENAME="$SCRIPT_FILENAME" "$FCGI_CMD_PATH" -bind -connect "$1" 2> /dev/null)
59+
FPM_STATUS=$(echo "$FPM_STATUS" | tail -n +5)
60+
61+
if test "$VERBOSE" = 1; then printf "php-fpm status output:\\n%s\\n" "$FPM_STATUS"; fi;
62+
63+
if test "$FPM_STATUS" = "File not found."; then
64+
>&2 printf "php-fpm status page non reachable\\n";
65+
exit 8;
66+
fi;
67+
}
68+
69+
# $1 - fpm option
70+
# $2 - expected value threshold
71+
check_fpm_health_by() {
72+
OPTION=$(echo "$1" | sed 's/--//g; s/-/ /g;')
73+
VALUE_EXPECTED="$2";
74+
VALUE_ACTUAL=$(echo "$FPM_STATUS" | grep "^$OPTION:" | cut -d: -f2 | sed 's/ //g')
75+
76+
if test "$VERBOSE" = 1; then printf "'%s' value '%s' and expected is less than '%s'\\n" "$OPTION" "$VALUE_ACTUAL" "$VALUE_EXPECTED"; fi;
77+
78+
if test "$VALUE_ACTUAL" -gt "$VALUE_EXPECTED"; then
79+
>&2 printf "'%s' value '%s' is greater than expected '%s'\\n" "$OPTION" "$VALUE_ACTUAL" "$VALUE_EXPECTED";
80+
exit 1;
81+
fi;
82+
}
83+
84+
PARAM_AMOUNT=0
85+
86+
# $1 - fpm option
87+
# $2 - expected value threshold
88+
check_later() {
89+
# The POSIX sh way to check if it's an integer, also the output is supressed since it's polution
90+
if ! test "$2" -eq "$2" 2> /dev/null; then
91+
>&2 printf "'%s' option value must be an integer, '%s' given\\n" "$1" "$2"; exit 3;
92+
fi
93+
94+
PARAM_AMOUNT=$(( PARAM_AMOUNT + 1 ))
95+
96+
eval "PARAM_TO_CHECK$PARAM_AMOUNT=$1"
97+
eval "VALUE_TO_CHECK$PARAM_AMOUNT=$2"
98+
}
99+
100+
# From the PARAM_TO_CHECK/VALUE_TO_CHECK magic variables, do all the checks
101+
check_fpm_health() {
102+
j=1
103+
while [ $j -le $PARAM_AMOUNT ]; do
104+
eval "CURRENT_PARAM=\$PARAM_TO_CHECK$j"
105+
eval "CURRENT_VALUE=\$VALUE_TO_CHECK$j"
106+
check_fpm_health_by "$CURRENT_PARAM" "$CURRENT_VALUE"
107+
j=$(( j + 1 ))
108+
done
109+
}
110+
111+
if ! GETOPT=$(getopt -o v --long verbose,accepted-conn:,listen-queue:,max-listen-queue:,listen-queue-len:,idle-processes:,active-processes:,total-processes:,max-active-processes:,max-children-reached:,slow-requests: -n 'php-fpm-healthcheck' -- "$@"); then
112+
>&2 echo "Invalid options, terminating." ; exit 3
113+
fi;
114+
115+
eval set -- "$GETOPT"
116+
117+
# FastCGI variables
118+
FCGI_CONNECT_DEFAULT="localhost:9000"
119+
FCGI_STATUS_PATH_DEFAULT="/status"
120+
121+
export REQUEST_METHOD="GET"
122+
export SCRIPT_NAME="${FCGI_STATUS_PATH:-$FCGI_STATUS_PATH_DEFAULT}"
123+
export SCRIPT_FILENAME="${FCGI_STATUS_PATH:-$FCGI_STATUS_PATH_DEFAULT}"
124+
FCGI_CONNECT="${FCGI_CONNECT:-$FCGI_CONNECT_DEFAULT}"
125+
126+
VERBOSE=0
127+
128+
while test "$1"; do
129+
case "$1" in
130+
-v|--verbose ) VERBOSE=1; shift ;;
131+
--) shift ; break ;;
132+
* ) check_later "$1" "$2"; shift 2 ;;
133+
esac
134+
done
135+
136+
FPM_STATUS=false
137+
138+
get_fpm_status "$FCGI_CONNECT"
139+
check_fpm_health

0 commit comments

Comments
 (0)