SeeDropHost

Self-host on a VPS

Checked against the code on 2026-10-30 (version 0.1.0) · Markdown version

Today SeeDropHost runs on your own server: there is no public hosted instance yet. This page summarises the full step-by-step guide (in Portuguese) that ships with the code as docs/VPS.md. It takes about 30 minutes and is copy-and-paste.

What you need

  • A VPS with Ubuntu 24.04 and 2 GB of memory. A data centre close to your visitors helps.
  • A domain, for example mysites.example.
  • Optional but recommended: a free Cloudflare account in front.

1. DNS (with Cloudflare in front)

TypeNameContentProxy
A@your server IPproxied
A* (every site)your server IPproxied
Aedgeyour server IPDNS only

edge is where your customers' domains point (CNAME); it stays "DNS only" so domains in other Cloudflare accounts can point to it. Leave Always Use HTTPS off — the server redirects to HTTPS itself, and the Let's Encrypt HTTP challenge for customer domains must reach port 80.

Wildcard origin certificate. In Cloudflare, create an origin certificate for mysites.example and *.mysites.example. After step 2, paste it into /etc/seedrophost/tls/origin.pem and origin.key and run the installer again. Use SSL/TLS mode Full until it is installed, then Full (strict).

2. Install

ssh root@YOUR-SERVER-IP
apt-get update && apt-get install -y git
git clone <repository-url> /opt/seedrophost
sudo bash /opt/seedrophost/deploy/install.sh mysites.example you@example.com

The installer:

  • installs Node.js 24 (official package, SHA256 checked) and Caddy;
  • creates the seedrophost user, the data folder /var/lib/seedrophost, the settings file /etc/seedrophost/env, and a random token and master key in /etc/seedrophost/credentials/ (readable by root only, never in the repository), handed to the service as systemd credentials;
  • starts a hardened systemd service (NoNewPrivileges, ProtectSystem=strict, ProtectHome and more), the daily backup and a firewall (ports 22, 80, 443).

Running it again is safe: existing secrets are kept. Read your token with sudo cat /etc/seedrophost/credentials/sdh_token.

Warning: store the master key (/etc/seedrophost/credentials/sdh_master_key) in a password manager. Without it, secret site variables cannot be read back, not even from a restored backup.

3. HTTPS

Caddy sits in front. The base domain, every <site>.<base>, every deploy preview and the drop domain share the wildcard certificate from step 1, so no certificate is requested per site. Customer domains get a Let's Encrypt certificate on their first visit (on-demand TLS), but only when Caddy asks SeeDropHost and the domain is already verified by TXT; the dashboard host gets one the same way when it is outside the base. Anything else gets no certificate, so nobody can exhaust your certificate quota by pointing random names at the server. SeeDropHost itself listens only on 127.0.0.1.

Dashboard, sites and anonymous drops

  • The installer sets SDH_PANEL_HOST to the base domain: the dashboard, API and MCP answer only there, and no site is ever served on that host. Sites live at <site>.<base>.
  • Publishing without an account (SDH_ANON_DROP=1) is off by default. If you turn it on, give it a separate domain with SDH_DROP_DOMAIN (same @ and * records, and its own origin certificate in drop-origin.pem / drop-origin.key), so a phishing page published anonymously never carries your main domain. Drop limits.
  • Optional: listing the drop domain (or the base) in the Public Suffix List makes browsers treat each site as a separate site. It takes weeks.

4. First deploy

Open https://mysites.example, sign in to the dashboard with the token and drop a folder, or from your computer:

export SDH_API_URL=https://mysites.example
export SDH_TOKEN=paste-the-token
npx sdh create my-site
npx sdh deploy ./site-folder --site my-site

The site is at https://my-site.mysites.example.

5. Remote MCP

claude mcp add --transport http seedrophost https://mysites.example/mcp --header "Authorization: Bearer YOUR-TOKEN"

Everything Claude does is in the audit log as mcp-remoto. The remote MCP does not read files on the server. MCP details.

6. Backup, restore, update, take down

  • Backup: every day at 03:30 the server copies the database and site files to /var/backups/seedrophost/seedrop-YYYYMMDD-HHMMSS and deletes copies older than 14 days. Run one now with sudo bash /opt/seedrophost/deploy/backup.sh. Keep a copy off the VPS (provider snapshots or scp).
  • Restore: stop the service, copy the database and the blobs/ folder back, fix ownership, start the service (exact commands in docs/VPS.md). On a new server, put the same master key and token in /etc/seedrophost/credentials/.
  • Update: sudo bash /opt/seedrophost/deploy/update.sh backs up, fetches the new version, installs, runs the tests as the seedrophost user (never root) and restarts only if they pass.
  • Take a site down at once (phishing, abuse): DELETE /v1/sites/{site} with the token. It removes the site with its deploys, domains, forms and leads, and is recorded in the audit log.

7. Configuration

VariableWhat it is
SDH_TOKENAPI token (required outside dev mode; from systemd credentials on the VPS)
SDH_MASTER_KEYencryption key for site variables (required outside dev mode; from systemd credentials on the VPS)
SDH_BASE_DOMAINsites live at <site>.<base>
SDH_PANEL_HOSTthe only host for dashboard, API and MCP; never serves a site
SDH_PORT / SDH_HOSTport and listen address (127.0.0.1 behind Caddy)
SDH_EDGE_CNAME / SDH_EDGE_IPV4what customers point their DNS to
SDH_DATA_DIRdatabase and files
SDH_ANON_DROP=1allows publishing without a token (off by default)
SDH_DROP_DOMAINseparate domain for anonymous drops
SDH_ANON_DROP_MAX_HOUR / SDH_ANON_DROP_MAX_MBserver-wide drops per hour (default 60) and total drop storage in MiB (default 2048)
SDH_FUNCTIONS=1runs functions — only if you own every site (why)
SDH_TRUST_PROXY=1read the visitor IP from X-Forwarded-For (only behind your own proxy)
SDH_ACCESS_LOG=1one JSON line per request, with a per-process IP alias instead of the raw IP

Health check: curl https://mysites.example/v1/health.

Known risks

RiskWhat to do
A phishing page on an anonymous drop stays up to 24 hoursdelete it with DELETE /v1/sites/{site}; use SDH_DROP_DOMAIN
x-sdh-actor in the audit log is declared by the clienttreat it as a label; the token is the identity
Country= rules trust CF-IPCountrywithout Cloudflare in front, visitors can fake it
Rate counters live in memorya restart resets them
Functions are not isolatedturn them on only if you own every site

Costs

Your server and domain. The guide estimates about R$ 35–80 per month (October 2026 prices, Brazil) for a 2 GB VPS, provider backup and a .com.br domain, with Cloudflare's free plan and free Let's Encrypt certificates. Hosted SeeDropHost plans: see pricing.