Skip to content

Latest commit

 

History

History
116 lines (80 loc) · 3.49 KB

File metadata and controls

116 lines (80 loc) · 3.49 KB

HTTPS (Local TLS)

Frank serves your Laravel app over HTTPS by default using locally-trusted certificates generated by mkcert.

How It Works

  1. frank generate (also called by frank new and frank setup) runs mkcert localhost 127.0.0.1 ::1
  2. Certificates are written to .frank/certs/ (gitignored automatically)
  3. The web server (Caddy or nginx) terminates TLS using these certificates
  4. Port 80 redirects to HTTPS (unless a custom port is configured)

Both runtimes support HTTPS:

  • FrankenPHP — Caddy handles TLS natively on port 443
  • FPM — nginx terminates TLS on port 443, proxies to PHP-FPM

Prerequisites

Install mkcert and trust its root CA:

# macOS
brew install mkcert
mkcert -install

# Linux (Fedora/Ubuntu)
sudo dnf install mkcert    # or: sudo apt install mkcert
mkcert -install

# Windows
choco install mkcert
mkcert -install

mkcert -install adds the CA to your system/browser trust store. Without this step, browsers will show a security warning.

Configuration

HTTPS is enabled by default. To disable it:

# frank.yaml
server:
  https: false

To use a custom port:

server:
  port: 4433

With a custom port, the HTTP→HTTPS redirect is suppressed (only the single HTTPS port is mapped).

Vite Dev Server

When running pnpm dev (or npm run dev) with HTTPS enabled, Vite must serve its assets over TLS too — otherwise the browser blocks them as mixed content.

Frank generates .frank/vite-server.js with the correct TLS configuration. Import it in your vite.config.js or vite.config.ts:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import frankServer from './.frank/vite-server.js';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
    ],
    server: frankServer,
});

Why this is needed: Vite must serve over TLS to avoid mixed content errors when your app runs on HTTPS. The generated .frank/vite-server.js configures Vite to use the same mkcert certificates as the web server, bind to 0.0.0.0 (required for Docker port mapping), and set the correct origin so Laravel's @vite Blade directive generates https:// URLs.

When HTTPS is disabled, .frank/vite-server.js exports a minimal config (host: '0.0.0.0' only), so the import works regardless of HTTPS mode.

Note: This is only relevant during development with pnpm dev. Production builds (pre-compiled assets) work without any Vite configuration.

Disabling HTTPS

When creating a new project, pass --http:

frank new myapp --http

For existing projects, set server.https: false in frank.yaml and regenerate:

frank generate
frank up -- --build

The app will be served on http://localhost (port 80).

Troubleshooting

Browser shows "certificate not trusted" Run mkcert -install to add the CA to your trust store, then restart your browser.

mkcert not found Install mkcert (see Prerequisites above). Frank will skip cert generation and warn you. The app still runs but without HTTPS.

Vite assets blocked (mixed content) Add the server block to your Vite config as shown above. Restart pnpm dev after editing.

"SSL_ERROR_INTERNAL_ERROR_ALERT" after upgrading to HTTPS The Docker image has a stale Caddyfile/nginx config baked in. Rebuild:

frank up -- --build