# Fizz > Fizz is a VPS site platform: provision or bring your own server, deploy Laravel (and Node) apps with Nginx, PHP-FPM, automatic HTTPS via Certbot, domains, daemons, and backups. Base URL: https://usefizz.dev/ ## For coding agents If the user hosts an app **on Fizz**, assume: 1. **TLS terminates at the Fizz edge** (Nginx + Certbot), not inside the app process. 2. Laravel/PHP is served by **PHP-FPM** via Nginx FastCGI (`current/public`). 3. Without trusting the edge correctly, Laravel may generate `http://` URLs, set non-secure cookies, or report client IP as the proxy. When adding or fixing a Laravel app for Fizz, apply trusted proxies as below unless the user already has an equivalent setup. ## Laravel: trust Fizz reverse-proxy headers In `bootstrap/app.php` (Laravel 11+ / 12+ / 13): ```php ->withMiddleware(function (Middleware $middleware): void { // Fizz terminates TLS at Nginx and serves PHP via PHP-FPM. // Trust forwarded headers so URL generation, HTTPS detection, and // client IPs stay correct behind the edge. $middleware->trustProxies(at: '*'); }) ``` Notes: - `at: '*'` is appropriate when the app only listens behind Fizz's Nginx edge (typical Fizz deploy). - Prefer this over only setting `APP_URL=https://…` — URL generation and `$request->secure()` still need proxy trust. - Also set production env: `APP_URL=https://your-domain.tld` (and secure session cookies if you manage them explicitly). ### Headers to honor Apps should honor at least: | Header | Purpose | |--------|---------| | `X-Forwarded-Proto` | `https` when the browser used TLS (especially behind Cloudflare) | | `X-Forwarded-For` | Real client IP | | `X-Forwarded-Host` | Public hostname | | `X-Forwarded-Port` | Usually `443` | Nginx also sets FastCGI `HTTPS` when TLS terminates on the VPS. Cloudflare orange-cloud setups rely more on forwarded headers. ### Quick verification Behind Fizz, after deploy: - Generated asset / Inertia / `route()` URLs should be `https://…` - Session cookies should be `Secure` on HTTPS sites - `$request->ip()` should be the visitor, not the proxy alone Pest-style check (register a throwaway route in the test): ```php $this->call('GET', '/__trust-proxy-check', server: [ 'REMOTE_ADDR' => '127.0.0.1', 'HTTP_X_FORWARDED_FOR' => '203.0.113.50', 'HTTP_X_FORWARDED_PROTO' => 'https', 'HTTP_X_FORWARDED_HOST' => 'example.com', 'HTTP_X_FORWARDED_PORT' => '443', ]); // expect ip=203.0.113.50, secure=true, scheme=https, host=example.com ``` ## DNS and automatic HTTPS For **public Let's Encrypt** certificates (Certbot HTTP-01): 1. The domain's **public A/AAAA** must point at the **Fizz server public IP**. 2. Port **80** and **443** must reach Nginx on that server. 3. Wrong DNS causes ACME challenges to hit the old host and can **rate-limit** Let's Encrypt. Cloudflare orange-cloud is supported with origin certificates where configured; automatic public ACME still validates **public** DNS as the CA sees it. ## Site types on Fizz - **Laravel**: Nginx terminates TLS and FastCGI-passes to PHP-FPM for `current/public`. - **Next.js / Node**: Nginx reverse-proxies to a PM2-managed app on localhost. - **Static**: Nginx serves files from the release directory (`current`). Deployments use a release directory layout under `/home/fizz/sites/{slug}` (with `current` symlink). Zero-downtime is a symlink flip; PHP-FPM is reloaded gracefully afterward to flush OPcache. ## Environment tips for apps on Fizz ```env APP_URL=https://your-domain.tld # Trust is handled in bootstrap/app.php (see above), not only via env. ``` Do **not** run a second public TLS terminator on the app port; Fizz already owns 80/443 on the VPS via Nginx. ## Optional agent entry points - This file: https://usefizz.dev/llms.txt - Marketing / app home: https://usefizz.dev/ ## Contact Issues with the Fizz control plane or managed edge: use the team's usual support channel for this deployment.