Yii框架不内置CI/CD,需通过Git+GitHub Actions等工具链实现;关键在于目录隔离、配置解耦、命令可复现,如web/设为DocumentRoot、runtime/和assets/可写但不入Git、敏感配置用环境变量注入、生产部署执行composer install --no-dev。

Yii 框架本身不内置 CI/CD 能力,但能无缝集成主流工具链;关键不是“Yii 怎么做 CI/CD”,而是「怎么让 Yii 项目适配 Git + GitHub Actions / GitLab CI / Jenkins 的标准流程」——重点在目录隔离、配置解耦、命令可复现。
为什么直接 push 到服务器会失败
常见错误现象:Class 'yii\web\Application' not found、Failed to open stream: No such file or directory in index.php、runtime/ is not writable。根本原因是:生产环境缺少 vendor/、未生成 autoload、web/ 不是 DocumentRoot、或 config/db.php 里硬编码了本地密码。
- Yii 的
web/目录必须设为 Web 服务器的根目录(DocumentRoot),不能把整个项目根目录暴露出去 -
runtime/和web/assets/必须可写,但不应纳入 Git(加到.gitignore) -
config/db.php等含敏感信息的文件,必须从版本库剥离,改用环境变量注入 -
composer install --no-dev是生产部署的强制要求,否则会引入phpunit等非运行时依赖
GitHub Actions 自动化部署 YAML 关键段
以部署到 Linux 服务器为例,核心是「构建 → 传输 → 重载」三步闭环。以下片段可直接用于 .github/workflows/deploy.yml:
name: Deploy to Production
on:
push:
branches: [main]
paths-ignore: ['**/*.md', '**/tests/**']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, pdo, pdo_mysql, openssl, xml, zip
- name: Install dependencies
run: composer install --no-interaction --no-dev --optimize-autoloader
- name: Upload to server
uses: appleboy/scp-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
source: ".*, !.git, !.github, !tests, !docker-compose.yml"
target: "/var/www/myapp"
- name: Remote commands
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /var/www/myapp
chmod -R 775 runtime/ web/assets/
chown -R www-data:www-data runtime/ web/assets/
php yii migrate/up --interactive=0 2>/dev/null || true注意:php yii migrate/up 加了 --interactive=0 和 || true 是为了防止无新迁移时中断流程;生产环境迁移应人工审核,此处仅作兜底。
环境变量驱动的 config/db.php 怎么写
这是多环境部署最易翻车的一环。不要在 config/db.php 里写死数据库地址,而要靠 getenv() 动态加载:
return [
'class' => 'yii\db\Connection',
'dsn' => getenv('DB_DSN') ?: 'mysql:host=localhost;dbname=testdb',
'username' => getenv('DB_USER') ?: 'root',
'password' => getenv('DB_PASSWORD') ?: '',
'charset' => 'utf8mb4',
];然后在目标服务器的 Web 服务配置中注入环境变量(Nginx + PHP-FPM 示例):
location ~ \.php$ {
fastcgi_param DB_DSN "mysql:host=db;dbname=myapp";
fastcgi_param DB_USER "appuser";
fastcgi_param DB_PASSWORD "s3cr3t!";
# ... 其他 fastcgi_param
}或者更稳妥地,在 /etc/php/*/fpm/pool.d/www.conf 中加:env[DB_DSN] = mysql:host=db;dbname=myapp。这样既不依赖 .env 文件,也不暴露在 PHP $_SERVER 中。
advanced 模板下前后端分离部署要注意什么
使用 yii2-app-advanced 时,frontend/web/ 和 backend/web/ 是两个独立入口,不能共用一个 DocumentRoot。
- Nginx 需配置两个 server 块,分别指向
/path/to/project/frontend/web和/path/to/project/backend/web -
frontend/config/main-local.php和backend/config/main-local.php必须各自独立管理环境变量 - CI 流程中要分别执行
cd frontend && composer install --no-dev和cd backend && composer install --no-dev - 迁移命令需指定应用路径:
php ./frontend/yii migrate/up和php ./backend/yii migrate/up
忽略 environments/ 目录的自动替换逻辑(如 init 命令),在 CI 中全部用环境变量替代——因为 init 是交互式命令,无法在无 TTY 的 pipeline 中运行。


















