SpipCP
Sites

Domains & SSL

Give a site a real hostname with automatic HTTPS β€” point one DNS record at it, and SpipCP handles the certificate, renewal, and a check that it actually serves.

Attaching a domain gives a site a real hostname with automatic HTTPS. You give the site a hostname and point one DNS record at the node. SpipCP routes the traffic, issues the TLS certificate, and proves https://yourdomain actually serves the site before marking it green. A domain that doesn't pass that check is never shown as working β€” it's failed with a fix to apply.

You attach domains from the site

Domains belong to a site, so you manage them under the site workspace's Networking tab β€” there's no separate top-level Domains page. The Networking tab has three sub-tabs: Domains (attach and manage hostnames), SSL (the certificate dashboard), and Routes (the underlying edge routes).

The Domains tab
πŸ“·A site's Domains tab β€” attach a hostname and watch its certificate issue.img/sites-domains.avif
A site's Domains tab β€” attach a hostname and watch its certificate issue.

Domains your app's customers bring

This page is for domains you attach. If your app serves its own customers on their domains (status.client.com), that's a different feature β€” see Custom customer domains, where the certificate is issued on demand and nobody adds each hostname in the panel.

The one thing you do in DNS

SpipCP asks for exactly one DNS record, and never anything else:

An A record: yourdomain β†’ your node's IP (shown to you when you attach).

That's the whole DNS setup. Once that record resolves to the node, the attach continues on its own β€” verify DNS, issue the certificate, test HTTPS, go green. You don't create challenge records, upload anything, or click "activate."

Cloudflare users: DNS only, not Proxied

If your DNS is on Cloudflare, create that A record as DNS only (grey cloud), not Proxied (orange cloud) β€” unless you attach with the Cloudflare driver (below). This only applies to Cloudflare: the orange-cloud proxy is a Cloudflare feature, so DNS on Bunny, Hetzner, deSEC, Gcore, or your own nameservers has nothing to flip.

The orange cloud hides your server's real IP behind Cloudflare. With the manual driver SpipCP checks that the hostname resolves to your node's IP, so a proxied record makes the check fail with dns: failed even though the record exists β€” SpipCP sees Cloudflare's IPs, not your node. SpipCP catches this and the remedy says so: "the record is proxied β€” set it to DNS only." Flip that one record to grey, then Retry attach.

What the wizard tells you before you attach

As soon as you type a valid hostname, the wizard resolves its authority tier and shows a banner β€” before you commit β€” so you know what will happen:

  • Hosted β€” "zone example.com is on your nameservers; the DNS record will be created automatically."
  • Connected β€” "zone found in a provider account you hold (e.g. Bunny); the record will be created automatically." If your cascade's default account doesn't hold this zone, the banner warns of a mismatch and suggests a per-domain override so the attach doesn't fail at record-write time.
  • External β€” "no connected account holds this zone (detected nameserver dns1.registrar.com); you'll get the exact records to create by hand." This sets the expectation up front instead of surprising you at the DNS-verify gate. When the detected nameserver is one SpipCP recognises (e.g. Cloudflare), the banner also offers the fix as a cross-link β€” "Want automatic records and wildcards? Connect Cloudflare β†’" β€” which deep-links into the managed-provider journey with that provider preselected. On an unrecognised nameserver it links the bring-your-own-DNS journey instead.
The attach wizard's tier pre-flight banner
πŸ“·The attach wizard resolves the hostname's authority tier before you commit β€” here, records will be created automatically. On an External tier the banner offers a 'Connect <provider> β†’' cross-link into the guided journey.img/sites-domain-attach-preflight.avif
The attach wizard resolves the hostname's authority tier before you commit β€” here, records will be created automatically. On an External tier the banner offers a 'Connect <provider> β†’' cross-link into the guided journey.

The pre-flight is advisory: the real record write at attach time is always the source of truth. It just turns a late failure into an up-front expectation.

The guided journeys open this same wizard, prefilled

When you reach the attach step from a guided setup journey, the panel picks the site, then opens this wizard with the hostname and the right DNS driver preselected β€” the manage-records-myself and bring-your-own-DNS journeys preselect the manual driver, the managed-token journey preselects the provider. There is no separate attach form; the journey just drives the one you see here.

Attaching a domain

Enter the hostname. The FQDN the site answers on (e.g. app.example.com). HTTPS is automatic from here β€” a free Let's Encrypt certificate, nothing to buy or upload. The wizard shows the detected authority tier (above) as you type.

Pick a DNS driver.

  • Manual β€” SpipCP shows you the A record to create; you add it at your DNS provider. (Cloudflare: set it DNS only.)
  • A provider driver β€” Cloudflare, Bunny, Hetzner, deSEC, or Gcore β€” SpipCP creates the record for you through that provider's API, using a DNS account you set up once. With the Cloudflare driver, the proxy (orange cloud) is safe to leave on, because SpipCP reads the record from Cloudflare's API instead of a public lookup. The other providers have no proxy.

Certificate + check. SpipCP requests the certificate from Let's Encrypt, then tests that the hostname serves the site over a valid HTTPS connection. Only then does it go green.

If a domain fails (wrong record, still proxied, DNS not propagated yet), fix the record and press Retry attach on the domain row β€” it re-runs the whole flow from the DNS check. No need to detach and start over.

The SSL dashboard

Networking β†’ SSL is a certificate dashboard β€” one row per domain, so you always know what you're running and when it expires:

ColumnWhat it tells you
DomainThe hostname the certificate covers.
Issued byThe certificate authority β€” Let's Encrypt (the default) in production, ZeroSSL / Actalis if you chose them, an uploaded custom cert, or the local dev CA (Pebble) in development.
CertificateIts state: issued, pending, renewing, failed, or none.
ExpiresThe expiry date and time left (e.g. in 62 days); amber within 21 days.
HTTPSWhether the check confirmed https://yourdomain serves with a valid certificate.
DNSWhich driver manages the record (manual, or a provider β€” Cloudflare / Bunny / Hetzner / deSEC / Gcore).
Renew nowForce an early renewal (rarely needed β€” see below).

A summary strip at the top counts what's secured, what's expiring within 21 days, and what needs attention. The same certificate detail also appears inline on each domain's row in the Domains sub-tab.

Issuance and renewal are both automatic

You don't buy, upload, or activate a certificate. When you attach a domain, the node's reverse proxy (Caddy) requests a free certificate from Let's Encrypt and installs it. It then renews each certificate roughly 30 days before expiry β€” no downtime, no cron job. The Renew now button only forces an early renewal; you never need it in normal use. A certificate-expiry check also warns you long before one could lapse. The one exception is a custom (bring-your-own) certificate β€” it doesn't auto-renew; SpipCP still warns on its expiry, and you re-upload before it lapses (see Choosing a certificate issuer).

Automating DNS with provider accounts

To let SpipCP create the record for you, connect a named DNS account under Settings β†’ DNS providers β€” a reusable credential you set up once and assign to many domains. SpipCP supports Cloudflare (US), Bunny (EU), Hetzner (German), deSEC (EU, DNSSEC by default), and Gcore (EU). Each account holds the provider's token, scoped to edit DNS records; the token is encrypted, write-only, and never reaches a node. See DNS providers for where to get each token and the EU/GDPR/free-tier notes.

The DNS-account cascade

You don't pick an account per domain by hand every time β€” a DNS account cascades node β†’ instance β†’ domain, exactly like git accounts:

LevelWhere you set itWho inherits it
Node defaultA node's DNS tabevery instance + domain under that node
Instance defaultAn instance's DNS tabevery domain on that instance
Per-domain overrideThe attach wizard / the domain rowjust that domain

A level left blank inherits from the one above, and the most-specific value wins: a domain override beats the instance default, which beats the node default. Change a node's default and every domain that never overrode follows automatically β€” no re-attach. Delete an account something pointed at and that reference falls back to "inherit the level above," never a broken pointer.

Set up an account first

Until at least one DNS account is available for a site, that provider's driver is disabled in the attach wizard, labelled "needs token in Settings", with a link to Settings β†’ DNS providers β€” so you're never led down a path that fails at attach. Full guide: DNS providers.

Wildcard subdomains and the Caddy DNS module

A wildcard certificate for *.example.com is issued over a DNS-01 challenge β€” the node's Caddy proves control of the domain by writing a TXT record through your provider's API. That needs the matching caddy-dns/<provider> module built into the Caddy on the node serving the site. A single hostname (no wildcard) uses the simpler HTTP-01 challenge and needs no DNS module.

If you request a wildcard and the node's Caddy lacks the right module, SpipCP doesn't fail silently β€” the wizard names the missing caddy-dns/<provider> module, so you know exactly what the node needs before the wildcard can issue.

Choosing a certificate issuer

Let's Encrypt is the default β€” free, automatic, nothing to configure. For operators who need an alternative, the issuer is selectable (an advanced choice in the attach wizard) and cascades node β†’ instance β†’ domain just like the DNS account:

IssuerWhat it isNeeds an account?
Let's EncryptThe default ACME CA β€” automatic issue + renew.No
ZeroSSLAn ACME CA requiring EAB (External Account Binding).Yes β€” an EAB issuer account
Actalis (EU)An EU ACME CA, also EAB-based.Yes β€” an EAB issuer account
CustomBring-your-own certificate β€” paste the chain + private key (PEM).Yes β€” a custom (PEM) issuer account

ZeroSSL and Actalis need an EAB issuer account (a Key ID + HMAC key from the provider's dashboard), and Custom needs a PEM account (the certificate chain + private key). You add both under Settings β†’ SSL issuers, where each secret is encrypted at rest and never reaches a node. Like the DNS account, the issuer account cascades β€” set a default per node or instance, override it per domain β€” and a chosen issuer with no account fails the attach with a remedy rather than going green.

β†’ Full guide: SSL issuer accounts.

Custom certificates don't auto-renew

A custom certificate isn't issued automatically, so SpipCP can't renew it. It reads the PEM on upload to record the expiry, then warns you just like an automatic cert (amber within 21 days, then an alert) β€” but the fix is to re-upload a fresh chain before it expires (Edit the issuer account with the new PEM). Let's Encrypt, ZeroSSL, and Actalis all renew automatically.

What you can manage

ControlWhat it does
Attach domainPoint a hostname at the site (one A record + the certificate).
DNS driverManual (you set the record) or a provider (Cloudflare / Bunny / Hetzner / deSEC / Gcore β€” SpipCP sets it).
Issuer (advanced)The certificate authority β€” Let's Encrypt by default; ZeroSSL / Actalis or a custom PEM; Pebble for local dev. Cascades node β†’ instance β†’ domain.
DNS accountWhich named DNS provider account drives the DNS write β€” inherited from the node/instance default, or overridden per domain.
SSL issuer accountWhich named issuer account supplies the EAB / custom-cert credential for a non-default issuer β€” inherited or overridden per domain.
Retry attachRe-run the attach after fixing a failed record (e.g. turning the proxy off).
Renew nowForce an early certificate renewal (rarely needed β€” renewal is automatic).
Orange-cloudToggle Cloudflare's proxy for a Cloudflare-driver domain (hidden for other providers β€” it's a Cloudflare product).
Wildcard subdomainOptionally catch *.domain for the site (requires a provider driver + the matching caddy-dns module on the node, since wildcards need a DNS-01 challenge).

How it works

The node's reverse proxy (Caddy) routes the hostname to the site's port on its instance, issues and auto-renews the certificate, and a certificate-expiry check warns you long before one lapses. The test before going green means "green" always means "actually serving."

β†’ Routes detail: Sites β†’ Networking. Β· Certificate alerts: Monitoring. Β· DNS accounts: Settings β†’ DNS providers. Β· Self-hosted DNS: DNS β†’ Self-hosted. Β· Issuer accounts: Settings β†’ SSL issuers.

On this page