Mengatur environment development dan produksi lewat .env, menonaktifkan display errors di produksi, dan praktik deploy CodeIgniter ke shared hosting maupun VPS dengan konfigurasi yang benar.

Sejauh ini kalian menjalankan aplikasi di laptop dengan php spark serve — environment development dengan error detail dan Debug Toolbar. Sekarang saatnya aplikasi meninggalkan laptop: ke server produksi, di mana aturannya berbeda total.
Di episode 16 ini kita membahas environment & deployment config — bagaimana satu codebase bisa berjalan konsisten di banyak environment, apa yang wajib diubah di produksi, dan langkah konkret deploy ke shared hosting dan VPS. Ini episode pertama dari tema deployment yang akan kita lanjutkan dengan Docker dan CI/CD di episode 23.
Nilai .env menimpa config class (kita pelajari di episode 3). Ini kekuatan utamanya: kode tidak berubah antar environment, hanya .env yang berbeda.
#--------------------------------------------------------------------
# ENVIRONMENT
#--------------------------------------------------------------------
CI_ENVIRONMENT = production
#--------------------------------------------------------------------
# APP
#--------------------------------------------------------------------
app.baseURL = 'https://devvnull.vercel.app/'
app.forceGlobalSecureRequests = true
app.indexPage = ''
#--------------------------------------------------------------------
# LOGGING
#--------------------------------------------------------------------
log.threshold = 4
#--------------------------------------------------------------------
# DATABASE
#--------------------------------------------------------------------
database.default.hostname = localhost
database.default.database = ci_blog_prod
database.default.username = ci_user
database.default.password = SANGAT_RAHASIA
database.default.DBDriver = MySQLi| Setting | Development | Production |
|---|---|---|
CI_ENVIRONMENT | development | production |
| Error display | Detail + stack trace | Sembunyikan |
| Debug Toolbar | Aktif | Nonaktif |
| Log level | 5 (warning ke atas) | 4 (error ke atas) |
app.forceGlobalSecureRequests | false | true |
| Cache | TTL pendek | TTL panjang / Redis |
Warning
Di produksi, display_errors harus off dan semua error dialihkan ke log. Menampilkan error detail di produksi bukan hanya buruk secara UX — ia membocorkan struktur internal (path, query, versi) yang bisa dieksploitasi penyerang. Detail hardening dibahas di episode 18 dan 20.
Ada tiga cara mengetahui environment di kode:
// 1. Konstanta ENVIRONMENT (dari CI_ENVIRONMENT)
echo ENVIRONMENT; // "development" | "testing" | "production"
// 2. Helper env()
$baseURL = env('app.baseURL', 'http://localhost:8080/');
// 3. Metode is_production()
if (is_production()) {
// aktifkan cache penuh
}env('key', $default) membaca dari .env; jika tidak ada, memakai default. is_production() adalah helper bawaan yang mengecek ENVIRONMENT === 'production'. Gunakan ini untuk logika kondisional seperti: cache lebih lama di produksi, atau fitur debug hanya di development.
Sebelum upload, jalankan persiapan di project:
composer install --no-dev --optimize-autoloader
php spark migrate --all
php spark cache:clearcomposer install --no-dev — tidak menginstall package development (misal PHPUnit) sehingga bundle lebih kecil dan aman.php spark migrate — jalankan migration di database produksi.php spark cache:clear — bersihkan cache stale dari environment lain.Periksa juga dua hal kritis:
.env tidak ter-commit ke git — buat .env baru di server dengan nilai produksi.writable/ writable oleh web server — logs, cache, session, upload ditulis di sini.Shared hosting (cPanel dsb.) biasanya tidak memberi akses root atau terminal. Strateginya:
public_html/ # document root
├── index.php # front controller (dari public/)
├── .htaccess
└── static/ # asset CSS/JS (dari public/)Karena document root adalah public_html/, dan isi public/ harus menjadi document root, ada dua pendekatan:
public/ ke public_html/, lalu semua folder lain (app/, writable/, vendor/) di atasnya (misal ../ci4/).public/index.php agar mengarah ke ../ci4/ (di luar public_html), lalu isi public_html/ dengan isi public/.// Sesuaikan jika app/ berada di luar public_html
$pathsPath = realpath(FCPATH . '../ci4/app/Config/Paths.php')
?: realpath(FCPATH . '../app/Config/Paths.php')
?: FCPATH . '../app/Config/Paths.php';Setelah upload, pastikan:
.env dibuat di lokasi aplikasi (bukan di public_html).writable/ di-set permission 755/775 dan writable oleh user web.app.baseURL mengarah ke domain dengan https://.Di VPS kalian punya kontrol penuh: install PHP-FPM, Nginx/Apache, dan arahkan document root ke public/.
rsync -avz --exclude '.env' --exclude 'writable/*' --exclude 'vendor' ./ user@server:/var/www/ci4/
ssh user@server 'cd /var/www/ci4 && composer install --no-dev --optimize-autoloader && php spark migrate'rsync menyalin kode (tanpa .env, writable, vendor), lalu di server kita jalankan Composer, migration, dan atur .env produksi. Contoh ini masih manual — di episode 23 kita otomasi penuh dengan Docker dan GitHub Actions.
sudo chown -R www-data:www-data /var/www/ci4/writableUser PHP-FPM (www-data di Debian/Ubuntu) harus bisa menulis ke writable/. Permission yang salah adalah penyebab paling umum aplikasi "blank page" setelah deploy.
Tip
Dokumen root Nginx/Apache harus menunjuk ke folder public/, bukan root project. Ini menjaga app/, vendor/, dan .env tidak bisa diakses langsung dari browser — aturan yang sama dengan episode 2, kini diterapkan di server nyata.
curl -sI https://devvnull.vercel.app/
# HTTP/2 200
curl -s https://devvnull.vercel.app/.env | head -1
# kosong / 404 - .env TIDAK boleh tereksposUji kedua ini penting: halaman utama harus 200, dan akses langsung ke .env harus gagal. Jika .env terbaca dari browser, segera perbaiki document root atau blokir akses file dot di server (kita lakukan di episode 20).
.env berbeda per environment; kode tetap sama — config yang benar menang.CI_ENVIRONMENT = production, display errors off, log level 4.composer install --no-dev, php spark migrate, php spark cache:clear sebelum go-live.public/ jadi document root; app di luarnya.public/, writable/ writable oleh web server.Inti yang harus dibawa pulang:
.env — jangan pernah commit .env produksi.writable/ writable dan document root menunjuk public/..env tidak terekspos.Di episode 17 selanjutnya kita akan membahas testing dengan PHPUnit — setup PHPUnit, unit test dan feature test, test database, serta praktik mengetes controller dan model. Aplikasi yang diuji adalah aplikasi yang bisa dikembangkan dengan percaya diri!