edge

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 6, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package edge generates the per-project artefacts the long-running containers read: a caddy site file and a pgweb bookmark.

Both are plain files in DRAGONRUN_HOME, mounted read-only into the containers. Registering a project therefore never restarts the stack -- caddy gets a reload, pgweb picks bookmarks up on next page load.

Index

Constants

View Source
const (
	CertLifetime         = "2160h" // 90 days
	IntermediateLifetime = "8760h" // 365 days
)

Lifetimes for the certificates caddy's local CA issues. `tls internal` defaults to a 12-hour leaf off a 7-day intermediate, which assumes a server that is always up to renew them. A dev edge is stopped overnight and hit again in the morning, and by then the certificate has expired.

A leaf is truncated to its issuer's notAfter, so the intermediate has to comfortably outlive it. Caddy renews the intermediate with a third of its life left -- four months here -- which is still longer than a whole leaf lifetime, so a leaf is never issued short. 90 days also stays under the 398-day ceiling browsers apply to server certificates.

CertLifetime is written into each generated site file. IntermediateLifetime is a global option and lives in the stack's Caddyfile; the constant is here so the two are stated together, and a test keeps them equal.

Variables

View Source
var ServiceHosts = map[string]string{
	"mail":  "mailpit:8025",
	"pgweb": "pgweb:8081",
}

ServiceHosts are the built-in UIs dragonrun serves under its own domain, so you never have to remember a port. They proxy to the CONTAINERS by service name -- caddy shares a network with them -- rather than back out through the host's published ports.

These are browser URLs, which is why a hostname is fine here while the database and SMTP DSNs deliberately stay on localhost: a browser URL failing off-network is a mild annoyance, an app failing to boot is not.

Functions

func Bookmarks added in v0.2.0

func Bookmarks() ([]string, error)

Bookmarks lists the pgweb bookmarks present on disk, by project name.

func CertHosts added in v0.2.0

func CertHosts() ([]string, error)

CertHosts lists the hostnames caddy holds a certificate for.

A certificate outlives the site file that caused it: unregister a project and caddy keeps its certificate until the volume is recreated, which is how a host nobody serves any more goes on looking real.

func DeleteCA

func DeleteCA(fp string) error

DeleteCA removes one certificate from the system keychain by fingerprint.

func EnsureCertLifetimes added in v0.2.0

func EnsureCertLifetimes() (bool, error)

EnsureCertLifetimes brings a running stack's certificates up to the lifetimes above, and reports whether it had to change anything.

Raising them in config is not enough on a stack that has already run. Caddy keeps the intermediate it minted under the old settings until it is nearly expired, and truncates every leaf to that date; it also keeps each cached leaf until that leaf's own renewal window. An install upgraded in place would go on serving twelve-hour certificates -- silently, which is the whole bug.

Deleting the intermediate makes caddy mint a replacement from the SAME root, so nothing has to be re-trusted and no keychain entry goes stale. The cached leaves go with it so every site is re-issued now rather than at its next renewal.

func Fingerprint

func Fingerprint(path string) (string, error)

Fingerprint returns the SHA-1 of a PEM certificate, formatted the way `security find-certificate -Z` prints it.

func KeychainCAs

func KeychainCAs() ([]string, error)

KeychainCAs lists every trusted caddy root, by fingerprint. Used to find roots left behind when the caddy volume was recreated.

func Reload

func Reload() error

Reload asks caddy to re-read its config in place. A restart would drop in-flight requests and, more annoyingly, re-issue certificates.

func RemoveBookmark

func RemoveBookmark(name string) error

func RemoveSite

func RemoveSite(name string) error

func RootCA

func RootCA() (string, error)

RootCA copies caddy's local CA out of the container so it can be trusted by the host. Until this is trusted, every https://*.test hit shows a warning.

func SiteFiles added in v0.2.0

func SiteFiles() ([]string, error)

SiteFiles lists the project site files present on disk, by project name. The built-in `_services.caddy` is dragonrun's own and never a project.

func TrustCA

func TrustCA(path string) error

TrustCA installs caddy's root into the system keychain. Requires sudo, and deliberately shells out visibly so the password prompt is not a surprise.

func UntrustCA

func UntrustCA(rootCrt string) (bool, error)

UntrustCA removes dragonrun's caddy root from the system keychain.

It matches on the certificate's SHA-1 fingerprint, not its name: the label carries a year ("Caddy Local Authority - 2026 ECC Root") and any other Caddy on this machine -- one of the per-project Caddyfiles, say -- produces a root with the same name. Deleting by name could untrust someone else's CA.

func WriteAllSites added in v0.2.0

func WriteAllSites(c *registry.Config) error

WriteAllSites regenerates every registered project's site file.

A site file is a pure function of the registry entry behind it, so rewriting them all is how a change to what dragonrun generates -- a certificate lifetime, say -- reaches projects that were registered by an older binary. Without this they keep whatever `register` wrote, however long ago.

func WriteBookmark

func WriteBookmark(c *registry.Config, p registry.Project) error

WriteBookmark points pgweb at the project's control database as the cluster superuser, so tenant databases created later are reachable from the UI's database switcher without any further registration.

It connects to postgres directly rather than through pgbouncer: browsing is a session-oriented workload and transaction pooling would only get in the way.

func WriteServiceSites

func WriteServiceSites(c *registry.Config) error

WriteServiceSites renders the built-in hostnames. One file, rewritten whenever the stack comes up, named with a leading underscore so it can never collide with a project's own site file.

func WriteSite

func WriteSite(p registry.Project) error

WriteSite renders the reverse proxy entry. The upstream is host.docker.internal because the app runs on the HOST under mprocs -- caddy is the only part of the request path that lives in docker.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL