Mengelola konfigurasi FrankenPHP lintas environment: environment variables bawaan (SERVER_NAME, SERVER_ROOT, FRANKENPHP_CONFIG), substitusi env di Caddyfile, variabel khusus worker, dan format konfigurasi Caddyfile versus JSON untuk dev, staging, dan produksi.

Setelah episode 10 mengamankan HTTPS, episode ini membahas topik yang menentukan kualitas operasional aplikasi nyata: manajemen konfigurasi. Aplikasi produksi hampir selalu berjalan di tiga environment (dev, staging, prod) dengan domain, root, dan perilaku yang berbeda — dan FrankenPHP menyediakan beberapa lapis mekanisme untuk itu, dari env vars bawaan sampai format konfigurasi alternatif.
Mengapa penting? Konfigurasi yang dikelola buruk adalah sumber utama drift environment: "berjalan di laptop saya tapi gagal di produksi". Memahami env substitution dan variabel bawaan FrankenPHP membuat satu konfigurasi bisa beradaptasi tanpa menulis file terpisah per environment.
FrankenPHP membaca beberapa env vars khusus untuk menginjeksi konfigurasi Caddy tanpa menyentuh Caddyfile:
| Variabel | Fungsi |
|---|---|
SERVER_NAME | Hostname yang dilayani + address listen; juga menentukan subjek sertifikat (episode 10) |
SERVER_ROOT | Direktori root situs, default public/ |
FRANKENPHP_CONFIG | Konfigurasi tambahan di bawah directive frankenphp (misal worker) |
CADDY_GLOBAL_OPTIONS | Global options Caddy (misal debug) |
Contoh paling umum — menjalankan image Docker yang sama untuk dua domain:
# staging
docker run -e SERVER_NAME="staging.kaliansite.com" ...
# produksi
docker run -e SERVER_NAME="kaliansite.com" ...Dan worker via env var:
docker run \
-e FRANKENPHP_CONFIG="worker ./public/index.php 4" \
-e SERVER_NAME="kaliansite.com" \
dunglas/frankenphpCaddyfile mendukung placeholder {$ENV_VAR}. Ini memungkinkan satu Caddyfile beradaptasi dengan environment:
{
frankenphp {
php_ini memory_limit {$PHP_MEMORY_LIMIT}
}
}
{$SERVER_NAME} {
root * {$SERVER_ROOT}
encode zstd br gzip
php_server {
try_files {path} index.php
}
}Kemudian bedakan per environment cukup lewat env vars:
# dev
SERVER_NAME="localhost" SERVER_ROOT="public" PHP_MEMORY_LIMIT=256M frankenphp run
# prod
SERVER_NAME="kaliansite.com" SERVER_ROOT="public" PHP_MEMORY_LIMIT=512M frankenphp runWarning
Placeholder {$VAR} di dalam root dan env mencegah Caddy meng-cache nilai tersebut — ada biaya performa di hot path. Gunakan substitusi env di tempat yang berubah jarang (hostname, memory limit), dan tetap pakai nilai literal di root jika performa jadi prioritas (lihat episode 17).
Semua env var yang kalian set akan tersedia di $_SERVER PHP — sama seperti PHP-FPM. Ini cara memberi tahu aplikasi environment-nya:
{
frankenphp {
worker {
file /app/public/index.php
env APP_ENV production
env APP_DEBUG 0
env DATABASE_URL postgres://user:pass@db:5432/app
}
}
}Di dalam PHP:
<?php
$env = $_SERVER['APP_ENV'] ?? 'production';
$debug = filter_var($_SERVER['APP_DEBUG'] ?? '0', FILTER_VALIDATE_BOOL);Catatan: meskipun variables_order diatur bebas, posisi E dianggap selalu menyertakan env — jadi $_ENV dan $_SERVER sama-sama berisi env var.
Danger
Di mode worker, $_ENV tidak di-reset antar request — jangan pernah menulis data request ke $_ENV di dalam handler (ingat episode 5). Set env vars di konfigurasi worker, bukan di kode aplikasi.
Caddyfile adalah format manusia. Di belakang layar, Caddy mengubahnya menjadi konfigurasi JSON (disebut Caddy JSON). Kedua format setara — Caddyfile hanyalah sugar di atas JSON.
frankenphp adapt --config Caddyfile --output Caddyfile.jsonJSON berguna saat konfigurasi dihasilkan/dikelola secara programatik (GitOps, controller Kubernetes) atau saat perlu menggabungkan bagian yang tidak bisa dinyatakan di Caddyfile.
frankenphp run --config Caddyfile.json| Kebutuhan | Pilihan |
|---|---|
| Konfigurasi ditulis manusia, dibaca cepat | Caddyfile |
| Konfigurasi dari template/CI/GitOps | JSON (via adapt) |
| Merge dari banyak sumber | JSON + API admin |
| Ingress controller K8s | JSON (episode 19) |
Aturan praktis: mulai dari Caddyfile; gunakan JSON hanya ketika otomasi menuntutnya.
Pola yang direkomendasikan untuk satu proyek:
frankenphp-lab/
Caddyfile # template utama, memakai {$VAR}
.env.example # contoh nilai env
env/
Caddyfile.dev
Caddyfile.staging
Caddyfile.prodJika kalian lebih suka file per environment, gabungkan dengan --config:
frankenphp run --config env/Caddyfile.prodKombinasi paling fleksibel: satu Caddyfile template + env vars (via {$VAR}) di development/CI, atau file terpisah jika perbedaan antar environment sangat besar.
{$VAR} di hot path: biaya performa karena cache mati (lihat callout di atas).adapt ulang — JSON yang basi menyebabkan perilaku tak terduga.Pada episode 11 ini, kalian telah mengelola konfigurasi FrankenPHP lintas environment.
Inti yang harus dibawa pulang:
SERVER_NAME, SERVER_ROOT, FRANKENPHP_CONFIG, CADDY_GLOBAL_OPTIONS.{$VAR} membuat satu Caddyfile adaptif ke banyak environment.$_SERVER PHP; set di worker config, jangan tulis $_ENV di runtime.frankenphp adapt untuk beralih.Di episode 12 selanjutnya kita masuk dunia observability: logging, observability, dan metrics — access log, structured JSON logging dengan frankenphp_log(), dan metrik Prometheus untuk memantau thread, worker, dan antrean request. Sampai jumpa di episode 12!