circleci虽无codeigniter专用支持,但可通过统一ci4初始化方式或ci3显式设置apppath/fcpath环境变量解决路径问题;须手动配置phpunit自动加载、禁止绝对路径、校验.env安全、用符号链接实现零停机部署。

CircleCI 本身不内置对 CodeIgniter 的特殊支持,但它的通用 Linux 运行环境完全能跑通这个框架——关键不是“能不能”,而是如何绕过 CodeIgniter 的隐式依赖和路径陷阱,让测试与部署真正可靠。
为什么 CI 流水线常在 composer install 后就失败
CodeIgniter 3 默认不走 composer 加载,而 CodeIgniter 4 虽然官方支持 Composer,但很多老项目仍混用手动 vendor 引入 + APPPATH/FCPATH 硬编码路径。CircleCI 默认工作目录是项目根,但若 index.php 中写死 require FCPATH . 'vendor/autoload.php';,而 FCPATH 指向 /var/www/html/(本地 Apache 路径),就会报 Failed opening required '.../vendor/autoload.php'。
解决办法只有两条路:
- 统一用
CodeIgniter 4并严格遵循其composer create-project codeigniter4/appstarter初始化方式,所有路径由system和app目录结构约束 - 如果是
CodeIgniter 3,必须在.circleci/config.yml中显式重写FCPATH和APPPATH—— 不靠 PHP 自动推导,而是用export注入环境变量 - 无论哪个版本,都禁止在
index.php或配置文件里写绝对路径;改用__DIR__或realpath()动态计算
phpunit 在 CircleCI 上找不到 CI_Controller
这是典型 autoloading 缺失:CI3 的核心类不在 PSR-4 规范下,CI4 则默认注册了 CodeIgniter\Autoloader\Autoloader,但 CircleCI 的 phpunit 进程启动时没加载它。
常见错误信息:Class 'CI_Controller' not found 或 Class 'Tests\Support\TestCase' not found。
- CI3 项目:在
phpunit.xml的<php></php>节点里加<const name="ENVIRONMENT" value="testing"></const>,并在tests/bootstrap.php中手动require_oncesystem/core/Controller.php和application/core/MY_Controller.php(如果存在) - CI4 项目:确保
phpunit.xml中bootstrap指向tests/_support/Bootstrap.php,且该文件调用了CodeIgniter\Testing\FeatureTestCase::setUp() - 无论哪个版本,都别信
phpunit --bootstrap vendor/autoload.php能自动搞定——CI 的类加载器必须被显式触发
部署到生产前,怎么验证 .env 不会暴露敏感信息
CodeIgniter 4 默认把 .env 放在 Web 根目录外,但很多团队为图省事把它放在 public/ 下,导致 @#@#@#@#@#@#@#@#@#@0 可直访。CircleCI 流水线没法替你改线上服务器配置,但它能提前拦截这种低级错误。
建议在 config.yml 的 test 阶段插入一个检查步骤:
- 运行
find . -name ".env" -path "./public/*" | grep -q "." && echo "FAIL: .env in public/" && exit 1 || echo "OK" - 同时检查
git status --porcelain是否包含未提交的.env—— 若有,说明有人把密钥 commit 进去了,应立即阻断流水线 - 更稳妥的做法是:CI 构建阶段完全不生成或复制
.env,只用circleci env注入CI_ENVIRONMENT、DB_HOST等变量,并在app/Config/Database.php中用$_ENV['DB_HOST'] ?? 'localhost'读取
构建产物怎么传给 Nginx 服务器而不中断服务
CodeIgniter 没有像 Laravel 那样内置 build 目录或静态资源哈希,所以“零停机部署”只能靠符号链接切换。
典型失败场景:直接 rsync -avz ./ /var/www/myapp/,期间 index.php 被覆盖一半,用户看到 Parse error。
- 在目标服务器上预设两个发布目录:
/var/www/myapp/releases/20260511123456/和/var/www/myapp/releases/20260511123501/ - CircleCI 的
deploy阶段用ssh执行脚本,把当前构建包解压进新时间戳目录,再ln -nfs releases/20260511123501 current -
current是 Nginxroot指向的路径,切换瞬间完成,无文件锁、无解析中断 - 务必在切换后执行
chown -R www-data:www-data current/,否则 CI 用ubuntu用户上传的文件,Nginx 会因权限拒绝读取app/Config/
真正的麻烦从来不在 YAML 写几行,而在 FCPATH 是否真等于 <strong>DIR</strong>、.env 是否真的没进 Git、以及 current 符号链接是否被其他运维脚本悄悄覆盖——这些细节不验,流水线越快,出事越突然。











