FrankenPHP Docker 镜像基于 官方 PHP 镜像。为流行的架构提供了 Debian 和 Alpine Linux 版本。建议使用 Debian 版本。

提供了 PHP 8.2 和 PHP 8.3 的变体。

标签遵循这种模式:dunglas/frankenphp/<frankenphp-version>-php<php-version>-<os>

  • <frankenphp-version><php-version> 分别代表 FrankenPHP 和 PHP 的主版本、次版本或补丁版本。
  • <os>bookworm(Debian Bookworm)或 alpine(最新稳定版的 Alpine)。

浏览标签

如何使用这些镜像

在您的项目中创建一个 Dockerfile

  1. FROM dunglas/frankenphp
  2. COPY . /app/public

然后,运行以下命令构建并运行 Docker 镜像:

  1. docker build -t my-php-app .
  2. docker run -it --rm --name my-running-app my-php-app

如何安装更多 PHP 扩展

基础镜像中提供了 docker-php-extension-installer 脚本。添加额外的 PHP 扩展非常简单:

  1. FROM dunglas/frankenphp
  2. # 在此处添加额外的扩展:
  3. RUN install-php-extensions \
  4. pdo_mysql \
  5. gd \
  6. intl \
  7. zip \
  8. opcache

如何安装更多 Caddy 模块

FrankenPHP 建立在 Caddy 之上,所有 Caddy 模块 都可以与 FrankenPHP 一起使用。

安装自定义 Caddy 模块的最简单方法是使用 xcaddy

  1. FROM dunglas/frankenphp:latest-builder AS builder
  2. # 将 xcaddy 复制到构建镜像中
  3. COPY --from=caddy:builder /usr/bin/xcaddy /usr/bin/xcaddy
  4. # 必须启用 CGO 才能构建 FrankenPHP
  5. ENV CGO_ENABLED=1 XCADDY_SETCAP=1 XCADDY_GO_BUILD_FLAGS="-ldflags '-w -s'"
  6. RUN xcaddy build \
  7. --output /usr/local/bin/frankenphp \
  8. --with github.com/dunglas/frankenphp=./ \
  9. --with github.com/dunglas/frankenphp/caddy=./caddy/ \
  10. # Mercure 和 Vulcain 包含在官方构建中,但可以自由移除它们
  11. --with github.com/dunglas/caddy-cbrotli \
  12. --with github.com/dunglas/mercure/caddy \
  13. --with github.com/dunglas/vulcain/caddy
  14. # 在此处添加额外的 Caddy 模块
  15. FROM dunglas/frankenphp AS runner
  16. # 用包含自定义模块的二进制文件替换官方二进制文件
  17. COPY --from=builder /usr/local/bin/frankenphp /usr/local/bin/frankenphp

FrankenPHP 提供的 builder 镜像包含了 libphp 的编译版本。构建镜像 为所有版本的 FrankenPHP 和 PHP 提供,包括 Debian 和 Alpine。

提示

如果你使用 Alpine Linux 和 Symfony,可能需要增加默认栈大小

默认启用工作模式

设置 FRANKENPHP_CONFIG 环境变量以使用工作脚本启动 FrankenPHP:

  1. FROM dunglas/frankenphp
  2. # ...
  3. ENV FRANKENPHP_CONFIG="worker ./public/index.php"

在开发中使用卷

为了更容易地使用 FrankenPHP 进行开发,将包含应用源代码的宿主机目录作为卷挂载到 Docker 容器中:

  1. 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:

  1. # compose.yaml
  2. services:
  3. php:
  4. image: dunglas/frankenphp
  5. # 如果你想使用自定义 Dockerfile,请取消下面一行的注释
  6. #build: .
  7. # 如果你想在生产环境中运行,请取消下面一行的注释
  8. # restart: always
  9. ports:
  10. - "80:80" # HTTP
  11. - "443:443" # HTTPS
  12. - "443:443/udp" # HTTP/3
  13. volumes:
  14. - ./:/app/public
  15. - caddy_data:/data
  16. - caddy_config:/config
  17. # 在生产中注释下面一行,它允许在开发中有美观的人类可读日志
  18. tty: true
  19. # Caddy 证书和配置所需的卷
  20. volumes:
  21. caddy_data:
  22. caddy_config:

作为非 root 用户运行

FrankenPHP 可以在 Docker 中作为非 root 用户运行。

这是一个示例 Dockerfile 这样做:

  1. FROM dunglas/frankenphp
  2. ARG USER=www-data
  3. RUN \
  4. # 对于基于 Alpine 的发行版使用 "adduser -D ${USER}"
  5. useradd -D ${USER}; \
  6. # 增加绑定端口 80 和 443 的额外能力
  7. setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/frankenphp; \
  8. # 给 /data/caddy 和 /config/caddy 写访问权限
  9. chown -R ${USER}:${USER} /data/caddy && chown -R ${USER}:${USER} /config/caddy
  10. USER ${USER}

无需任何能力运行

即使以无根用户身份运行,FrankenPHP 也需要 CAP_NET_BIND_SERVICE 能力才能在特权端口(80 和 443)上绑定 web 服务器。

如果你将 FrankenPHP 暴露在非特权端口(1024 及以上),可以作为非 root 用户运行 web 服务器,而且不需要任何能力:

  1. FROM dunglas/frankenphp
  2. ARG USER=www-data
  3. RUN \
  4. # 对于基于 Alpine 的发行版使用 "adduser -D ${USER}"
  5. useradd -D ${USER}; \
  6. # 移除默认能力
  7. setcap -r /usr/local/bin/frankenphp; \
  8. # 给 /data/caddy 和 /config/caddy 写访问权限
  9. chown -R ${USER}:${USER} /data/caddy && chown -R ${USER}:${USER} /config/caddy
  10. USER ${USER}

接下来,设置 SERVER_NAME 环境变量以使用非特权端口。示例::8000

更新

Docker 镜像构建:

  • 当标记新版本时
  • 如果官方 PHP 镜像有新版本,则在协调世界时每天凌晨 4 点

开发版本

开发版本可在 dunglas/frankenphp-dev Docker 仓库中获得。每次将提交推送到 GitHub 仓库的主分支时,都会触发新的构建。

latest 标签指向 main 分支的头部。还提供形式为 sha-<git-commit-hash> 的标签。