Files
archived-frankenphp/docs/cn/docker.md
Antonin CLAUZIER 01beb66573 ci: PHP 8.5 (#2006)
Co-authored-by: Marc <m@pyc.ac>
Co-authored-by: Kévin Dunglas <kevin@dunglas.fr>
2025-11-21 13:54:07 +01:00

205 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 构建自定义 Docker 镜像
[FrankenPHP Docker 镜像](https://hub.docker.com/r/dunglas/frankenphp) 基于 [官方 PHP 镜像](https://hub.docker.com/_/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>` 要么是 `bookworm`(用于 Debian Bookworm要么是 `alpine`(用于 Alpine 的最新稳定版本)。
[浏览标签](https://hub.docker.com/r/dunglas/frankenphp/tags)。
## 如何使用镜像
在项目中创建 `Dockerfile`
```dockerfile
FROM dunglas/frankenphp
COPY . /app/public
```
然后运行以下命令以构建并运行 Docker 镜像:
```console
docker build -t my-php-app .
docker run -it --rm --name my-running-app my-php-app
```
## 如何安装更多 PHP 扩展
[`docker-php-extension-installer`](https://github.com/mlocati/docker-php-extension-installer) 脚本在基础镜像中提供。
添加额外的 PHP 扩展很简单:
```dockerfile
FROM dunglas/frankenphp
# 在此处添加其他扩展:
RUN install-php-extensions \
pdo_mysql \
gd \
intl \
zip \
opcache
```
## 如何安装更多 Caddy 模块
FrankenPHP 建立在 Caddy 之上,所有 [Caddy 模块](https://caddyserver.com/docs/modules/) 都可以与 FrankenPHP 一起使用。
安装自定义 Caddy 模块的最简单方法是使用 [xcaddy](https://github.com/caddyserver/xcaddy)
```dockerfile
FROM dunglas/frankenphp:builder AS builder
# 在构建器镜像中复制 xcaddy
COPY --from=caddy:builder /usr/bin/xcaddy /usr/bin/xcaddy
# 必须启用 CGO 才能构建 FrankenPHP
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
```
FrankenPHP 提供的 `builder` 镜像包含 `libphp` 的编译版本。
[用于构建的镜像](https://hub.docker.com/r/dunglas/frankenphp/tags?name=builder) 适用于所有版本的 FrankenPHP 和 PHP包括 Alpine 和 Debian。
> [!TIP]
>
> 如果你的系统基于 musl libcAlpine Linux 上默认使用)并搭配 Symfony 使用,
> 你可能需要 [增加默认堆栈大小](compile.md#using-xcaddy)。
## 默认启用 worker 模式
设置 `FRANKENPHP_CONFIG` 环境变量以使用 worker 脚本启动 FrankenPHP
```dockerfile
FROM dunglas/frankenphp
# ...
ENV FRANKENPHP_CONFIG="worker ./public/index.php"
```
## 开发挂载宿主机目录
要使用 FrankenPHP 轻松开发,请从包含应用程序源代码的主机挂载目录作为 Docker 容器中的 volume
```console
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
```yaml
# compose.yaml
services:
php:
image: dunglas/frankenphp
# 如果要使用自定义 Dockerfile请取消注释以下行
#build: .
# 如果要在生产环境中运行,请取消注释以下行
# restart: always
ports:
- "80:80" # HTTP
- "443:443" # HTTPS
- "443:443/udp" # HTTP/3
volumes:
- ./:/app/public
- caddy_data:/data
- caddy_config:/config
# 在生产环境中注释以下行,它允许在 dev 中使用清晰可读日志
tty: true
# Caddy 证书和配置所需的挂载目录
volumes:
caddy_data:
caddy_config:
```
## 以非 root 用户身份运行
FrankenPHP 可以在 Docker 中以非 root 用户身份运行。
下面是一个示例 `Dockerfile`
```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}
```
### 无权限运行
即使在无根运行时FrankenPHP 也需要 `CAP_NET_BIND_SERVICE` 权限来将
Web 服务器绑定到特权端口80 和 443
如果你在非特权端口1024 及以上)上公开 FrankenPHP则可以以非 root 用户身份运行
Web 服务器,并且不需要任何权限:
```dockerfile
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 镜像会按照以下条件更新:
- 发布新的版本后
- 每日 4:00UTC 时间)检查新的 PHP 镜像
## 开发版本
可在此 [`dunglas/frankenphp-dev`](https://hub.docker.com/repository/docker/dunglas/frankenphp-dev) 仓库获取开发版本。
每次在 GitHub 仓库的主分支有新的 commit 都会触发一次新的 build。
`latest*` tag 指向最新的 `main` 分支,且同样支持 `sha-<git-commit-hash>` 的 tag。