| title | Environment Variables Reference |
|---|---|
| description | Complete reference for all Cbox environment variables |
| weight | 1 |
Complete reference for all environment variables supported by Cbox PHP Base Images powered by Cbox Init.
These are the most commonly used variables. Just set what you need!
| Variable | Default | Description |
|---|---|---|
PUID |
(container default) | User ID for application files — fixes permission issues |
PGID |
(container default) | Group ID for application files |
LARAVEL_SCHEDULER |
false |
Enable Laravel scheduler |
LARAVEL_HORIZON |
false |
Enable Laravel Horizon |
LARAVEL_REVERB |
false |
Enable Laravel Reverb WebSockets |
LARAVEL_QUEUE |
false |
Enable queue workers |
PHP_MEMORY_LIMIT |
256M |
PHP memory limit |
PHP_MAX_EXECUTION_TIME |
30 |
Max script execution time |
The most common Docker problem: files created inside the container are owned by www-data (UID 33), but your host user has a different UID (typically 1000). This causes permission denied errors on bind mounts, and files created in the container can't be edited on the host.
PUID/PGID solves this by remapping the container's www-data user to match your host user.
| Variable | Default | Description |
|---|---|---|
PUID |
(container default) | Set the UID that www-data runs as |
PGID |
(container default) | Set the GID that www-data runs as |
APP_USER |
www-data |
Application user name |
APP_GROUP |
www-data |
Application group name |
id -u # Your UID (typically 1000)
id -g # Your GID (typically 1000)services:
app:
image: ghcr.io/cboxdk/php-baseimages/php-fpm-nginx:8.4-bookworm
volumes:
- ./:/var/www/html
environment:
- PUID=1000
- PGID=1000Linux with bind mounts — the most common case. Without PUID/PGID, Laravel's storage/ and bootstrap/cache/ will be owned by UID 33, and your editor/IDE can't write to them:
environment:
- PUID=1000
- PGID=1000NFS volumes — NFS preserves the original UID/GID. Match them to avoid permission issues:
environment:
- PUID=1001
- PGID=1001CI/CD pipelines — GitHub Actions and GitLab CI run as UID 1001 or similar:
environment:
- PUID=1001
- PGID=1001- The container's
www-datauser is remapped to the specified UID/GID - Ownership of
/var/www/htmlis updated to match - Framework directories (
storage/,bootstrap/cache/,var/) are chowned automatically - PHP-FPM runs worker processes as the remapped user
- Files created by PHP have the correct ownership on your host
- Requires root mode — PUID/PGID only works in root images (the default). Rootless images skip PUID/PGID mapping since the container already runs as
www-data. - Docker Desktop (macOS/Windows) — Docker Desktop handles permission translation automatically via its VM layer, so PUID/PGID is usually not needed. It won't break anything if set, though.
- Only set what you need — if you only need to change the UID, just set
PUID. If you only need the GID, just setPGID.
These user-friendly variables are automatically mapped to Cbox Init process controls by the entrypoint script.
| Variable | Maps To | Description |
|---|---|---|
LARAVEL_SCHEDULER |
CBOX_INIT_PROCESS_SCHEDULER_ENABLED |
Enable php artisan schedule:work |
LARAVEL_HORIZON |
CBOX_INIT_PROCESS_HORIZON_ENABLED |
Enable Laravel Horizon |
LARAVEL_REVERB |
CBOX_INIT_PROCESS_REVERB_ENABLED |
Enable Laravel Reverb |
LARAVEL_QUEUE |
CBOX_INIT_PROCESS_QUEUE_DEFAULT_ENABLED |
Enable default queue worker |
LARAVEL_QUEUE_HIGH |
CBOX_INIT_PROCESS_QUEUE_HIGH_ENABLED |
Enable high priority queue |
CBOX_QUEUE_AUTOSCALER |
CBOX_INIT_PROCESS_AUTOSCALER_ENABLED |
Enable queue autoscaler (cboxdk/laravel-queue-autoscale) |
| Variable | Default | Description |
|---|---|---|
CBOX_INIT_PROCESS_QUEUE_DEFAULT_SCALE |
2 |
Number of default queue worker instances |
CBOX_INIT_PROCESS_QUEUE_HIGH_SCALE |
1 |
Number of high priority queue worker instances |
| Variable | Default | Description |
|---|---|---|
LARAVEL_OPTIMIZE_ENABLED |
false |
Run config:cache, route:cache, view:cache on startup |
LARAVEL_MIGRATE_ENABLED |
false |
Run php artisan migrate --force on startup |
LARAVEL_MIGRATE_ALLOW_FAILURE |
false |
Continue container startup if migrations fail |
| Variable | Default | Description |
|---|---|---|
PHP_MEMORY_LIMIT |
256M |
Memory limit |
PHP_MAX_EXECUTION_TIME |
30 |
Max execution time |
PHP_MAX_INPUT_TIME |
60 |
Max input time |
PHP_POST_MAX_SIZE |
100M |
Max POST size |
PHP_UPLOAD_MAX_FILESIZE |
100M |
Max upload size |
PHP_MAX_FILE_UPLOADS |
20 |
Max simultaneous uploads |
PHP_MAX_INPUT_VARS |
1000 |
Max input variables |
PHP_DATE_TIMEZONE |
UTC |
Default timezone |
PHP_DISPLAY_ERRORS |
Off |
Display errors (use On for dev) |
PHP_DISPLAY_STARTUP_ERRORS |
Off |
Display startup errors |
PHP_ERROR_REPORTING |
E_ALL & ~E_DEPRECATED & ~E_STRICT |
Error reporting level |
PHP_LOG_ERRORS |
On |
Log errors |
PHP_ERROR_LOG |
/dev/stderr |
Error log destination |
PHP_SESSION_COOKIE_SECURE |
(not set) | Restrict session cookies to HTTPS (1 recommended for prod) |
PHP_REALPATH_CACHE_TTL |
600 |
Path cache TTL in seconds |
PHP_OPEN_BASEDIR |
/var/www/html:/tmp:/var/tmp |
Restrict filesystem access (FPM only) |
| Variable | Default | Description |
|---|---|---|
PHP_OPCACHE_ENABLE |
1 |
Enable OPcache |
PHP_OPCACHE_MEMORY_CONSUMPTION |
256 |
OPcache memory (MB) |
PHP_OPCACHE_INTERNED_STRINGS_BUFFER |
16 |
Interned strings buffer (MB) |
PHP_OPCACHE_MAX_ACCELERATED_FILES |
20000 |
Max cached files |
PHP_OPCACHE_REVALIDATE_FREQ |
0 |
Revalidation frequency |
PHP_OPCACHE_VALIDATE_TIMESTAMPS |
0 |
Validate timestamps (1 for dev) |
PHP_OPCACHE_JIT |
tracing |
JIT mode: tracing, function, off |
PHP_OPCACHE_JIT_BUFFER_SIZE |
128M |
JIT buffer size |
| Variable | Default | Description |
|---|---|---|
PHP_FPM_PM |
dynamic |
Process manager: dynamic, static, ondemand |
PHP_FPM_PM_MAX_CHILDREN |
50 |
Max concurrent child processes |
PHP_FPM_PM_START_SERVERS |
5 |
Initial child count (dynamic mode) |
PHP_FPM_PM_MIN_SPARE_SERVERS |
5 |
Min idle processes (dynamic mode) |
PHP_FPM_PM_MAX_SPARE_SERVERS |
35 |
Max idle processes (dynamic mode) |
PHP_FPM_PM_MAX_REQUESTS |
500 |
Requests per child before recycling (0 = unlimited) |
PHP_FPM_REQUEST_TERMINATE_TIMEOUT |
60s |
Max request execution time before kill |
| Variable | Default | Description |
|---|---|---|
NGINX_HTTP_PORT |
80 |
HTTP port |
NGINX_HTTPS_PORT |
443 |
HTTPS port |
NGINX_WEBROOT |
/var/www/html/public |
Document root |
NGINX_INDEX |
index.php index.html |
Index files |
NGINX_SERVER_TOKENS |
off |
Hide Nginx version |
| Variable | Default | Description |
|---|---|---|
NGINX_CLIENT_MAX_BODY_SIZE |
100M |
Max request body |
NGINX_CLIENT_BODY_TIMEOUT |
60s |
Body read timeout |
NGINX_CLIENT_HEADER_TIMEOUT |
60s |
Header read timeout |
All security headers are fully configurable via environment variables. Set to empty string to disable.
| Variable | Default | Description |
|---|---|---|
NGINX_HEADER_X_FRAME_OPTIONS |
SAMEORIGIN |
Clickjacking protection |
NGINX_HEADER_X_CONTENT_TYPE_OPTIONS |
nosniff |
MIME sniffing protection |
NGINX_HEADER_X_XSS_PROTECTION |
1; mode=block |
XSS filter |
NGINX_HEADER_CSP |
(see below) | Content-Security-Policy |
NGINX_HEADER_REFERRER_POLICY |
strict-origin-when-cross-origin |
Referrer information |
NGINX_HEADER_COOP |
(disabled) | Cross-Origin-Opener-Policy (opt-in) |
NGINX_HEADER_COEP |
(disabled) | Cross-Origin-Embedder-Policy (opt-in) |
NGINX_HEADER_CORP |
(disabled) | Cross-Origin-Resource-Policy (opt-in) |
NGINX_HEADER_PERMISSIONS_POLICY |
(see below) | Browser feature permissions |
Default CSP:
default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'self'
Default Permissions-Policy:
accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()
Cross-Origin Isolation Headers (COOP/COEP/CORP):
These headers are disabled by default because they break most applications that use:
- External APIs (payment gateways, analytics, social login)
- CDN resources (fonts, scripts, images)
- Third-party embeds (YouTube, maps, widgets)
Enable for maximum security (advanced use cases only):
environment:
- NGINX_HEADER_COOP=same-origin
- NGINX_HEADER_COEP=require-corp
- NGINX_HEADER_CORP=same-originDisable a header (set to empty):
environment:
- NGINX_HEADER_CSP= # Disable Content-Security-PolicySee Security Hardening for customization examples.
| Variable | Default | Description |
|---|---|---|
NGINX_GZIP |
on |
Enable gzip (on/off) |
NGINX_GZIP_VARY |
on |
Add Vary: Accept-Encoding |
NGINX_GZIP_PROXIED |
any |
Compress proxied requests |
NGINX_GZIP_COMP_LEVEL |
6 |
Compression level (1-9) |
NGINX_GZIP_MIN_LENGTH |
1000 |
Min size to compress (bytes) |
NGINX_GZIP_TYPES |
(see below) | MIME types to compress |
Default gzip types:
text/plain text/css text/xml text/javascript application/json application/javascript application/xml application/xml+rss application/x-javascript image/svg+xml
Disable gzip:
environment:
- NGINX_GZIP=off| Variable | Default | Description |
|---|---|---|
NGINX_OPEN_FILE_CACHE |
max=10000 inactive=20s |
Cache config (off to disable) |
NGINX_OPEN_FILE_CACHE_VALID |
30s |
Cache validation interval |
NGINX_OPEN_FILE_CACHE_MIN_USES |
2 |
Min uses before caching |
NGINX_OPEN_FILE_CACHE_ERRORS |
on |
Cache file errors |
Disable file cache:
environment:
- NGINX_OPEN_FILE_CACHE=off| Variable | Default | Description |
|---|---|---|
NGINX_FASTCGI_PASS |
127.0.0.1:9000 |
PHP-FPM address |
NGINX_FASTCGI_BUFFERS |
8 8k |
FastCGI buffers |
NGINX_FASTCGI_BUFFER_SIZE |
8k |
Buffer size |
NGINX_FASTCGI_BUSY_BUFFERS_SIZE |
16k |
Busy buffers size |
NGINX_FASTCGI_CONNECT_TIMEOUT |
60s |
Connect timeout |
NGINX_FASTCGI_SEND_TIMEOUT |
60s |
Send timeout |
NGINX_FASTCGI_READ_TIMEOUT |
60s |
Read timeout |
| Variable | Default | Description |
|---|---|---|
NGINX_ACCESS_LOG |
/var/log/nginx/access.log |
Access log path (off or false to disable) |
NGINX_ERROR_LOG |
/var/log/nginx/error.log |
Error log path |
NGINX_ERROR_LOG_LEVEL |
warn |
Error log level |
Disable access logging (reduces disk I/O in high-traffic scenarios):
environment:
- NGINX_ACCESS_LOG=false
# or
- NGINX_ACCESS_LOG=off| Variable | Default | Description |
|---|---|---|
NGINX_STATIC_EXPIRES |
1y |
Static file cache duration |
NGINX_STATIC_CACHE_CONTROL |
public, immutable |
Cache-Control header |
NGINX_STATIC_ACCESS_LOG |
off |
Static file access logging |
NGINX_TRY_FILES |
/index.php?$query_string |
try_files fallback |
Configure Cbox to run behind Cloudflare, HAProxy, Traefik, Nginx, Fastly, Tailscale, or other reverse proxies.
| Variable | Default | Description |
|---|---|---|
NGINX_TRUSTED_PROXIES |
(empty) | Space-separated list of trusted proxy IPs/CIDRs |
NGINX_REAL_IP_HEADER |
X-Forwarded-For |
Header containing real client IP |
NGINX_REAL_IP_RECURSIVE |
on |
Recursive IP extraction from proxy chain |
# Docker/Kubernetes internal networks
NGINX_TRUSTED_PROXIES: "10.0.0.0/8 172.16.0.0/12 192.168.0.0/16"
# Cloudflare
NGINX_TRUSTED_PROXIES: "173.245.48.0/20 103.21.244.0/22 ..."
NGINX_REAL_IP_HEADER: "CF-Connecting-IP"
# Tailscale
NGINX_TRUSTED_PROXIES: "100.64.0.0/10"
# Traefik/HAProxy (Docker network)
NGINX_TRUSTED_PROXIES: "172.16.0.0/12"When proxies are configured, these headers are available in PHP:
| PHP Variable | Description |
|---|---|
$_SERVER['REMOTE_ADDR'] |
Real client IP (after proxy extraction) |
$_SERVER['HTTP_X_FORWARDED_FOR'] |
Full proxy chain |
$_SERVER['HTTP_X_FORWARDED_PROTO'] |
Original protocol (http/https) |
$_SERVER['HTTP_X_FORWARDED_HOST'] |
Original hostname |
$_SERVER['HTTP_X_REAL_IP'] |
Real client IP |
See Reverse Proxy & mTLS Guide for detailed setup.
| Variable | Default | Description |
|---|---|---|
SSL_MODE |
off |
SSL mode: off, on, full |
SSL_CERTIFICATE_FILE |
/etc/ssl/certs/cbox-selfsigned.crt |
Certificate path |
SSL_PRIVATE_KEY_FILE |
/etc/ssl/private/cbox-selfsigned.key |
Private key path |
SSL_PROTOCOLS |
TLSv1.2 TLSv1.3 |
SSL protocols |
SSL_CIPHERS |
HIGH:!aNULL:!MD5 |
SSL ciphers |
SSL_HSTS_HEADER |
max-age=31536000; includeSubDomains |
HSTS header value |
off- HTTP onlyon- HTTPS enabled (HTTP still available)full- HTTPS with HTTP to HTTPS redirect
Enable client certificate authentication for zero-trust networks, service mesh, or API authentication.
| Variable | Default | Description |
|---|---|---|
MTLS_ENABLED |
false |
Enable mTLS client verification |
MTLS_CLIENT_CA_FILE |
/etc/ssl/certs/client-ca.crt |
CA certificate for client verification |
MTLS_VERIFY_CLIENT |
optional |
optional, on (required), or optional_no_ca |
MTLS_VERIFY_DEPTH |
2 |
Maximum certificate chain depth |
When mTLS is enabled, client certificate details are available:
| PHP Variable | Description |
|---|---|
$_SERVER['SSL_CLIENT_VERIFY'] |
SUCCESS, FAILED, or NONE |
$_SERVER['SSL_CLIENT_S_DN'] |
Client subject DN (e.g., /CN=service-name) |
$_SERVER['SSL_CLIENT_I_DN'] |
Client issuer DN |
$_SERVER['SSL_CLIENT_SERIAL'] |
Certificate serial number |
$_SERVER['SSL_CLIENT_FINGERPRINT'] |
Certificate fingerprint |
services:
app:
image: ghcr.io/cboxdk/php-baseimages/php-fpm-nginx:8.4-bookworm
environment:
SSL_MODE: "on"
MTLS_ENABLED: "true"
MTLS_VERIFY_CLIENT: "optional"
volumes:
- ./certs/client-ca.crt:/etc/ssl/certs/client-ca.crt:ro
- ./certs/server.crt:/etc/ssl/certs/cbox-selfsigned.crt:ro
- ./certs/server.key:/etc/ssl/private/cbox-selfsigned.key:roSee Reverse Proxy & mTLS Guide for complete setup.
Automatically decrypt .env.encrypted files at container startup.
| Variable | Default | Description |
|---|---|---|
LARAVEL_ENV_ENCRYPTION_KEY |
(empty) | Decryption key (e.g., base64:xxx) |
LARAVEL_ENV_ENCRYPTION_KEY_FILE |
(empty) | Path to file containing decryption key |
LARAVEL_ENV_FORCE_DECRYPT |
false |
Overwrite existing .env file |
Using environment variable:
environment:
- LARAVEL_ENV_ENCRYPTION_KEY=base64:your-encryption-key-hereUsing Docker secrets:
environment:
- LARAVEL_ENV_ENCRYPTION_KEY_FILE=/run/secrets/laravel_env_key
secrets:
- laravel_env_keyThe Management API provides runtime control over container processes. It is disabled by default for security.
| Variable | Default | Description |
|---|---|---|
CBOX_INIT_API_ENABLED |
false |
Enable the Management API |
CBOX_INIT_API_PORT |
9180 |
Port the API listens on |
CBOX_INIT_API_AUTH |
(empty) | Bearer token for API authentication |
services:
app:
image: ghcr.io/cboxdk/php-baseimages/php-fpm-nginx:8.4-bookworm
ports:
- "9180:9180"
environment:
CBOX_INIT_API_ENABLED: "true"
CBOX_INIT_API_AUTH: "my-secret"See Cbox Init Integration for endpoints, CLI commands, and examples.
| Variable | Default | Description |
|---|---|---|
CBOX_INIT_METRICS_ENABLED |
true |
Enable Prometheus metrics endpoint |
CBOX_INIT_METRICS_PORT |
9090 |
Metrics endpoint port |
CBOX_INIT_LOG_LEVEL |
info |
Log level: debug, info, warn, error |
CBOX_INIT_LOG_FORMAT |
json |
Log format: json, text |
CBOX_INIT_SHUTDOWN_TIMEOUT |
30 |
Seconds to wait for graceful process shutdown |
CBOX_INIT_CONFIG |
/etc/cbox-init/cbox-init.yaml |
Path to cbox-init config file |
| Variable | Default | Description |
|---|---|---|
XDEBUG_MODE |
off |
Xdebug mode: debug, develop, coverage, profile, or comma-separated |
XDEBUG_CONFIG |
(empty) | Xdebug config string (e.g., client_host=host.docker.internal client_port=9003) |
PHP_IDE_CONFIG |
(empty) | IDE server mapping (e.g., serverName=docker) |
# Example: Enable step debugging
environment:
XDEBUG_MODE: "debug"
XDEBUG_CONFIG: "client_host=host.docker.internal client_port=9003"
PHP_IDE_CONFIG: "serverName=docker"| Variable | Default | Description |
|---|---|---|
WORKDIR |
/var/www/html |
Working directory |
CBOX_INIT_CONFIG |
/etc/cbox-init/cbox-init.yaml |
Cbox Init config path |
REVERB_PORT |
8080 |
Reverb port for healthcheck (override if using non-default port) |
environment:
- PUID=1000
- PGID=1000
- PHP_DISPLAY_ERRORS=On
- PHP_OPCACHE_VALIDATE_TIMESTAMPS=1environment:
- PUID=1000
- PGID=1000
- LARAVEL_SCHEDULER=true
- PHP_MEMORY_LIMIT=512Menvironment:
- PHP_MEMORY_LIMIT=1G
- PHP_MAX_EXECUTION_TIME=120
- NGINX_FASTCGI_READ_TIMEOUT=120s
- LARAVEL_QUEUE=trueenvironment:
- LARAVEL_HORIZON=true
- LARAVEL_SCHEDULER=trueenvironment:
- LARAVEL_REVERB=true
ports:
- "8000:80"
- "8080:8080"