CI4 Apex Deploy System

Documentation

Introduction

CI4 Apex Deploy System

CI4 Apex Deploy System is the professional base system for developing and deploying fully containerized, production-ready CodeIgniter 4 applications with a switchable database engine. Unzip, configure, and run in under 10 minutes.

The kit solves the most common problems when starting a serious project:

  • Docker infrastructure ready out of the box
  • Functional CI4 environment from the first boot
  • Switchable database engine — MySQL or PostgreSQL, one command apart
  • VIAVI Operations Panel at /viavi/ for health, queues, profile and kit controls
  • VIAVI Intelligence in the panel (Professional/Ultimate) — environment diagnostics, log summaries and code scaffolding, powered by Claude (Anthropic) using your own API key
  • Foundation for real CI/CD pipelines
  • Production-ready from day one
Component Version Role
CodeIgniter 4 ^4.7 MVC framework, Shield auth, Queue
PHP 8.5 (FPM) Runtime, FastCGI
Nginx 1.28-alpine Reverse proxy, static files
Database MySQL 9.7 or PostgreSQL 16 Switchable via make db-switch-*
Redis 8.8-alpine Cache, sessions, queue backend
Supervisor system Manages php-fpm in prod container
Sentry SDK ^4.10 Error capture in production
PHPStan ^2.2 Static analysis level 6, zero errors
Rector ^2.5 Automated refactoring for PHP 8.5
PHPUnit ^11.2 Unit, bootstrap, session, and DB testing
pcov PECL Coverage driver (dev only)

Prerequisites

PHP and Composer are not required on the host machine — everything runs inside containers.

  • Docker Desktop 4.x or Docker Engine 24.x with Compose v2
  • GNU Make
  • Git 2.x

Implementation guide

1. Unzip the kit

Unzip the downloaded .zip file into your empty project folder.

2. Start the environment

$ make setup
# Runs: build + up + migrate + seed + healthcheck

You don't need to create .env manually — make setup generates it automatically from .env.example if it doesn't exist.

Starting fresh with PostgreSQL instead of MySQL? In that case you do need .env created before switching (the switch commands edit it in place): cp .env.example .env && make db-switch-postgres && make setup.

3. Verify the status

$ curl http://localhost:8080/health
// Expected response
{
  "status": "ok",
  "database": { "status": "ok" },
  "redis": { "status": "ok" }
}

4. Quality gates

$ make stan # PHPStan level 6 — no errors
$ make rector # Rector dry-run — no changes
$ make test # PHPUnit — all suites must pass

Configuration

Database engine

Switch between MySQL and PostgreSQL at any time. Each command tears down the running stack, rewrites .env, and points Docker Compose at the matching file:

$ make db-switch-mysql
$ make db-switch-postgres

No other command changes — make up, make migrate, make test, etc. all work identically regardless of which engine is active.

KIT_STAGE

Controls what is served at /. Toggle from the operations panel or via Make:

Valor Behavior
setup VIAVI onboarding screen (default)
building VIAVI onboarding screen while you build
launched Serves your application at /
$ make launch # KIT_STAGE=launched
$ make stage-building # KIT_STAGE=building
$ make stage-setup # KIT_STAGE=setup

On Railway/Render, .env is ephemeral — set KIT_STAGE in their environment variable panel instead. On VPS the file persists on disk, and the panel switch works correctly.

Default credentials

Change these credentials immediately after the first login.
Email admin@local.test
Password Password123!

Account recovery

If you lose the admin password, two options are available:

Option 1 — Web flow with recovery key

Requires RECOVERY_KEY to already be set in your .env (or Railway's variables) before you lose access — set it up now, not when you already need it.

1. Generate the key. The command uses OpenSSL to create 32 random bytes in hex format:

$ openssl rand -hex 32

On Windows, PowerShell doesn't ship with openssl built in. Run the command from Git Bash (installed alongside Git for Windows, which you already have) or from inside the container's shell: docker compose exec php openssl rand -hex 32 — either path gives the same result.

2. Save the generated key. Copy the value the command returns (a 64-character string) and add it to your .env:

RECOVERY_KEY=your_generated_key_here

On Railway, add it as a service environment variable instead of in .env (remember: .env is ephemeral there). Also save it in a password manager — it's your only recovery key if you lose access to the panel.

3. When you need to recover access: visit /viavi/profile/reset, confirm the account's current email, and enter the recovery key you saved in step 2.

Option 2 — Emergency CLI

Requires server or container access (SSH, or your host's terminal panel). Forces the account back to factory credentials regardless of whether you set up RECOVERY_KEY — this is the fallback if you never generated one:

$ make reset-admin

Usage

VIAVI Operations Panel

The kit ships with a built-in operations panel at /viavi/, always available regardless of your application's state.

URL Description
/viavi/ Main panel — health, queues, kit controls
/viavi-dashboard Shortcut to the operations panel
/viavi/ai VIAVI Intelligence — Professional: diagnose only. Ultimate: full
/viavi/profile Update email and password
/viavi/commands Makefile command reference
/health Public JSON healthcheck for orchestrators

VIAVI Intelligence

Available in the panel for Professional and Ultimate tiers. Powered by Claude (Anthropic), using your own API key — the kit never proxies or bills for these calls.

Capability Professional Ultimate
Diagnose environment
Summarize logs
Generate code

Log content is scanned and redacted for anything resembling a password, token, or API key before it is ever sent to the API. Generated code is always returned as text for manual review — never written to disk automatically.

Starting your application

  1. Edit app/Views/home.php with your application home screen.
  2. Define your routes in app/Config/Routes.php.
  3. Edit app/Controllers/Home.php with your root controller logic.
  4. Launch your app:
$ make launch

Routes reserved by the kit — do not overwrite: /viavi/*, /viavi-dashboard, /health, /login, /post-login, /set-organization/*

Available commands

$ make setup # Build, up, migrate, seed, healthcheck
$ make test # PHPUnit — all suites
$ make stan # PHPStan level 6
$ make rector # Rector dry-run
$ make migrate # Run pending migrations
$ make seed # Run seeders
$ make db-switch-mysql # Switch engine to MySQL
$ make db-switch-postgres # Switch engine to PostgreSQL
$ make launch # KIT_STAGE=launched
$ make down-v # docker compose down -v
$ make uninstall # Destroy volumes, reset .env (asks to confirm)
$ make deploy # Deploy (see scripts/deploy.sh)

Deployment

The kit includes deployment guides for three platforms. Select the one that best fits your project.

Railway

Ultimate Tier required

Single-container image. Environment variables are injected directly — the .env file is not used in production.

$ railway login
$ railway link
$ railway run php spark migrate --all

KIT_STAGE must be set in Railway's Variables panel, not in .env.

Render

Ultimate Tier required

Render does not offer MySQL natively — use Railway MySQL as an external provider (recommended: native foreign key support and simple credential copy-paste) or Aiven/PlanetScale as alternatives.

VPS (Ubuntu 24.04)

Ultimate Tier required

Full control. The .env file persists on disk, so the KIT_STAGE switch from the VIAVI panel works correctly in production.

$ ./scripts/deploy.sh v1.0.0
# backup → pull → migrate → healthcheck

FAQ

Basic knowledge is enough. The kit includes clear documentation and scripts that do the heavy lifting. With make setup your environment is running in minutes.

Yes. Any system with Docker Desktop installed can run this kit without modifications.

Yes. The engine is switchable with a single command (make db-switch-mysql / make db-switch-postgres), no code changes — included migrations are portable across both engines.

The kit runs PHP 8.5 (FPM) fixed inside the Docker container — that version isn't swappable like the database engine. Your local machine doesn't need PHP installed at all, but your code must be compatible with PHP 8.5 to run inside the kit.

Yes, with exceptions. The kit reserved routes (/viavi/*, /health, /login) must not be overwritten. Everything else is yours.

No. The panel requires authentication. Only users with valid credentials can access /viavi/.

Yes. The license allows use in personal and client projects. One license per project.