PHP项目Symfony platformsh与云部署

wen PHP项目 3

本文目录导读:

PHP项目Symfony platformsh与云部署

  1. 核心优势 (Why Platform.sh for Symfony?)
  2. 核心配置文件 (项目根目录)
  3. 环境变量适配文件 (关键)
  4. 本地开发与调试
  5. 数据库迁移与部署策略
  6. 常见问题与坑 (Troubleshooting)
  7. 性能优化建议
  8. 快速入门脚本

这是一个非常专业且具体的 PHP 项目部署问题,我将为你详细解析 Symfony 项目在 Platform.sh 上的云部署流程、核心配置及最佳实践。

这是目前 PHP 全栈开发中非常主流且高效的 PaaS 方案组合。


核心优势 (Why Platform.sh for Symfony?)

  • 无缝集成: Platform.sh 专为 Symfony 设计,拥有官方维护的 symfony 工具包和默认配置。
  • 完美容器化: 自动为每个环境(开发/测试/生产/PR)生成独立的容器,环境完全隔离且复制。
  • 自带 PaaS: 内置数据库(PostgreSQL/MySQL)、Redis、Elasticsearch、Solr 等服务,无需额外配置。
  • 自动化部署: 原生支持 Git 驱动部署,每个分支自动生成一个预览环境,可直接访问。
  • 无缝迁移: 可以零停机地进行数据库迁移、环境切换。

核心配置文件 (项目根目录)

Platform.sh 通过以下三个 YAML 文件定义整个项目的拓扑结构和构建流程。

.platform/routes.yaml

定义 HTTP 路由规则,决定域名如何连接到哪个应用。

# .platform/routes.yaml
"https://{default}/":
    type: upstream
    upstream: "app:http"
    # 强制 HTTPS
    ssl:
        enabled: true
"https://www.{default}/":
    type: redirect
    to: "https://{default}/"

.platform/services.yaml

定义项目所需的外部服务(数据库、缓存、搜索等)。

# .platform/services.yaml
database:
    # 推荐使用 PostgreSQL
    type: postgresql:15
    disk: 2048
cache:
    # Redis 用于 Symfony 缓存/会话/锁
    type: redis:7.0
search:
    # 用于全文搜索 (可选)
    type: elasticsearch:8.12
    disk: 1024
# 可选:队列
# queue:
#     type: rabbitmq:3.13

.platform.app.yaml (核心应用定义)

这是最关键的文件,定义了 PHP 版本、Symfony 构建、依赖、worker 以及磁盘挂载。

要点解读:

# .platform.app.yaml
name: app
type: 'php:8.3'  # 使用最新 LTS PHP
# 基础设施
relationships:
    database: "database:postgresql"
    redis: "cache:redis"
    elasticsearch: "search:elasticsearch"
    # queue: "queue:rabbitmq"
# 构建步骤 (在 composer install 后执行)
hooks:
    build: |
        set -x -e
        cp .env.platformsh .env.local  # 复制环境变量
        composer install --no-dev --optimize-autoloader
        # Symfony 构建优化
        php bin/console cache:clear --env=prod
        php bin/console assets:install --symlink --relative public
    deploy: |
        # 数据库迁移 (仅在主分支或生产环境执行)
        php bin/console doctrine:migrations:migrate --env=prod --no-interaction --allow-no-migration
        # 预热缓存
        php bin/console cache:warmup --env=prod
# Web 入口
web:
    locations:
        '/':
            root: 'public'
            passthru: '/index.php'  # Symfony 入口
            # 静态文件缓存 (长期缓存)
            expires: 1y
            scripts: false
            allow: true
        '/var/cache':
            # 避免缓存目录被访问
            deny: true
# 磁盘挂载 (持久化数据)
disk: 2048
mounts:
    # Symfony 日志
    '/var/log': { source: local, source_path: log }
    # 用户上传文件
    '/public/uploads': { source: local, source_path: uploads }
    # Doctrine 结果缓存 (可选)
    '/var/cache': { source: local, source_path: cache }
# Worker 进程 (可选, 处理异步任务如邮件)
workers:
    messenger_consume:
        commands:
            # 消费 Symfony Messenger 消息
            start: php bin/console messenger:consume async -vv
        # 与 web 容器共享持久化数据
        mounts:
            '/var/log': { source: local, source_path: log }
# 环境变量注入
variables:
    env:
        APP_ENV: 'prod'
        # 自动注入 Platform.sh 服务连接信息
        DATABASE_URL: '${PLATFORM_RELATIONSHIPS:database:postgresql:url}'
        REDIS_URL: '${PLATFORM_RELATIONSHIPS:redis:redis:url}'
        # MAILER_DSN: 'sendmail://default'  # Platform.sh 内置邮件

环境变量适配文件 (关键)

不要手动写死 DATABASE_URL,使用 symfony/psr-http-message-bridge 提供的自动配置包。

推荐方式:使用 symfony/runtime + symfony/psr-http-message-bridge

无需编写 .env.platformsh 文件,安装依赖即可:

composer require symfony/runtime symfony/psr-http-message-bridge

这样,Symfony 会自动读取 PLATFORM_RELATIONSHIPS 环境变量,并将 services.yaml 中的服务自动注入到 Symfony DI 容器中。

传统方式(手动配置 .env.local

# 在构建钩子中运行:cp .env.platformsh .env.local
# 然后在 .env.local 中:
DATABASE_URL="${PLATFORM_RELATIONSHIPS:database:postgresql:url}"
REDIS_CACHE_URL="${PLATFORM_RELATIONSHIPS:redis:redis:url}"
ELASTICSEARCH_DSN="${PLATFORM_RELATIONSHIPS:elasticsearch:elasticsearch:url}"
MAILER_DSN="sendmail://default"

本地开发与调试

Platform.sh 提供了 platform CLI 工具,支持本地开发环境。

  1. 安装 CLI:

    curl -fsSL https://platform.sh/cli/installer | bash
  2. 登录并初始化:

    platform login
    platform project:create --title "My Symfony App"
  3. 本地启动 (类似 Docker Compose):

    platform local:build
    platform local:start

    这会在本地启动一个完全相同的容器化环境(PHP, PostgreSQL, Redis)。


数据库迁移与部署策略

部署时最常见的风险是 数据库 Schema 变更导致生产环境中断

零停机迁移最佳实践 (适用于高流量站点)

  1. 利用 deploy 钩子: 在 .platform.app.yamldeploy 阶段,运行:

    php bin/console doctrine:migrations:migrate --env=prod --no-interaction

    deploy 钩子会在新容器启动且 接管旧流量之前 运行,这意味着:

    • 旧版本仍然在线。
    • 新容器执行迁移(可能花了 5 秒)。
    • 迁移成功后,路由器将流量切换到新容器。
    • 整个过程对用户透明。
  2. 回滚策略: 如果需要回滚,Platform.sh 会自动将流量切回旧容器,但数据库迁移 回滚需要手动编写

    • 推荐方案: 遵循 可逆迁移 原则,新增字段时,不要立即使该字段 NOT NULL,而是先添加,允许 NULL,然后逐步填充,回滚时,删除该字段即可。

常见问题与坑 (Troubleshooting)

问题 原因 解决方案
502 Bad Gateway PHP-FPM 崩溃或入口文件错误 检查 web.locationsroot 是否正确指向 public;查看日志:platform log --lines 100
数据库连接失败 .platform.app.yamlrelationshipsservices.yaml 名称不匹配 确保 services.yaml 定义的 database 名称与 relationships: database: 一致
Composer 内存不足 构建时 composer 需要大量内存 hooks.build 中添加:COMPOSER_MEMORY_LIMIT=-1 composer install ...
Session 丢失 没有配置 Redis 作为 Session 存储 修改 config/packages/framework.yamlsession: { handler_id: 'cache.redis' }
文件上传失败 public/uploads 目录未挂载 确保 .platform.app.yamlmounts 正确配置并写入 public/uploads
HTTP 缓存不起作用 Symfony 的 http_cache 没有挂载 使用 Redis 或 文件缓存作为 cache.pool;在 public/index.php 中启用反向代理。

性能优化建议

  1. Redis 做主缓存:

    # services.yaml
    cache:
        type: redis:7.0
    # config/packages/cache.yaml
    framework:
        cache:
            app: cache.adapter.redis
            system: cache.adapter.redis
  2. 启用 OPCache (JIT):

    # .platform.app.yaml
    variables:
        env:
            PHP_OPCACHE_VALIDATE_TIMESTAMPS: "0"  # 生产环境禁用文件时间检查
            PHP_OPCACHE_JIT: "tracing"
            PHP_OPCACHE_JIT_BUFFER_SIZE: "100M"
  3. CDN + 静态文件: 在 web.locations['/'] 中设置 expires: 1y 并开启 gzip


快速入门脚本

  1. 安装 Platform.sh CLI:

    curl -fsSL https://platform.sh/cli/installer | bash
  2. 创建新项目:

    platform project:create --title "my-symfony-app" --region "eu-3.platform.sh"
  3. 推送代码到 Platform.sh:

    git remote add platform <你的 Platform.sh Git 地址>
    git push platform main
  4. 访问预览环境: Platform.sh 会自动为 main 分支生成一个可访问的 URL,格式如: https://main-xxxxxxxx-xxxxxxxx-xxxx.eu-3.platformsh.site/

  5. 一键创建环境:

    platform environment:branch feature/new-feature

对于 Symfony 项目,Platform.sh 是目前 最佳的生产级云部署方案 之一。

  • 核心价值: 无需管理服务器,自动伸缩,每个分支都是一个完整环境。
  • 关键文件: 围绕 routes.yaml, services.yaml, .platform.app.yaml 三个文件。
  • 最佳实践: 使用 symfony/runtime 自动注入环境变量;利用 deploy 钩子实现零停机迁移;使用 Redis 做缓存和 Session。

如果你是从零开始,强烈建议使用 composer create-project symfony/skeleton . 然后运行 platform project:build,Platform.sh 会自动生成最完整的配置模板。

抱歉,评论功能暂时关闭!