The serversideup/php Docker images shipped v4.6.0-beta1 with a CADDY_ACME_PROFILE variable. Set to shortlived, it selects Let's Encrypt's short-lived certificate profile, the only profile under which Let's Encrypt issues IP-address certificates. A FrankenPHP container reachable only by IP can therefore serve real HTTPS without any DNS record. Jay Rogers of Server Side Up announced the feature alongside the beta.
The typical use cases: staging boxes, internal APIs behind a VPN, demo servers, self-hosted dashboards. Until now those meant self-signed certificates with browser warnings or a reverse proxy holding the real cert. Let's Encrypt made 6-day certificates and IP certificates generally available in January. Caddy implements profile selection and IP identifiers, and FrankenPHP embeds Caddy, currently v2.11.4.
CADDY_ACME_PROFILE defaults to off and accepts shortlived, tlsserver, or classic. With shortlived, Caddy requests certificates valid for 160 hours and renews them every two days. Short-lived certificates fall under the CA/Browser Forum definition that requires no revocation information, though the profile still points to a CRL. Setting any profile drops the ZeroSSL fallback the images otherwise keep. The two-day renewal cycle also means less margin: if a firewall change blocks egress to the ACME API, the certificate expires in about four and a half days instead of weeks.
The feature exists only in beta tags, so pin serversideup/php:8.4-frankenphp-v4.6.0-beta1 rather than the stable tag. The Compose setup uses SSL_MODE: "full", CADDY_AUTO_HTTPS: "on", CADDY_ACME_PROFILE: "shortlived", CADDY_HTTPS_SERVER_ADDRESS with the IP, and CADDY_GLOBAL_OPTIONS: "default_sni example.com". The container runs unprivileged on 8080 and 8443, so ports 80 and 443 must be mapped and reachable for the ACME challenge. The default_sni fallback is needed because clients connecting to an IP send no SNI, leaving Caddy nothing to match a certificate against.
IPv6 users should test before relying on it. Caddy fixed IPv6 handling for IP certificates in issue #7399, closed in April, so v2.11.4 includes the fix, but IPv4 has worked longer. Mount /config and /data as volumes: certificates and ACME account state live there, and losing them on restart triggers new requests. Let's Encrypt allows five certificates per identifier set per seven days, so a few redeploys can exhaust the week.
The beta also aligns TRUSTED_PROXY behavior across FrankenPHP, NGINX, and Apache so request()->ip() returns the visitor rather than the proxy. It accepts cloudflare (default), sucuri, local, or off, and trusts Docker's internal ranges alongside the CDN. FrankenPHP gains a caddyfile-global.d directory, Laravel Nightwatch gets a healthcheck-nightwatch script running php artisan nightwatch:status, and AUTORUN_LARAVEL_SKIP_IF_NOT_FOUND lets containers exit cleanly when Laravel is not installed yet. As a prerelease, it should stay off anything you cannot afford to break.
Comments
No comments yet — be the first.
Open the discussion
No account or password needed — just enter your e-mail and we’ll send you a one-time sign-in link. First time here? You’re set up automatically.
Your rating will be applied automatically after you sign in.
Check your inbox
We’ve sent a sign-in link to …. Open it on this device — this tab will sign you in automatically.
Nothing arrived? Check your spam folder — and mark the mail as "Not spam" so it lands in your inbox next time.