ServerVault
Sign in Get started

ServerVault User Manual

Add a server in 30 seconds, deploy PHP or AI-generated apps in minutes, and never SSH just to check disk space again.

14-day free trial. Every new account gets full access to all features. Your card is collected at signup but nothing is charged until the trial ends. Cancel any time before that and you owe nothing.

Up and running in 5 minutes

Here's the whole flow from zero to a live server. Each step has a detailed section below if you want to go deeper.

  1. Create your free account — takes about 30 seconds.
  2. Click Servers → Add server, give it a name, and save.
  3. Copy the one-line bootstrap command and run it on your Ubuntu VPS as root.
  4. Your server shows Online within 30 seconds — you're done.

What you need

  • A VPS or dedicated server running Ubuntu 22.04 or 24.04 LTS (64-bit) — any cloud provider works
  • At least 512 MB RAM and 1 vCPU — most $5/mo VPS plans qualify
  • The ability to run one command on the server as root — that's the only manual step
  • Standard outbound internet access from the server (enabled by default on every VPS)

How the agent works

ServerVault installs a tiny background service on your server — about 8 MB, zero dependencies. It phones home every 5 seconds to pick up work (creating apps, provisioning SSL, etc.) and sends a heartbeat every 30 seconds so you can watch CPU, RAM, and disk usage live in your dashboard. Your server never needs an open inbound port.

curl -fsSL https://servervault.dev/install.sh | bash -s -- --token=YOUR_TOKEN

Replace YOUR_TOKEN with the token shown on your server's page. The one-line installer will:

  1. Install nginx, PHP (7.4 – 8.3), MySQL 8, Certbot, and UFW on the server
  2. Download the ServerVault agent binary to /usr/local/bin/servervault-agent
  3. Register it as a systemd service so it starts automatically on reboot
  4. Send the first heartbeat — your server turns Online in under 30 seconds

Add your first server

In your dashboard, click Servers → Add server. Give it a friendly name — "Production", "Staging", "DigitalOcean NYC3" — whatever helps you remember it. Click Save and you'll immediately see a unique bootstrap command ready to copy.

Run the bootstrap command

Each server gets a unique one-time token. Copy the bootstrap command from the server page and paste it into your server terminal as <code>root</code>. It looks like this:

curl -fsSL https://servervault.dev/install.sh | bash -s -- --token=svt_abc123...

Launch on Linode or DigitalOcean

Skip manual VPS setup entirely. From Servers → Add server, switch to the Linode or DigitalOcean tab, pick a region and plan, and ServerVault provisions the box and installs the agent for you — no bootstrap command to copy.

  • Bring your own account — connect your Linode or DigitalOcean account once via OAuth, then launch servers billed directly by the provider, no markup.
  • Or let ServerVault host it — provisioned on ServerVault's own infrastructure and billed through your subscription with a small markup included.
  • Either way, the agent installs itself automatically and your server shows Online within a couple of minutes.

Understanding server status

StatusWhat it means
PENDINGServer created in ServerVault, bootstrap command not run yet
ONLINEAgent is running and sending heartbeats — everything is working
OFFLINENo heartbeat for 5+ minutes — check if the server or agent is down
ERRORAgent reported a problem — open the server page for details

Create an app

An "app" is one isolated website or web application — a WordPress site, a Laravel project, a static site, anything. Each app gets its own Linux user, web root, and PHP process so apps on the same server can't interfere with each other. To create one, open a server and click New app, then:

  • Enter a name using letters, numbers, and dashes (e.g. my-blog or client-site)
  • Choose a PHP version — you can change it later without losing data
  • Click Create — ServerVault configures nginx, PHP-FPM, and the web root in about 15 seconds

Pick a PHP version

Every app gets its own PHP-FPM pool, so you can run a WordPress site on PHP 8.1 and a legacy app on PHP 7.4 on the exact same server — no conflicts. Need to upgrade? Change the version in app settings and the switch takes a few seconds:

  • PHP 8.5
  • PHP 8.4
  • PHP 8.3
  • PHP 8.2
  • PHP 8.1
  • PHP 8.0
  • PHP 7.4

Deploy your code

Two ways to get your code live:

  • Auto-deploy from Git (recommended) — connect your GitHub, GitLab, or Bitbucket account, pick a repo and branch, and every git push deploys automatically. Set it up once and forget about it. See Git & Auto-deploy below.
  • Deploy on demand — click Deploy now on the app's Git tab whenever you're ready. Great for controlled releases where you want to decide when code goes live.

Host AI-generated apps safely

ServerVault is built for teams shipping quickly with AI coding tools. You can host generated Laravel, PHP, and static projects using the same Git-based release flow you already trust.

  • Keep generated code in Git and use branch-based deploys for traceability
  • Use custom deploy scripts to add quality gates (tests, linters, migrations)
  • Ship preview, staging, and production variants on separate apps or servers

Connect GitHub, GitLab, or Bitbucket

Go to Git Accounts in the sidebar and click Connect GitHub (or GitLab / Bitbucket). You'll be taken to that provider to approve access — it takes about 10 seconds. Once connected, the account appears in your list and can be linked to any app.

You can connect multiple accounts across providers — for example your personal GitHub account and a work GitLab account. Each app can use a different account independently.

Auto-deploy on every push

On any app's Git tab, do this once:

  1. Select the Git account to use from the dropdown.
  2. Choose the repository and the branch to deploy (e.g. main).
  3. Toggle Auto-deploy on push to on.
  4. Copy the Webhook URL shown and add it in your repo under Settings → Webhooks with content type application/json.

From that point forward, every push to that branch triggers a deploy. The deploy log appears in real time — you'll see exactly what's happening.

Customize the deploy script

ServerVault runs a deploy script on every deploy. The default script for a Laravel app looks like this — tweak it in the app's <strong>Git → Deploy Script</strong> tab to match your project:

cd /srv/users/srv-myapp/apps/myapp
git pull origin main
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan queue:restart

The script runs as the app's system user in a bash shell. If any command returns a non-zero exit code the deploy is marked failed and stops — nothing broken gets pushed live.

Working with multiple Git accounts

You can connect more than one account for the same provider — handy if you maintain both personal projects and client repos across different GitHub or GitLab organizations. On the Git Accounts page each connected account has its own card. When setting up an app, a dropdown lets you pick which account to use for that specific app.

Point a domain to your app

Before adding a domain in ServerVault, log into your DNS registrar and create an A record pointing your domain (e.g. example.com) to your server's IP address. DNS changes take a few minutes to propagate — you can check with ping example.com. Once DNS resolves to your server, open the app, type the domain into the Domains field, and click Add. nginx starts serving the app on that domain immediately.

Free SSL in one click

Once your domain is added and DNS has propagated, click Provision SSL next to the domain. ServerVault requests a free Let's Encrypt certificate, configures nginx for HTTPS, and sets up an automatic HTTP → HTTPS redirect — all in about 30 seconds. Certificates renew automatically 30 days before they expire. You'll never think about SSL again.

Managed email hosting for app domains

Attach email domains to an app, verify DNS, and create mailboxes directly from the app screen. You can open webmail in one click and rotate mailbox passwords when needed.

Create and manage mailboxes

  1. Open an app and switch to the Email tab
  2. Add your domain and copy the required MX, SPF, DKIM, and DMARC records
  3. Click Verify DNS, then create mailboxes for your team or clients

Mailbox pricing

Mailboxes aren't billed separately — creating or deleting one doesn't change your subscription.

Create a MySQL database

On the app page, scroll to Databases and enter a database name, then click Create. ServerVault generates a strong random password, creates an isolated MySQL user with access only to that one database, and shows you the credentials. Copy the password before closing the dialog — you can always retrieve it later, but this is the only time it's shown in full.

Retrieve your database credentials

Already closed the dialog? No problem. Click Show credentials on any database row at any time to see the host, port, username, and password. Credentials are stored encrypted and are always accessible from your dashboard.

Browser terminal — SSH from anywhere

Every server has a full terminal built into the dashboard. No SSH client to install, no firewall rules to open, no VPN to connect to. Open your browser, click the Terminal tab, and you're in — from any device, anywhere.

How to open a terminal

  1. Open a server and click the Terminal tab.
  2. Click Connect. ServerVault creates a secure session and signals the agent.
  3. A live terminal appears — type commands exactly as you would over SSH.
  4. Sessions close after 30 minutes of inactivity. Click Connect again to start a fresh session.

The terminal runs as root via the agent. All traffic goes through your ServerVault control plane — your server never needs an open inbound port.

File manager — edit files without SFTP

Every app has a file manager on its Files tab. Browse, edit, upload, and reorganize files directly in your browser — no FTP client, no WinSCP, no nano over SSH.

  • Browse — click through directories and see file sizes and permissions at a glance.
  • Edit — click any text file to open it in a code editor right in the browser.
  • Upload — drag and drop files or folders to upload them instantly.
  • Download — click any file to download it to your computer.
  • Create — add new files or folders without opening a terminal.
  • Rename / Delete — rename or permanently remove files and directories.
  • Chmod — change file permissions with a numeric mode (e.g. 644, 755).
  • Zip / Unzip — compress a folder into a .zip for backup, or extract an archive in place.

File operations run as the app's system user — you can only access files within that app's own directory.

Share access with your team

Need to give a developer access to one server, or let a client see their own app? Go to Team in the sidebar, invite teammates by email, and choose exactly which servers, apps, and databases they can see. Everyone else stays invisible to them.

Invite a teammate

  1. Go to Team in the sidebar.
  2. Enter the person's email and select the servers, apps, and databases they should be able to access.
  3. Click Send invite — they'll get an email with a link to accept.
  4. Once they accept, they're in — and can only see exactly what you allowed.

Granular access control

Team members can only see and interact with resources you explicitly grant them. They can't add new servers, touch billing, or see anything outside their assigned scope. You can update or revoke their access at any time from the Team page — changes take effect immediately.

Agent API (for developers)

The Go agent communicates with ServerVault over HTTPS. All endpoints live under /api/agent/v1/. You only need this section if you're building a custom integration or debugging agent behavior.

Heartbeat endpoint

POST /api/agent/v1/heartbeat
Authorization: Bearer <agent_token>

{
  "status": "online",
  "agentVersion": "1.0.0",
  "metrics": {
    "cpuPercent": 12.4,
    "memUsedBytes": 512000000,
    "memTotalBytes": 2048000000,
    "diskUsedBytes": 10000000000,
    "diskTotalBytes": 50000000000,
    "loadAvg1m": 0.42
  }
}

Jobs endpoints

GET  /api/agent/v1/jobs/pending
PATCH /api/agent/v1/jobs/{actionId}       { "status": "succeeded" }
POST  /api/agent/v1/jobs/{actionId}/logs  { "line": "..." }

Automation API (for developers)

Script your own account — send email today, with deploys, server provisioning, and database management planned next — using one personal API token. This is separate from the Agent API above, which is for the background agent only, not your own scripts.

Get your API token

Go to Account Settings → API Access and click Generate API Token. It's shown once — copy it somewhere safe. Every request authenticates with Authorization: Bearer <token>. Regenerating replaces it immediately and the old token stops working right away.

Mail Relay API — send email over HTTPS

If another server you run has outbound SMTP blocked by its hosting provider but can reach ServerVault over HTTPS, relay email through your account's mailer instead of SMTP directly. One endpoint, one request:

POST /api/relay/mail/send
Authorization: Bearer <your personal API token>
Content-Type: application/json

{
  "to": "user@example.com",
  "subject": "Your report is ready",
  "body": "Plain text or simple HTML, up to ~100KB.",
  "from": "reports@yourdomain.com"
}
Field Required Type Example
toYesstring, or array of up to 5"user@example.com"
subjectYesstring, max 255 characters"Your report is ready"
bodyYesstring, max ~100KB — plain text or simple HTML, auto-detected"Hi there, ..."
fromNostring (email)"reports@yourdomain.com" — must be on a domain you've verified in ServerVault; omit it to use your account's default sender

Response — Every response, success or failure, is one of these two shapes:

{ "sent": true }

{ "sent": false, "error": "Daily send limit reached" }

Status codes

StatusMeaning
200Sent — response is {"sent": true}
401Missing, invalid, or revoked bearer token
422A field failed validation, or from isn't a verified domain you own
429Over the per-minute limit (30/min/account), or your account's daily send cap
500The SMTP send itself failed on our end

Automation API (v1) — manage your account by script

The same token also authenticates endpoints under /api/v1/ for reading and managing your servers, apps, databases, domains, and email — every one of them scoped to exactly what your account can already see and do in the dashboard, nothing more. Server provisioning isn't available here yet.

Every request needs Authorization: Bearer <token>. A successful response looks like {"data": ...} — an object for a single resource, an array for a list. A failed one looks like {"error": "...", "code": "..."}. A write that queues real work on your server returns 202 with an action_id — poll GET /api/v1/actions/{id} to see when it finishes.

GET /api/v1/servers
Authorization: Bearer <your personal API token>

{ "data": [ { "id": 2, "name": "web-1", "status": "ONLINE", "provider": "digitalocean", ... } ] }
GET /api/v1/servers/999
Authorization: Bearer <your personal API token>

{ "error": "Server not found", "code": "not_found" }

Reads

Endpoint Query params Returns (fields)
GET /api/v1/serversid, name, ip_address, hostname, status, provider, provider_region, agent_version, last_heartbeat_at, setup_completed_at, created_at
GET /api/v1/servers/{id}same fields, single object
GET /api/v1/appsserver_id (optional)id, server_id, name, php_version, status, github_repo, github_branch, auto_deploy, created_at
GET /api/v1/apps/{id}same fields, single object
GET /api/v1/databasesapp_id (optional)id, app_id, db_name, db_user, created_at — credentials are never included here
GET /api/v1/domainsapp_id (optional)id, app_id, domain, is_primary, ssl_status, ssl_expires_at
GET /api/v1/email-domainsid, domain, provider, status, dns_verified
GET /api/v1/email-domains/{id}/mailboxesid, email, quota_mb, disabled, created_at — no passwords
GET /api/v1/actions/{id}id, server_id, type, status, attempts, completed_at, created_at — poll this to watch an async job finish

Writes

Writes queue a real job for your server's agent — they're rate-limited tighter than reads (20/min/account vs. 60/min/account).

POST /api/v1/apps
Authorization: Bearer <your personal API token>
Content-Type: application/json

{ "server_id": 2, "name": "my-blog", "php_version": "8.3", "system_user": "myblog" }

{ "data": { "id": 9, "server_id": 2, "name": "my-blog", "status": "CREATING", "action_id": 41, ... } }
Endpoint Body params Notes
POST /api/v1/appsserver_id, name, php_version, system_user — all requiredQueues CREATE_APP
POST /api/v1/apps/{id}/deployDeploys the app's already-configured Git repo/branch; 422 if none is set
DELETE /api/v1/apps/{id}Queues DELETE_APP
POST /api/v1/apps/{id}/domainsdomain (required), is_primary (optional)Queues CREATE_DOMAIN (nginx vhost)
POST /api/v1/domains/{id}/sslQueues PROVISION_SSL (free Let's Encrypt cert)
DELETE /api/v1/domains/{id}Removes the domain record immediately, synchronously
POST /api/v1/databasesapp_id, db_name, db_user (required), db_password (optional, auto-generated if omitted)Response includes db_password once — copy it, it's never shown again
DELETE /api/v1/databases/{id}Queues DELETE_DATABASE
POST /api/v1/email-domainsapp_id, domain — both required
DELETE /api/v1/email-domains/{id}Deletes every mailbox on it first
POST /api/v1/email-domains/{id}/mailboxesusername, password (required), quota_mb (optional), policy_agreed: true (required)Not billed — policy_agreed confirms acceptable use (no spam, no warmup tools)
DELETE /api/v1/email-domains/{id}/mailboxes/{mailboxId}Removes the mailbox

Status codes

StatusMeaning
200 / 201 / 202200 for reads and sync writes, 201 for a created resource, 202 when a job was queued for the agent
401Missing or invalid bearer token
404The resource doesn't exist, or belongs to a different account — deliberately indistinguishable, so a token can't be used to probe for other accounts' IDs
422Validation failed — check error for which field
429Over the per-minute limit (60/min/account for reads, 20/min/account for writes)
500Something failed on our end creating the mailbox on the mail server