Self-host on a VPS
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)
| Type | Name | Content | Proxy |
|---|---|---|---|
| A | @ | your server IP | proxied |
| A | * (every site) | your server IP | proxied |
| A | edge | your server IP | DNS 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
seedrophostuser, 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,ProtectHomeand 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_HOSTto 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 withSDH_DROP_DOMAIN(same@and*records, and its own origin certificate indrop-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-HHMMSSand deletes copies older than 14 days. Run one now withsudo bash /opt/seedrophost/deploy/backup.sh. Keep a copy off the VPS (provider snapshots orscp). - Restore: stop the service, copy the database and the
blobs/folder back, fix ownership, start the service (exact commands indocs/VPS.md). On a new server, put the same master key and token in/etc/seedrophost/credentials/. - Update:
sudo bash /opt/seedrophost/deploy/update.shbacks up, fetches the new version, installs, runs the tests as theseedrophostuser (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
| Variable | What it is |
|---|---|
SDH_TOKEN | API token (required outside dev mode; from systemd credentials on the VPS) |
SDH_MASTER_KEY | encryption key for site variables (required outside dev mode; from systemd credentials on the VPS) |
SDH_BASE_DOMAIN | sites live at <site>.<base> |
SDH_PANEL_HOST | the only host for dashboard, API and MCP; never serves a site |
SDH_PORT / SDH_HOST | port and listen address (127.0.0.1 behind Caddy) |
SDH_EDGE_CNAME / SDH_EDGE_IPV4 | what customers point their DNS to |
SDH_DATA_DIR | database and files |
SDH_ANON_DROP=1 | allows publishing without a token (off by default) |
SDH_DROP_DOMAIN | separate domain for anonymous drops |
SDH_ANON_DROP_MAX_HOUR / SDH_ANON_DROP_MAX_MB | server-wide drops per hour (default 60) and total drop storage in MiB (default 2048) |
SDH_FUNCTIONS=1 | runs functions — only if you own every site (why) |
SDH_TRUST_PROXY=1 | read the visitor IP from X-Forwarded-For (only behind your own proxy) |
SDH_ACCESS_LOG=1 | one 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
| Risk | What to do |
|---|---|
| A phishing page on an anonymous drop stays up to 24 hours | delete it with DELETE /v1/sites/{site}; use SDH_DROP_DOMAIN |
x-sdh-actor in the audit log is declared by the client | treat it as a label; the token is the identity |
Country= rules trust CF-IPCountry | without Cloudflare in front, visitors can fake it |
| Rate counters live in memory | a restart resets them |
| Functions are not isolated | turn 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.