尧图精选

FrankenPHP 生产环境部署实战:用 Docker Compose 在单台 Linux 服务器上发布 PHP 应用

🕒 发布时间:2026/9/16 3:25:59 📁 来源:尧图网络
FrankenPHP 生产环境部署实战用 Docker Compose 在单台 Linux 服务器上发布 PHP 应用【免费下载链接】frankenphp The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp本篇技术指南以 FrankenPHP 官方文档《Déploiement en production》为主体系统讲解如何借助 Docker Compose 将 PHP 应用部署到生产服务器从编写生产级Dockerfile、准备服务器与域名到一键启动、自动签发 HTTPS 证书再到反向代理与多节点集群部署。读完本文你将掌握一套可直接复制上线的 FrankenPHP 生产部署流程并理解其底层镜像结构与 Caddy 配置机制。部署方案概览FrankenPHP 是基于 Caddy 构建的现代 PHP 应用服务器它把 Web 服务器与 PHP 解释器打包进同一个二进制、同一套配置体系中因此生产部署可以极度简化不再需要单独配置 Nginx PHP-FPM 两套组件只需一个运行 FrankenPHP 的 Docker 容器即可同时承担静态文件服务、PHP 执行、自动 HTTPS 证书管理与 HTTP/3 支持。本教程的部署目标是单台 Linux 服务器应用打包进 Docker 镜像通过 Docker Compose 编排启动Caddy 自动为域名申请并续期 TLS 证书。官方建议若你使用 Symfony可参考基于 FrankenPHP 的 Symfony Docker 项目的生产部署文档若使用 API Platform同样基于 FrankenPHP则可参考该框架自带的部署文档——本文提供的是与框架无关的通用方案。第一步准备你的应用镜像编写生产级 Dockerfile在 PHP 项目根目录创建一个Dockerfile以官方镜像为基础定制你的应用FROM dunglas/frankenphp # 务必把 your-domain-name.example.com 替换成你的真实域名 ENV SERVER_NAMEyour-domain-name.example.com # 如果你想禁用 HTTPS改用下面的值 #ENV SERVER_NAME:80 # 如果你的项目不是以 public 目录作为 Web 根目录可以在这里指定 # ENV SERVER_ROOTweb/ # 启用 PHP 的生产环境配置 RUN mv $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini # 把项目的 PHP 文件拷贝到 public 目录 COPY . /app/public # 如果你使用 Symfony 或 Laravel需要把整个项目拷贝过去 #COPY . /app各指令的含义与背景如下ENV SERVER_NAME该变量直接注入到镜像内置的默认 Caddyfile 中见仓库中的 caddy/frankenphp/Caddyfile用于决定 Caddy 监听哪些地址、为哪些主机名自动申请 TLS 证书。镜像默认值为localhost设置为域名后Caddy 会在启动时自动向 Lets Encrypt 申请该域名的 HTTPS 证书。若只想走 HTTP如暂未备案或内网环境设置为:80即可关闭自动 HTTPS。ENV SERVER_ROOT对应默认 Caddyfile 中的root {$SERVER_ROOT:public/}指令默认值为public/。多数框架Symfony、Laravel 等以public/作为 Web 根目录无需改动若你的入口目录不同例如web/在此覆盖。mv $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini官方 PHP 镜像默认不启用任何php.ini仅提供php.ini-production与php.ini-development两个模板。生产环境务必启用前者错误展示、display_errors、内存限制等参数均按生产安全基准预设。开发环境可改拷php.ini-development。这一用法同样记录在 docs/fr/config.md 的 Docker 配置一节中。COPY . /app/public仅把应用源码放进 Web 根目录适合入口全部在public/下的项目Symfony/Laravel 需要把vendor、var等目录一并打包因此改为COPY . /app。提示如果你的项目使用 Composer 管理依赖必须把 Composer 装进镜像并在构建阶段执行依赖安装官方推荐多阶段构建可参考 docs/fr/docker.md 中关于自定义镜像、安装 PHP 扩展与 Caddy 模块的详细说明。理解官方镜像的结构为了写出更贴合实际的 Dockerfile有必要了解官方镜像内部布局。仓库根目录的 Dockerfile 展示了镜像的关键事实镜像基于官方 PHP 镜像php-base构建WORKDIR为/app并预创建/app/public、/config/caddy、/data/caddy、/etc/caddy、/etc/frankenphp等目录默认入口为frankenphp run --config /etc/frankenphp/Caddyfile --adapter caddyfile设置XDG_CONFIG_HOME/config、XDG_DATA_HOME/data即 Caddy 的配置与数据含 TLS 证书、ACME 账户分别存放在/config与/data——这正是compose.yaml中必须为这两个目录挂载持久化卷的原因暴露端口80、443、443/udpHTTP/3以及管理端口2019内置健康检查curl -f http://localhost:2019/metrics因此docker compose up --wait可以等待容器真正就绪。镜像内置的默认 caddy/frankenphp/Caddyfile 还声明了encode zstd br gzip内容压缩、php_serverPHP 执行 静态文件服务以及FRANKENPHP_CONFIG、CADDY_GLOBAL_OPTIONS等环境变量注入点生产环境可按需覆盖。编写 compose.yaml 编排文件接着在项目根目录添加compose.yamlservices: php: image: dunglas/frankenphp restart: always ports: - 80:80 # HTTP - 443:443 # HTTPS - 443:443/udp # HTTP/3 volumes: - caddy_data:/data - caddy_config:/config # Caddy 证书与配置所需的卷 volumes: caddy_data: caddy_config:要点说明restart: always容器异常退出后由 Docker 自动拉起是生产环境的必要配置端口映射80HTTP用于跳转/挑战、443HTTPS、443/udpHTTP/3需要宿主内核支持 UDP若镜像中改用了非特权端口此处需相应调整caddy_data与caddy_config两个命名卷分别对应镜像内的/data与/config。Caddy 自动申请的 TLS 证书与 ACME 账号信息存放在/data/caddyCaddyfile 配置相关状态存放在/config/caddy。必须持久化否则每次重建容器都会重新申请证书极易触发 Lets Encrypt 速率限制。注意以上示例面向生产环境。开发时你可能更希望挂载源码卷、使用php.ini-development、并将SERVER_NAME设为localhost之类便于本地调试的值更进阶的多阶段构建、Composer、额外 PHP 扩展等可参考基于 FrankenPHP 的 Symfony Docker 项目。最后若项目使用 Git 管理提交以上两个文件并推送到远端仓库即可进入服务器准备环节。第二步准备一台服务器生产部署需要一个 Linux 服务器。教程以 DigitalOcean 的虚拟机Droplet为例实际上任何装有 Docker 的 Linux 服务器均可。如果你已经有一台装好 Docker 的 Linux 服务器可以直接跳到「配置域名」一节。在 DigitalOcean 的「Create a Droplet」流程中在 Choose an image 区域切换到Marketplace应用市场标签页搜索名为Docker的应用镜像选择该镜像即可快速获得一台预装最新版 Docker 与 Docker Compose 的 Ubuntu 服务器测试用途选择最便宜的套餐即可真实生产负载建议按业务规模选择 General Usage通用型套餐其余选项可保持默认务必配置 SSH 密钥或 root 密码然后点击 Finalize and create。等待几十秒完成初始化后用 SSH 登录ssh rootdroplet-ip第三步配置域名大多数生产站点需要绑定域名。若尚未拥有域名先通过注册商购买。然后在 DNS 服务商处为域名添加一条A 记录指向服务器 IPyour-domain-name.example.com. IN A 207.154.233.113在 DigitalOcean Domains 服务Networking Domains中按上图方式添加即可。重要提示FrankenPHP 默认使用Lets Encrypt自动签发 TLS 证书而 Lets Encrypt不支持为裸 IP 地址签发证书因此使用域名是启用自动 HTTPS 的硬性前提。若你的场景必须使用 IP 直接访问只能放弃自动 HTTPS 或改用其他证书方案。第四步执行部署将项目拷贝到服务器方式不限git clone、scp均可。使用 Git 时可考虑配置部署密钥Deploy Key以只读权限拉取代码GitHub 与 GitLab 均支持。示例git clone gitgithub.com:username/project-name.git进入项目目录并启动应用docker compose up --wait--wait会等待容器通过健康检查即镜像内置的curl http://localhost:2019/metrics后才返回。启动完成后服务器已对外提供服务Caddy 已自动为你的域名申请并配置好 HTTPS 证书直接访问https://your-domain-name.example.com即可看到你的应用。警告Docker 构建存在缓存层每次部署前务必确认拿到的是最新构建产物若怀疑缓存导致旧代码上线可用docker compose build --no-cache强制全量重建避免改了代码没生效的坑。第五步在反向代理 / 负载均衡之后运行如果你的架构中 FrankenPHP 位于反向代理或负载均衡之后例如 Nginx、AWS ELB、Google Cloud LB必须解决信任链问题否则客户端真实信息会丢失。1. 让 Caddy 信任代理在 Caddyfile 的全局选项中配置trusted_proxies使 Caddy 信任上游传入的X-Forwarded-*请求头{ servers { trusted_proxies static your-IPs } }将your-IPs替换为代理/负载均衡的真实 IP 或网段多个 IP 以空格分隔。只有来自这些可信 IP 的X-Forwarded-For、X-Forwarded-Proto等头部才会被采纳这直接关系到访问日志中的客户端 IP 与 HTTPS 协议判断是否正确。2. 让 PHP 框架信任代理反向代理场景下仅配置 Caddy 还不够——PHP 框架层也必须显式信任代理否则框架会忽略这些头部Symfony设置TRUSTED_PROXIES环境变量Laravel配置trustedproxies中间件。以上两处配置缺一不可。缺少任一层信任X-Forwarded-For与X-Forwarded-Proto都会被忽略从而出现 HTTPS 检测错误强制跳转回 HTTP、客户端 IP 记录错误等典型生产事故。第六步多节点集群部署单机容量不足时可将应用横向扩展到多台机器Docker Swarm官方 Compose 文件与 Swarm 的 stack 部署兼容可直接用docker stack deploy把同一份编排文件跑在集群上Kubernetes可参考 API Platform 提供的 Helm chart其底层同样使用 FrankenPHP它封装了 Deployment、Service、Ingress 与证书管理等完整资源适合已有 K8s 基础设施的团队。生产环境进阶加固建议除了本教程的核心流程结合仓库文档 docs/fr/docker.md 与 docs/fr/config.md以下实践可进一步提升生产部署质量启用 Worker 模式通过FRANKENPHP_CONFIG环境变量让应用以常驻内存的 worker 方式启动ENV FRANKENPHP_CONFIGworker ./public/index.php避免每次请求重新引导框架显著降低开销php_server内的worker指令同样支持多 worker 配置详见 docs/fr/worker.md。以非 root 用户运行在 Dockerfile 中创建普通用户并用setcap cap_net_bind_serviceeip保留 80/443 绑定能力若改用非特权端口如:8000甚至可以完全移除该 capability降低提权风险。镜像加固基于 Google distroless 或 Docker hardened 等最小基础镜像二次构建可显著缩小攻击面与镜像体积注意这类镜像不含 shell 与包管理器调试不便仅建议安全要求极高的生产环境使用具体多阶段构建脚本见 docs/fr/docker.md。内存泄漏兜底若第三方扩展存在无法根除的内存增长可在 Caddyfile 全局设置max_requests例如max_requests 500让 PHP 线程处理完指定请求数后自动重启释放内存该机制属于实验性功能见 docs/fr/config.md。至此一套从镜像构建、服务器初始化、域名与 TLS 证书到反向代理和集群扩展的 FrankenPHP 生产部署方案已经完整落地你可以直接照着在本项目仓库对应的 docs/fr/production.md 基础上按需裁剪使用。【免费下载链接】frankenphp The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →