Эта страница была переведена сообществом и не обязательно является актуальной. Обратитесь к справочной версии.
Эта страница была переведена сообществом и не обязательно является актуальной. Обратитесь к справочной версии.
Эта страница была переведена сообществом и не обязательно является актуальной. Обратитесь к справочной версии.
Docker-образы FrankenPHP основаны на официальных PHP-образах. Доступны варианты для Debian и Alpine Linux для популярных архитектур. Рекомендуется использовать Debian-варианты.
Доступны версии для PHP 8.2, 8.3, 8.4 и 8.5.
Теги следуют следующему шаблону: dunglas/frankenphp:<frankenphp-version>-php<php-version>-<os>.
<frankenphp-version> и <php-version> — версии FrankenPHP и PHP соответственно, начиная с мажорных (например, 1), минорных (например, 1.2) и заканчивая патч-версиями (например, 1.2.3).<os> может быть trixie (для Debian Trixie), bookworm (для Debian Bookworm) или alpine (для последней стабильной версии Alpine).Создайте Dockerfile в вашем проекте:
FROM dunglas/frankenphp
COPY . /app/public
Затем выполните следующие команды для сборки и запуска Docker-образа:
docker build -t my-php-app .
docker run -it --rm --name my-running-app my-php-app
Для удобства в образе предоставлен Caddyfile по умолчанию, содержащий полезные переменные окружения.
Скрипт docker-php-extension-installer предоставляется в базовом образе. Установка дополнительных PHP-расширений осуществляется просто:
FROM dunglas/frankenphp
# Добавьте дополнительные расширения здесь:
RUN install-php-extensions \
pdo_mysql \
gd \
intl \
zip \
opcache
FrankenPHP построен на базе Caddy, и все модули Caddy можно использовать с FrankenPHP.
Самый простой способ установить пользовательские модули Caddy — использовать xcaddy:
FROM dunglas/frankenphp:builder AS builder
# Копируем xcaddy в образ сборки
COPY --from=caddy:builder /usr/bin/xcaddy /usr/bin/xcaddy
# Для сборки FrankenPHP необходимо включить CGO
RUN CGO_ENABLED=1 \
XCADDY_SETCAP=1 \
XCADDY_GO_BUILD_FLAGS="-ldflags='-w -s' -tags=nobadger,nomysql,nopgx" \
CGO_CFLAGS=$(php-config --includes) \
CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
xcaddy build \
--output /usr/local/bin/frankenphp \
--with github.com/dunglas/frankenphp=./ \
--with github.com/dunglas/frankenphp/caddy=./caddy/ \
--with github.com/dunglas/caddy-cbrotli \
# Mercure и Vulcain включены в официальный билд, но вы можете их удалить
--with github.com/dunglas/mercure/caddy \
--with github.com/dunglas/vulcain/caddy
# Добавьте дополнительные модули Caddy здесь
FROM dunglas/frankenphp AS runner
# Заменяем официальный бинарный файл на пользовательский с добавленными модулями
COPY --from=builder /usr/local/bin/frankenphp /usr/local/bin/frankenphp
Образ builder, предоставляемый FrankenPHP, содержит скомпилированную версию libphp.
Образы builder доступны для всех версий FrankenPHP и PHP, как для Debian, так и для Alpine.
Tip
Если вы используете Alpine Linux и Symfony, возможно, потребуется увеличить размер стека.
Установите переменную окружения FRANKENPHP_CONFIG, чтобы запускать FrankenPHP с рабочим скриптом:
FROM dunglas/frankenphp
# ...
ENV FRANKENPHP_CONFIG="worker ./public/index.php"
Для удобной разработки с FrankenPHP смонтируйте директорию с исходным кодом приложения на хосте как том в Docker-контейнере:
docker run -v $PWD:/app/public -p 80:80 -p 443:443 -p 443:443/udp --tty my-php-app
Tip
Опция
--ttyпозволяет получать удобочитаемые логи вместо JSON-формата.
С использованием Docker Compose:
# compose.yaml
services:
php:
image: dunglas/frankenphp
# раскомментируйте следующую строку, если хотите использовать собственный Dockerfile
#build: .
# раскомментируйте следующую строку для работы в production-окружении
# restart: always
ports:
- "80:80" # HTTP
- "443:443" # HTTPS
- "443:443/udp" # HTTP/3
volumes:
- ./:/app/public
- caddy_data:/data
- caddy_config:/config
# закомментируйте следующую строку в production — в dev она обеспечивает удобочитаемые логи
tty: true
# Тома, необходимые для сертификатов и конфигурации Caddy
volumes:
caddy_data:
caddy_config:
FrankenPHP может запускаться под обычным пользователем в Docker.
Пример Dockerfile для этого:
FROM dunglas/frankenphp
ARG USER=appuser
RUN \
# Для дистрибутивов на основе Alpine используйте "adduser -D ${USER}"
useradd ${USER}; \
# Добавить возможность привязки к портам 80 и 443
setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/frankenphp; \
# Предоставить доступ на запись в /config/caddy и /data/caddy
chown -R ${USER}:${USER} /config/caddy /data/caddy
USER ${USER}
Даже при запуске без root-прав, FrankenPHP требуется возможность CAP_NET_BIND_SERVICE для привязки веб-сервера к зарезервированным портам (80 и 443).
Если вы открываете доступ к FrankenPHP на непривилегированном порту (1024 и выше), можно запустить веб-сервер от имени обычного пользователя без необходимости предоставления дополнительных возможностей:
FROM dunglas/frankenphp
ARG USER=appuser
RUN \
# Для дистрибутивов на основе Alpine используйте "adduser -D ${USER}"
useradd ${USER}; \
# Удалить стандартные возможности
setcap -r /usr/local/bin/frankenphp; \
# Предоставить доступ на запись в /config/caddy и /data/caddy
chown -R ${USER}:${USER} /config/caddy /data/caddy
USER ${USER}
Затем установите переменную окружения SERVER_NAME, чтобы использовать непривилегированный порт.
Пример: :8000.
Docker-образы собираются:
Чтобы ещё больше уменьшить поверхность атаки и размер ваших Docker-образов FrankenPHP, также возможно создавать их на основе Google Distroless или Docker Hardened образов.
Warning
Эти минимальные базовые образы не включают оболочку или менеджер пакетов, что значительно усложняет отладку. Поэтому они рекомендуются только для продакшена, если безопасность является высоким приоритетом.
При добавлении дополнительных PHP-расширений вам потребуется промежуточная стадия сборки:
FROM dunglas/frankenphp AS builder
# Добавьте дополнительные PHP-расширения здесь
RUN install-php-extensions pdo_mysql pdo_pgsql #...
# Скопировать общие библиотеки frankenphp и всех установленных расширений во временное место
# Этот шаг можно также выполнить вручную, проанализировав вывод ldd для бинарного файла frankenphp и каждого файла расширения .so
RUN apt-get update && apt-get install -y libtree && \
EXT_DIR="$(php -r 'echo ini_get("extension_dir");')" && \
FRANKENPHP_BIN="$(which frankenphp)"; \
LIBS_TMP_DIR="/tmp/libs"; \
mkdir -p "$LIBS_TMP_DIR"; \
for target in "$FRANKENPHP_BIN" $(find "$EXT_DIR" -maxdepth 2 -type f -name "*.so"); do \
libtree -pv "$target" | sed 's/.*── \(.*\) \[.*/\1/' | grep -v "^$target" | while IFS= read -r lib; do \
[ -z "$lib" ] && continue; \
base=$(basename "$lib"); \
destfile="$LIBS_TMP_DIR/$base"; \
if [ ! -f "$destfile" ]; then \
cp "$lib" "$destfile"; \
fi; \
done; \
done
# Базовый образ Distroless Debian — убедитесь, что версия Debian совпадает с базовым образом
FROM gcr.io/distroless/base-debian13
# Альтернатива: Docker Hardened Image
# FROM dhi.io/debian:13
# Путь к приложению и Caddyfile для копирования в контейнер
ARG PATH_TO_APP="."
ARG PATH_TO_CADDYFILE="./Caddyfile"
# Скопировать приложение в /app
# Для дополнительного усиления убедитесь, что только записываемые пути принадлежат пользователю nonroot
COPY --chown=nonroot:nonroot "$PATH_TO_APP" /app
COPY "$PATH_TO_CADDYFILE" /etc/caddy/Caddyfile
# Скопировать frankenphp и необходимые библиотеки
COPY --from=builder /usr/local/bin/frankenphp /usr/local/bin/frankenphp
COPY --from=builder /usr/local/lib/php/extensions /usr/local/lib/php/extensions
COPY --from=builder /tmp/libs /usr/lib
# Скопировать конфигурационные файлы php.ini
COPY --from=builder /usr/local/etc/php/conf.d /usr/local/etc/php/conf.d
COPY --from=builder /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
# Директории данных Caddy — должны быть доступны для записи пользователю nonroot даже в файловой системе только для чтения
ENV XDG_CONFIG_HOME=/config \
XDG_DATA_HOME=/data
COPY --from=builder --chown=nonroot:nonroot /data/caddy /data/caddy
COPY --from=builder --chown=nonroot:nonroot /config/caddy /config/caddy
USER nonroot
WORKDIR /app
# Точка входа для запуска frankenphp с указанным Caddyfile
ENTRYPOINT ["/usr/local/bin/frankenphp", "run", "-c", "/etc/caddy/Caddyfile"]
Версии для разработки доступны в Docker-репозитории dunglas/frankenphp-dev.
Сборка запускается автоматически при каждом коммите в основную ветку GitHub-репозитория.
Теги latest* указывают на голову ветки main.
Также доступны теги в формате sha-<git-commit-hash>.