Self-hosting

Preview Last updated

Running Skip the Sell yourself — a single binary with SQLite, environment-variable configuration, Litestream backups, and offline-verifiable license keys.

Preview. Self-hosting ships with the first release. This guide describes the planned shape so you can evaluate it early; details may move before launch.

One binary, one file#

The artifact is the same Go binary the hosted platform runs: the API plus the checkout UI embedded, a static build with no external runtime, talking to a single SQLite database file. Point it at a directory and it runs:

./skip

The same artifact ships as a container image; the deploy recipes land with the release.

Configure with environment variables#

Every variable has a default; a misconfiguration fails at startup with an error naming the variable to fix — not later, on the first email or the first deal.

Core variables:

Variable Default What it is
SKIP_ADDR :8080 Listen address for the HTTP server
SKIP_DB_PATH ./data/skip.db SQLite database file
SKIP_PRODUCT_NAME Skip the Sell Display name of the product
SKIP_BASE_URL https://app.skipthesell.com Public base URL of your deployment — used in deal URLs, emails and discovery

Transactional email has one sender interface with three providers, selected by SKIP_EMAIL_PROVIDER:

Provider Use Requires
log (default) local and dev; prints to the log nothing
resend the hosted platform RESEND_API_KEY
smtp self-hosting, including Amazon SES via its SMTP interface SKIP_SMTP_HOST

Common email variables: SKIP_EMAIL_FROM (the sender on every message), SKIP_EMAIL_DIR (with the log provider, also write each message as .eml and .json). SMTP variables: SKIP_SMTP_HOST, SKIP_SMTP_PORT (default 587), SKIP_SMTP_USERNAME and SKIP_SMTP_PASSWORD — both or neither. The connection is upgraded with STARTTLS; credentials are never sent over a cleartext connection, and port 465 is rejected at startup in favor of 587 with STARTTLS.

Backups#

The database is one file, so backup is a solved problem: we will document a recipe with Litestream continuously replicating the SQLite file to S3-compatible object storage, with point-in-time restore. The hosted platform runs the same shape before the first paying customer.

License keys, verified offline#

  • Your license is an Ed25519-signed document, prefixed stsp-lic-v1. so parsers can dispatch on the format. It carries the schema version, a key ID, entitlements, limits and an expiry.
  • Verification is fully offline: the binary ships with the trusted public keys (rotation happens through key IDs), and no phone-home is ever required to run.
  • An expired or invalid license degrades the instance to read-only after a grace period — never a lock-out. Signed deals and contract terms stay retrievable for as long as the account exists.
  • Usage reporting uses one versioned schema with two transports: through the API by default, or a signed export file for air-gapped installs (a premium tier).

Self-hosting changes nothing else#

It is the same API, under the same versioned contract, serving its own discovery: your agents find your deployment's /llms.txt and meta.discovery on your own domain (for agents). You connect your own Stripe. The hosted platform and your instance differ in who operates them, not in behavior. Credentials are the same too: API keys, deal tokens and operator tokens all carry the platform's published skipthesell_… format, whatever deployment minted them.

Upgrade note. Credentials minted before that format shipped carry the older sk_/dlt_/opt_ shape and keep authenticating only until 2027-02-07T00:00:00Z (the end of 2027-02-06 UTC) — one fixed instant for every deployment. An instance upgrading after it accepts only the new format: rotate your agents' credentials before upgrading past it.