Create a site, upload files or a ZIP, and PULPHOST detects the runtime: composer.json or index.php means PHP, package.json means Node.js, requirements.txt or pyproject.toml means Python, index.html alone means Static. Change it any time in Settings.
Sites live at vdu.me/username/site/. The gateway strips that prefix before your app sees the request and sends it as X-Forwarded-Prefix and PULPHOST_BASE_PATH. Use relative asset URLs (./assets/app.js) or set your framework base (Vite base: "./", Next.js basePath). For dynamic apps a subdomain is simpler once enabled.
Listen on 0.0.0.0:$PORT. The package manager is picked from your lockfile.
app.listen(process.env.PORT, "0.0.0.0")
PHP runs on PHP-FPM behind nginx inside your container. For Laravel set Document Root to public, Install to composer install --no-dev --optimize-autoloader, and put php artisan migrate --force in Post-deploy command. Nothing runs automatically unless you set it.
Add a TXT record _pulphost.example.com with the token shown, point a CNAME (or A record) at the server, then press Verify. HTTPS is issued automatically.
Free plan: 1 GB storage, 1 GB RAM and 1 vCPU shared across your running sites, enforced by cgroups v2 and XFS project quotas. Builds time out and have process limits.
Every dynamic site runs in its own container: non-root user, all capabilities dropped, no-new-privileges, read-only root filesystem, PID and memory limits, no Docker socket, and a network that cannot reach other sites or platform databases. Your dashboard is served from a separate origin, so hosted sites can't act on your account.