Skip to content
PortBay

Trusted HTTPS on .test domains, in one click

https://blog.test instead of localhost:5173. PortBay issues the certificate with mkcert, resolves the hostname with managed local DNS, and routes it through a bundled Caddy edge.

blog.test is liveCaddy, PHP 8.3 and a trusted HTTPS certificate — nothing to configure
Live
0Config files
1Click to live
100%Local & private

HTTPS + .test domains

https://name.test per project: mkcert certificates, managed local DNS and a bundled Caddy edge, with expiry and reissue in view.

The short answer

How do I get trusted HTTPS on localhost on a Mac?

Trusted HTTPS on a local .test domain needs three pieces: a certificate authority your Mac trusts, which mkcert -install creates and adds to the system keychain; DNS that resolves the hostname to your machine without an /etc/hosts line per site, which dnsmasq does with address=/.test/127.0.0.1 plus an /etc/resolver/test entry; and a web server that serves the project on that hostname with the issued certificate. RFC 6761 reserves .test for exactly this, so a local domain can never collide with a real registration. PortBay runs that stack for you: a per-project certificate through mkcert (the local root CA installs once, with your approval) stored under ~/Library/Application Support/PortBay/certs/, the hostname resolved by a managed local resolver, and requests routed through a bundled Caddy edge to the project's port. Cookies, OAuth callbacks and secure-context APIs then behave as they will in production.

Verified against the product, 2026-07-10.
In the app

From folder to https://, one press of play

PortBay
Projects
marketing-site
Client work
Next.js
https://marketing-site.test
Running
acme-shop
Laravel
PHP 8.3
acme-shop.test
Stopped
design-tokens
Vite
design-tokens.test
Stopped

The project boots, the hostname resolves, and the lock is real: a per-project mkcert certificate served by the bundled Caddy edge.

How it works

What the one click actually does

  1. The hostname is derived
  2. mkcert issues the certificate
  3. DNS resolves .test to your Mac
  4. Caddy routes the request
  5. Reissue when something breaks

The hostname is derived

Add a project and it gets a .test hostname from its name. On Pro you can move every project to any local suffix you like; hostnames migrate automatically.

https://blog.test

mkcert issues the certificate

One per project, trusted by the mkcert root CA that is installed once with your approval. Certificates are stored per project and renewed by PortBay.

~/Library/Application Support/PortBay/certs/<project-id>/

DNS resolves .test to your Mac

A managed local resolver answers for the suffix, so the hostname works in every browser and CLI on the machine without touching /etc/hosts per project.

Caddy routes the request

PortBay generates route config from its registry and applies it through Caddy's admin API: hostname in, project port out, TLS terminated with the project's certificate.

Reissue when something breaks

The Certificates page lists common name, issuer and expiry per project, with reissue in the row actions. Agents can do the same over MCP with portbay_cert_info and portbay_reissue_cert.

Spec

HTTPS, tier by tier

CapabilityCommunityPro
Trusted HTTPS on .test domainsIncludedIncluded
ProjectsUp to 6Unlimited
Custom domain suffixPinned to .testAny suffix

Move every project from .test to any local suffix; existing hostnames migrate automatically.

Certificate list with expiry + reissueIncludedIncluded
Agent cert tools over MCPIncludedIncluded

portbay_cert_info reads metadata; portbay_reissue_cert mints a fresh certificate.

Without PortBay

The mkcert + dnsmasq + Caddy afternoon

The manual stack behind local HTTPS is three tools and four config files, repeated in part for every new project.

PortBay runs this exact stack for you: mkcert, managed DNS and Caddy, reconciled per project on every start.

Questions

Asked before downloading

Why .test and not .dev or .local?

.test is reserved for exactly this (RFC 2606): it will never be a real internet domain. .dev is a real, Google-operated TLD on the HSTS preload list, so browsers force it to real HTTPS. .local belongs to mDNS/Bonjour on macOS and collides with device discovery. .test avoids both traps.

Do I have to install and run mkcert myself for PortBay's HTTPS?

No. PortBay issues and renews per-project certificates through mkcert for you. The one manual moment is trusting the local root CA, which is privileged and interactive, so the app asks for your approval once.

My browser suddenly warns about a local site. Now what?

A sudden warning is a mismatch between the certificate Caddy serves and the hostname, or a missing mkcert root. Open Certificates, reissue the project's certificate, and restart Caddy from Services. The guide's diagnostic checklist covers the rest: reconcile hostnames, then restart the project.

Can other devices on my network open a .test site?

No. .test hostnames resolve only on your Mac. To show a local site to a phone, a client or a webhook, open a Cloudflare tunnel from the share menu: it gives the project a public HTTPS URL in one click.

Does HTTPS work for every stack PortBay runs?

Yes. TLS is terminated at the bundled Caddy edge and proxied to the project's port, so PHP, Node, static and mobile-backend projects all get the same trusted certificate treatment without stack-specific setup.

PortBay mascot — a friendly blue tugboat

Give your projects and your agents a real local home.

Download for macOS

Free & open source · macOS 11+ on Apple Silicon · Pro from $10/mo