First boot
Admin account → first-boot wizard (5 steps) → dashboard handoff. Five minutes start to finish.
After the bootstrap installer finishes and prints your dashboard URL, open it in a browser. What follows is deterministic — every step is idempotent. Close the tab and come back; you’ll resume where you left off.
[!NOTE] The wizard auto-adopts the admin you create in stage 1 — you only enter your password once. Every step is also reachable directly via its API endpoint if you’d rather script it (see the engine’s
/api/onboarding/*routes), but the UI is the recommended path.
Stage 1 — Admin account (LoginPage setup mode)
On a fresh install, no admin user exists yet. The login page detects this and switches to “Create your admin” mode automatically — you won’t see a login form, you’ll see a setup form.
What you’ll fill in
- Username — short, used for log lines and audit events. Lowercase, no spaces.
- Email — what you’ll log in with afterwards. Real address recommended; password reset uses it (when SMTP is configured).
- Password — minimum 8 characters. Vloud writes a bcrypt hash to its SQLite DB; the password never leaves the server.
Submit → the user is created in the users table, you’re immediately logged in, and the dashboard tries to load.
Stage 2 — First-boot gate redirect
The dashboard checks vloud_onboarding_state.completed and sees it’s still false. Every authenticated route redirects to /onboarding until the wizard finishes — this prevents operators from skipping setup.
First step the wizard does: silently POST /api/onboarding/admin/adopt-current — adopts the LoginPage-created admin into the wizard’s state machine so the downstream steps can proceed without re-prompting for your password.
Stage 3 — The first-boot wizard (5 steps)
A six-step React flow with a progress indicator at the top. The bar shows: Welcome → Account → Domain → Test site → Verify → Done. Each step has a single primary CTA; everything else is informational.
Step 1 — Welcome
A summary card: “Welcome to Vloud. You’re signed in as <your-email>.” If cPanel was detected during the bootstrap, this step adds an amber banner explaining that Vloud is in coexistence mode on port 2500 (so it won’t disturb your existing cPanel accounts).
Click Get started.
Step 2 — First hosting account
A “hosting account” is the Linux user that owns one or more websites on this server. Pick a short slug. The constraint:
- 2–30 characters
- lowercase letters, digits,
-,_ - must start with a letter
Example: acme or dogfood1.
What Vloud does on submit:
- creates the Linux user via
useradd --create-home - writes
/home/<slug>/{public_html,logs,tmp,etc}from the standard skel - generates a per-tenant PHP-FPM pool at
/etc/php/8.3/fpm/pool.d/<slug>.conf - reloads
php8.3-fpm - reserves one slot against
max_linux_usersin your license’s locked-model limits
If your license is at capacity, this step returns HTTP 402 with an Upgrade prompt; pick a smaller install or upgrade your tier first.
Step 3 — Attach a domain
You have two paths here:
Path A — DNS-attached (recommended)
- Make sure your DNS A record points at the server’s public IP (shown on the page).
- Confirm with
dig +short hosting.acme.comfrom your laptop. - Type the FQDN in the wizard field.
- Leave the auto-SSL checkbox ticked.
- Click Attach domain.
What happens server-side:
- nginx vhost config rendered to
/etc/nginx/sites-available/vloud-<slug>.confand symlinked intosites-enabled nginx -t+nginx -s reload- Let’s Encrypt issuance queued via certbot — HTTPS goes live within ~30s
- DKIM key auto-generated if mail is enabled for this domain
Path B — IP fallback (no DNS yet)
Tick “I don’t have DNS yet” → the wizard serves the test site at the raw server IP. SSL won’t be issued in this mode (Let’s Encrypt requires a real domain). Useful for previewing before DNS propagates. You can re-attach the same site properly once DNS is set up.
Step 4 — Deploy a test site
Single button. The wizard drops a minimal index.php with a known marker into /home/<slug>/public_html/ and sets ownership correctly. Takes 5–15 seconds.
Step 5 — Verify it’s serving
The wizard curls the domain from the server itself and confirms three things:
- nginx returned a 200
- php-fpm rendered the file (the response went through PHP, not static)
- the response body contains the expected marker (confirms the file Vloud just wrote is what’s being served)
On success: tick → step 6. On failure (DNS hasn’t propagated yet, etc.): the wizard shows the actual HTTP status / detail it got back. Two recovery paths:
- Re-try — most useful when DNS is propagating but slow.
- Skip for now — marks the wizard complete without verification. After you exit, an amber Unverified setup banner appears at the top of every page until you re-verify or fix the underlying issue.
[!WARNING] Skip-Verify is safe to use, but don’t ignore the amber banner afterwards. A non-serving test site usually means the actual production sites you deploy next will also not serve — fix DNS / SSL before putting real workloads on it.
Step 6 — Done
Summary card with your account slug, domain, test-site URL, and a CTA to open the dashboard. The wizard marks itself complete (sets vloud_onboarding_state.completed = 1), the first-boot gate disarms, and you’re routed to /dashboard.
Stage 4 — Dashboard handoff
First time on the dashboard, you’ll see:
- Sidebar capacity widget showing your tier (e.g.
ENTERPRISEin trial mode), status pill (ACTIVE), and capacity bars formax_instancesandmax_linux_users. Click → Settings → License. - Trial banner at the top: “30-day trial active — NN days remaining” (only when ≤7 days left, otherwise hidden).
- Help icon in the top bar (the
?) opens Help menu: Report a bug, My tickets, Documentation.
Recommended next steps
- Activate a license from Settings → License (or stay on the trial — 30 days).
- Deploy your first real app — WordPress in 2 minutes, or a Next.js app from Git.
- Read the tier-features matrix to understand what’s unlocked at your plan.
- Check Settings → Modules to see which daemons are active on this install.
- If you came from cPanel, see cPanel migration to pull existing accounts across.
What if a wizard step fails?
Common modes + fixes:
- “invalid_slug” on step 2 — slug doesn’t match the regex. Lowercase letters/digits/
-/_, start with a letter. - “admin_not_set” on step 2 — adopt-current failed silently. Refresh the page (it re-runs adopt-current automatically).
- “first_account_already_set” on step 2 — you re-ran step 2 after a successful first run. The wizard skips ahead to step 3.
- “invalid_domain” on step 3 — RFC 1035 form required (
host.example.com, not a URL). - “validation didn’t complete” on step 5 — typically DNS hasn’t propagated. Wait ~5 min and re-verify, or skip for now.
Resetting the wizard
If you want to start over (e.g. you typed the wrong domain), drop to the server and run:
# From the dashboard: /onboarding → "Reset wizard" — or:
curl -fsS -X POST http://127.0.0.1:2500/api/onboarding/reset \
-H "Cookie: vloud_session=<your-session-cookie>"
This clears the wizard’s state row only — created hosting accounts, domains, certs, and mailboxes survive untouched.
What got installed (so far)
By the end of the wizard you have, on this server:
- One Linux user (the hosting account slug) with PHP-FPM pool + home dir scaffolding
- One nginx vhost serving the test site
- (if DNS path) a Let’s Encrypt cert auto-renewing for that vhost
- A running engine + 30-day trial + machine-bound HMAC chain
- Mail + DNS + FTP + firewall + fail2ban daemons (skipped if cPanel coexist)
- Audit logs in
audit_events; redacted support bundles available on demand
That’s a real, working hosting box. Now go deploy something on it.