Skip to content

Commit 028ed7e

Browse files
committed
rework container to frankenphp runtime
1 parent e532a9a commit 028ed7e

File tree

7 files changed

+109
-74
lines changed

7 files changed

+109
-74
lines changed

Dockerfile

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,25 @@
55
# If you want to build this locally you want to run `docker build -f Dockerfile.dev .`
66
##
77

8+
ARG TARGETOS=linux
9+
ARG TARGETARCH=amd64
10+
11+
# ================================
12+
# Stage 0: Base Runtime (FrankenPHP dev, GNU libc)
13+
# ================================
14+
FROM dunglas/frankenphp-dev:php8.4-bookworm AS base
15+
16+
# Keep compatible with the legacy Docker builder (no BuildKit required).
17+
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/install-php-extensions
18+
19+
RUN chmod +x /usr/local/bin/install-php-extensions \
20+
&& install-php-extensions bcmath gd intl zip pcntl pdo_mysql pdo_pgsql bz2 \
21+
&& rm /usr/local/bin/install-php-extensions
22+
823
# ================================
924
# Stage 1-1: Composer Install
1025
# ================================
11-
FROM --platform=$TARGETOS/$TARGETARCH localhost:5000/base-php:$TARGETARCH AS composer
26+
FROM --platform=$TARGETOS/$TARGETARCH base AS composer
1227

1328
WORKDIR /build
1429

@@ -58,15 +73,17 @@ RUN yarn run build
5873
# ================================
5974
# Stage 5: Build Final Application Image
6075
# ================================
61-
FROM --platform=$TARGETOS/$TARGETARCH localhost:5000/base-php:$TARGETARCH AS final
76+
FROM --platform=$TARGETOS/$TARGETARCH base AS final
6277

6378
WORKDIR /var/www/html
6479

65-
RUN apk add --no-cache \
80+
RUN apt-get update \
81+
&& apt-get install -y --no-install-recommends \
6682
# packages for running the panel
67-
caddy ca-certificates supervisor supercronic fcgi \
83+
ca-certificates supervisor curl netcat-openbsd \
6884
# required for installing plugins. Pulled from https://github.com/pelican-dev/panel/pull/2034
69-
zip unzip 7zip bzip2-dev yarn git
85+
zip unzip p7zip-full bzip2 git yarnpkg \
86+
&& rm -rf /var/lib/apt/lists/*
7087

7188
COPY --chown=root:www-data --chmod=770 --from=composerbuild /build .
7289
COPY --chown=root:www-data --chmod=770 --from=yarnbuild /build/public ./public
@@ -83,25 +100,23 @@ RUN mkdir -p /pelican-data/storage /pelican-data/plugins /var/run/supervisord \
83100
# Allow www-data write permissions where necessary
84101
&& chown -R www-data: /pelican-data .env ./storage ./plugins ./bootstrap/cache /var/run/supervisord /var/www/html/public/storage \
85102
&& chmod -R 770 /pelican-data ./storage ./bootstrap/cache /var/run/supervisord \
86-
&& chown -R www-data: /usr/local/etc/php/ /usr/local/etc/php-fpm.d/
103+
&& chown -R www-data: /usr/local/etc/php/
87104

88105
# Configure Supervisor
89106
COPY docker/supervisord.conf /etc/supervisord.conf
90107
COPY docker/Caddyfile /etc/caddy/Caddyfile
91-
# Add Laravel scheduler to crontab
92-
COPY docker/crontab /etc/crontabs/crontab
93108

94109
COPY docker/entrypoint.sh /entrypoint.sh
95110
COPY docker/healthcheck.sh /healthcheck.sh
96111

97112
HEALTHCHECK --interval=5m --timeout=10s --start-period=5s --retries=3 \
98-
CMD /bin/ash /healthcheck.sh
113+
CMD /bin/sh /healthcheck.sh
99114

100115
EXPOSE 80 443
101116

102117
VOLUME /pelican-data
103118

104119
USER www-data
105120

106-
ENTRYPOINT [ "/bin/ash", "/entrypoint.sh" ]
121+
ENTRYPOINT [ "/bin/sh", "/entrypoint.sh" ]
107122
CMD [ "supervisord", "-n", "-c", "/etc/supervisord.conf" ]

Dockerfile.base

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
# ================================
2-
# Stage 0: Build PHP Base Image
3-
# ================================
4-
FROM --platform=$TARGETOS/$TARGETARCH php:8.4-fpm-alpine
5-
6-
ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
7-
8-
RUN install-php-extensions bcmath gd intl zip pcntl pdo_mysql pdo_pgsql bz2
9-
10-
RUN rm /usr/local/bin/install-php-extensions
1+
# ================================
2+
# Stage 0: Base Panel Runtime (FrankenPHP dev, GNU libc)
3+
# ================================
4+
#
5+
# We use the FrankenPHP *development* images (as requested) and a GNU libc base
6+
# (Debian bookworm) to avoid musl compatibility issues and to match "gnu"
7+
# expectations.
8+
#
9+
FROM dunglas/frankenphp-dev:php8.4-bookworm
10+
11+
# Keep compatible with the legacy Docker builder (no BuildKit required).
12+
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/install-php-extensions
13+
14+
# Match what the panel previously installed on php:*-alpine.
15+
RUN chmod +x /usr/local/bin/install-php-extensions \
16+
&& install-php-extensions bcmath gd intl zip pcntl pdo_mysql pdo_pgsql bz2 \
17+
&& rm /usr/local/bin/install-php-extensions

Dockerfile.dev

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
# syntax=docker.io/docker/dockerfile:1.13-labs
22
# Pelican Development Dockerfile
33

4-
FROM --platform=$TARGETOS/$TARGETARCH php:8.4-fpm-alpine AS base
4+
ARG TARGETOS=linux
5+
ARG TARGETARCH=amd64
56

6-
ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
7+
FROM dunglas/frankenphp-dev:php8.4-bookworm AS base
78

8-
RUN install-php-extensions bcmath gd intl zip pcntl pdo_mysql pdo_pgsql bz2
9+
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/install-php-extensions
10+
11+
RUN chmod +x /usr/local/bin/install-php-extensions \
12+
&& install-php-extensions bcmath gd intl zip pcntl pdo_mysql pdo_pgsql bz2
913

1014
RUN rm /usr/local/bin/install-php-extensions
1115

@@ -62,16 +66,18 @@ RUN yarn run build
6266
# ================================
6367
# Stage 5: Build Final Application Image
6468
# ================================
65-
FROM --platform=$TARGETOS/$TARGETARCH base AS final
69+
FROM base AS final
6670

6771
WORKDIR /var/www/html
6872

6973
# Install additional required libraries
70-
RUN apk add --no-cache \
74+
RUN apt-get update \
75+
&& apt-get install -y --no-install-recommends \
7176
# packages for running the panel
72-
caddy ca-certificates supervisor supercronic fcgi coreutils \
77+
ca-certificates supervisor curl coreutils netcat-openbsd \
7378
# required for installing plugins. Pulled from https://github.com/pelican-dev/panel/pull/2034
74-
zip unzip 7zip bzip2-dev yarn git
79+
zip unzip p7zip-full bzip2 git yarnpkg \
80+
&& rm -rf /var/lib/apt/lists/*
7581

7682
COPY --chown=root:www-data --chmod=770 --from=composerbuild /build .
7783
COPY --chown=root:www-data --chmod=770 --from=yarnbuild /build/public ./public
@@ -88,25 +94,23 @@ RUN mkdir -p /pelican-data/storage /pelican-data/plugins /var/run/supervisord \
8894
# Allow www-data write permissions where necessary
8995
&& chown -R www-data: /pelican-data .env ./storage ./plugins ./bootstrap/cache /var/run/supervisord /var/www/html/public/storage \
9096
&& chmod -R 770 /pelican-data ./storage ./bootstrap/cache /var/run/supervisord \
91-
&& chown -R www-data: /usr/local/etc/php/ /usr/local/etc/php-fpm.d/
97+
&& chown -R www-data: /usr/local/etc/php/
9298

9399
# Configure Supervisor
94100
COPY docker/supervisord.conf /etc/supervisord.conf
95101
COPY docker/Caddyfile /etc/caddy/Caddyfile
96-
# Add Laravel scheduler to crontab
97-
COPY docker/crontab /etc/crontabs/crontab
98102

99103
COPY docker/entrypoint.sh /entrypoint.sh
100104
COPY docker/healthcheck.sh /healthcheck.sh
101105

102106
HEALTHCHECK --interval=5m --timeout=10s --start-period=5s --retries=3 \
103-
CMD /bin/ash /healthcheck.sh
107+
CMD /bin/sh /healthcheck.sh
104108

105109
EXPOSE 80 443
106110

107111
VOLUME /pelican-data
108112

109113
USER www-data
110114

111-
ENTRYPOINT [ "/bin/ash", "/entrypoint.sh" ]
115+
ENTRYPOINT [ "/bin/sh", "/entrypoint.sh" ]
112116
CMD [ "supervisord", "-n", "-c", "/etc/supervisord.conf" ]

docker/Caddyfile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
servers {
33
## docs https://caddyserver.com/docs/caddyfile/options#trusted-proxies
4-
{$CADDY_TRUSTED_PROXIES}
4+
{$CADDY_TRUSTED_PROXIES}
55
{$CADDY_STRICT_PROXIES}
66
}
77
admin off
@@ -14,5 +14,11 @@
1414
encode gzip
1515

1616
file_server
17-
php_fastcgi 127.0.0.1:9000
17+
18+
# FrankenPHP replaces php-fpm + fastcgi with an in-process PHP runtime.
19+
# When we later want Laravel "worker mode", we can extend this block with
20+
# FrankenPHP worker directives (often via Laravel Octane).
21+
php_server {
22+
worker ./public/index.php
23+
}
1824
}

docker/entrypoint.sh

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/ash -e
1+
#!/bin/sh -eu
22
# check for .env file or symlink and generate app keys if missing
33
if [ -f /var/www/html/.env ]; then
44
echo "external vars exist."
@@ -10,30 +10,30 @@ else
1010
touch /pelican-data/.env
1111

1212
# manually generate a key because key generate --force fails
13-
if [ -z ${APP_KEY} ]; then
14-
echo -e "Generating key."
13+
if [ -z "${APP_KEY:-}" ]; then
14+
echo "Generating key."
1515
APP_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
16-
echo -e "Generated app key: $APP_KEY"
17-
echo -e "APP_KEY=$APP_KEY" > /pelican-data/.env
16+
echo "Generated app key: $APP_KEY"
17+
printf '%s\n' "APP_KEY=$APP_KEY" > /pelican-data/.env
1818
else
19-
echo -e "APP_KEY exists in environment, using that."
20-
echo -e "APP_KEY=$APP_KEY" > /pelican-data/.env
19+
echo "APP_KEY exists in environment, using that."
20+
printf '%s\n' "APP_KEY=$APP_KEY" > /pelican-data/.env
2121
fi
2222

2323
# enable installer
24-
echo -e "APP_INSTALLED=false" >> /pelican-data/.env
24+
printf '%s\n' "APP_INSTALLED=false" >> /pelican-data/.env
2525
fi
2626

2727
# create directories for volumes
2828
mkdir -p /pelican-data/database /pelican-data/storage/avatars /pelican-data/storage/fonts /pelican-data/storage/icons /pelican-data/plugins /var/www/html/storage/logs/supervisord 2>/dev/null
2929

3030
# if the app is installed then we need to run migrations on start. New installs will run migrations when you run the installer.
31-
if [ "${APP_INSTALLED}" == "true" ]; then
31+
if [ "${APP_INSTALLED:-}" = "true" ] && [ "${SKIP_MIGRATIONS:-}" != "true" ]; then
3232
#if the db is anything but sqlite wait until it's accepting connections
33-
if [ "${DB_CONNECTION}" != "sqlite" ]; then
33+
if [ "${DB_CONNECTION:-}" != "sqlite" ]; then
3434
# check for DB up before starting the panel
3535
echo "Checking database status."
36-
until nc -z -v -w30 $DB_HOST $DB_PORT
36+
until nc -z -v -w30 "${DB_HOST:-}" "${DB_PORT:-}"
3737
do
3838
echo "Waiting for database connection..."
3939
# wait for 1 seconds before check again
@@ -44,21 +44,31 @@ if [ "${APP_INSTALLED}" == "true" ]; then
4444
php artisan migrate --force
4545
fi
4646

47-
echo -e "Optimizing Filament"
47+
echo "Optimizing Filament"
4848
php artisan filament:optimize
4949

5050
# default to caddy not starting
5151
export SUPERVISORD_CADDY=false
52+
export SUPERVISORD_QUEUE=true
53+
export SUPERVISORD_SCHEDULER=true
5254
export PARSED_APP_URL=${APP_URL}
5355

56+
# allow running the queue worker and scheduler in separate containers later
57+
if [ "${SKIP_QUEUE:-}" = "true" ]; then
58+
export SUPERVISORD_QUEUE=false
59+
fi
60+
if [ "${SKIP_SCHEDULER:-}" = "true" ]; then
61+
export SUPERVISORD_SCHEDULER=false
62+
fi
63+
5464
# checking if app url is using https
5565
if echo "${APP_URL}" | grep -qE '^https://'; then
5666
echo "https domain found setting email var"
5767
export PARSED_LE_EMAIL="email ${LE_EMAIL}"
5868
fi
5969

6070
# when running behind a proxy
61-
if [ "${BEHIND_PROXY}" == "true" ]; then
71+
if [ "${BEHIND_PROXY:-}" = "true" ]; then
6272
echo "running behind proxy"
6373
echo "listening on port 80 internally"
6474
export PARSED_LE_EMAIL=""
@@ -68,19 +78,19 @@ if [ "${BEHIND_PROXY}" == "true" ]; then
6878
fi
6979

7080
# disable caddy if SKIP_CADDY is set
71-
if [ "${SKIP_CADDY:-}" == "true" ]; then
72-
echo "Starting PHP-FPM only"
81+
if [ "${SKIP_CADDY:-}" = "true" ]; then
82+
echo "Starting app services without web server"
7383
else
74-
echo "Starting PHP-FPM and Caddy"
84+
echo "Starting app services"
7585
# enable caddy
7686
export SUPERVISORD_CADDY=true
7787

7888
# handle trusted proxies for caddy when variable has data
79-
if [ ! -z ${TRUSTED_PROXIES} ]; then
89+
if [ -n "${TRUSTED_PROXIES:-}" ]; then
8090
export CADDY_TRUSTED_PROXIES=$(echo "trusted_proxies static ${TRUSTED_PROXIES}" | sed 's/,/ /g')
8191
export CADDY_STRICT_PROXIES="trusted_proxies_strict"
8292
fi
8393
fi
8494

8595
echo "Starting Supervisord"
86-
exec "$@"
96+
exec "$@"

docker/healthcheck.sh

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
#!/bin/ash -e
1+
#!/bin/sh -eu
22

3-
if [ ${SKIP_CADDY} ! "true" ]; then
4-
curl -f http://localhost/up || exit 1
3+
# If the web server is enabled, ensure the app responds.
4+
if [ "${SKIP_CADDY:-}" != "true" ]; then
5+
curl -fsS http://localhost/up >/dev/null
56
fi
6-
7-
cgi-fcgi -bind -connect 127.0.0.1:9000 || exit 2
8-
9-
exit 0

docker/supervisord.conf

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,23 @@ serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix so
2121
username=dummy
2222
password=dummy
2323

24-
[program:php-fpm]
25-
command=/usr/local/sbin/php-fpm -F
26-
autostart=true
27-
autorestart=true
28-
29-
[program:queue-worker]
30-
command=/usr/local/bin/php /var/www/html/artisan queue:work --tries=3
31-
autostart=true
32-
autorestart=true
33-
3424
[program:caddy]
35-
command=caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
25+
26+
command=/usr/local/bin/frankenphp run --config /etc/caddy/Caddyfile --adapter caddyfile
3627
autostart=%(ENV_SUPERVISORD_CADDY)s
3728
autorestart=%(ENV_SUPERVISORD_CADDY)s
3829
priority=10
3930
stdout_logfile=/dev/fd/1
4031
stdout_logfile_maxbytes=0
4132
redirect_stderr=true
4233

43-
[program:supercronic]
44-
command=supercronic -overlapping /etc/crontabs/crontab
45-
autostart=true
46-
autorestart=true
34+
[program:queue-worker]
35+
command=/usr/local/bin/php /var/www/html/artisan queue:work --tries=3
36+
autostart=%(ENV_SUPERVISORD_QUEUE)s
37+
autorestart=%(ENV_SUPERVISORD_QUEUE)s
38+
39+
[program:scheduler]
40+
command=/usr/local/bin/php /var/www/html/artisan schedule:work
41+
autostart=%(ENV_SUPERVISORD_SCHEDULER)s
42+
autorestart=%(ENV_SUPERVISORD_SCHEDULER)s
4743
redirect_stderr=true

0 commit comments

Comments
 (0)