SuperAPI AI 工具集

symfony-yoandev-local-dev

部署与运维

查看项目

更新于 10-16 06:03

技能介绍

用途

本技能用于在本地搭建并运行 Symfony 项目:服务(PostgreSQL、Mailpit)跑在 Docker 中,PHP 跑在宿主机,由 Symfony CLI 把两者连接起来。它属于核心层级——项目跑不起来就无法测试;而生产近似容器是按需使用的部分,应在发布前运行,而不是每天使用。

主要能力

  • 用 Docker Compose 启动 PostgreSQL 与 Mailpit。
  • 用 Symfony CLI 启动开发服务器(HTTPS),并自动注入环境变量。
  • 打开应用与查看已发送邮件的 Web 界面。
  • 通过 symfony var:export --debug 查看实际注入的变量及其来源。
  • 提供生产近似容器,用于发布前验证。
  • 提供常见启动故障的症状与原因对照。

使用方式

日常循环命令:

docker compose up -d          # PostgreSQL + Mailpit
symfony server:start -d       # dev server, HTTPS, variables injected
symfony open:local            # open the app
symfony open:local:webmail    # read the emails it sent

变量注入机制:不需要在任何地方写 DATABASE_URL 或 MAILER_DSN。Symfony CLI 会检查正在运行的容器,把每个暴露的容器端口与已知服务表进行匹配,并将变量导出到它启动的 PHP 进程中。可用以下命令查看:

symfony var:export --debug     # exactly what is being injected, and from where

这也是 compose.override.yaml 发布端口时不指定宿主机端口的原因:

services:
  database:
    ports:
      - "5432"     # not "5432:5432"

Docker 会选择一个空闲的宿主机端口,CLI 会发现它。两个项目可以并行运行,无需为了避开冲突而修改文件。固定宿主机端口会白白丢掉这一好处。

需要知道的后果:

  • symfony console 不等于 php bin/console。前者会获得注入的变量,后者不会。按此方式配置的项目中,php bin/console doctrine:migrations:migrate 会连接失败,而 symfony console … 可以正常工作,且错误信息不会解释原因。
  • 注入的变量优先于 .env.test。symfony console doctrine:database:drop --force --env=test 会删除开发数据库,因为 Docker 变量无论 --env 如何都会被应用。这是有文档记录的行为,且已导致真实数据丢失。针对测试数据库的操作请使用 php bin/console。

完整的检测表、服务命名标签以及如何让某个服务退出检测,见 references/symfony-cli.md。

搭建一个两者都没有的项目

把 assets/compose.yaml 和 assets/compose.override.yaml 复制到项目根目录。它们与 Doctrine 和 Mailer recipe 生成的内容一致,因此仍保留 recipe 的项目无需从这里获取任何内容。

然后执行:

docker compose up -d
symfony console doctrine:database:create
symfony console doctrine:migrations:migrate --no-interaction
symfony console doctrine:fixtures:load --no-interaction   # if the project has fixtures
symfony server:start -d

如果项目没有 fixtures 也没有种子数据,应如实说明,而不是编造数据行——一个能启动的空应用是正常结果,悄悄编造数据会掩盖上手流程不完整这一事实。

HTTPS

symfony server:ca:install     # once per machine

之后每个项目都通过 HTTPS 与 HTTP/2 提供服务,且没有证书警告。

这不仅是舒适度问题。AssetMapper 依赖 HTTP/2 多路复用:它提供许多小文件而不是一个 bundle。用纯 HTTP 开发意味着,唯一能注意到问题的环境与生产行为不同。它还会在你写代码的当天就暴露混合内容与安全 cookie 问题,而不是在部署之后。

邮件

Mailpit 捕获所有邮件,不会有任何内容离开本机。

symfony open:local:webmail

邮件似乎消失时检查两件事:

  • 它们可能只是排队,并未发送。该标准会把 SendEmailMessage 路由到 async 传输,因此在 worker 消费之前不会有内容到达 Mailpit。运行 symfony console messenger:consume async -vv,或接受邮件延迟出现。在测试中,适用的断言是 assertQueuedEmailCount(),而不是 assertEmailCount()。
  • mailer 服务必须暴露 1025 端口,这是 CLI 匹配的依据。8025 端口只是 Web 界面。

按生产方式检查

开发服务器在生产不具备的方面很宽容:加载了 profiler、OPcache 关闭、资源通过 PHP 提供、错误可见。有些 bug 只存在于这条线的另一侧。

docker compose -f compose.yaml -f compose.prod-like.yaml up --build
open https://localhost

assets/Dockerfile.prod-like 以 APP_ENV=prod、生产 php.ini、权威 classmap 和 asset-map:compile 构建。它能回答开发服务器无法回答的问题:

  • 资源是否真的能编译,并且是被提供而不是被生成;
  • 应用是否能在没有仅开发用 bundle 的情况下启动;
  • 是否有任何东西依赖 profiler 或 APP_DEBUG=1;
  • 当错误不再显示时,页面是否仍然可用。

这是验证步骤,不是工作环境。不要把日常开发搬进去:你会失去即时重载和单步调试,并且每次修改都要付出重建代价。在发布重要内容前运行,而不是每次提交前运行。

它也不是生产用 Dockerfile。真实部署请使用 dunglas/symfony-docker,它处理 worker、健康检查、非 root 用户和 TLS。运行时应查看的细节与清单见 references/frankenphp.md。

适用场景

  • 在本地启动并运行 Symfony 项目。
  • 需要 PostgreSQL 与邮件捕获的日常开发。
  • 发布前做生产近似验证。
  • 排查本地启动、变量注入、端口与邮件相关问题。

限制

  • 生产近似容器仅用于验证,不适合日常开发。
  • 它不是生产 Dockerfile;真实部署需使用 dunglas/symfony-docker。
  • 注入变量会覆盖 --env=test,针对测试数据库需使用 php bin/console。
  • 邮件默认走 async 传输,需消费 worker 才会到达 Mailpit。

启动故障排查

症状 原因
数据库连接被拒绝 容器未运行,或使用了 php bin/console 而非 symfony console
could not find driver 宿主机 PHP 缺少 pdo_pgsql——容器的扩展在这里无关
变量未注入 容器从不同目录启动,或 compose 项目名不同。检查 symfony var:export --debug
端口已被占用 compose.override.yaml 中固定了宿主机端口。移除它,让 Docker 选择
邮件从未到达 它们被排队了;消费该传输
迁移跑到了错误的数据库 Docker 变量覆盖了 --env=test。测试数据库请使用 php bin/console

symfony server:log 会把服务器、PHP 和应用日志显示在一个流中,通常比打开 var/log/dev.log 更快。

参考文件

文件 何时阅读
references/symfony-cli.md 变量注入、服务检测、命名标签、worker 进程
references/frankenphp.md 运行生产近似检查以及应关注什么