Open-source, self-hosted PaaS. Git auto-deploy, automatic SSL, custom domains, databases, your own email server and one-click apps, all on your own server.
A self-hosted alternative to Heroku, Vercel, Netlify, Render and Coolify.
Website Β· Quick start Β· Features Β· Deploying apps Β· Email server Β· API Β· FAQ Β· β Sponsor
Tip
SelfDeploy is 100% free and open source. If it saves you hosting bills or time, please consider supporting its development:
buymeacoffee.com/99proteam. Every coffee funds new features, fixes and updates. β Starring the repo helps too!
SelfDeploy turns any Linux VPS into your own Platform-as-a-Service. Push to Git and your app is built, deployed with zero downtime and served over HTTPS. You can also run PostgreSQL, MySQL, MongoDB and Redis with scheduled backups, host email for your domains, and launch WordPress, Ghost, n8n and more in one click. It ships as a single Go binary in one Docker container.
On a fresh Ubuntu/Debian server (1 GB RAM minimum, 2 GB+ recommended), run:
curl -fsSL https://raw.githubusercontent.com/99proteam/selfdeploy/main/install.sh | sudo bashThen open http://YOUR_SERVER_IP:8000 and create your admin account. Docker is installed for you if it's missing. Re-run the same command to upgrade; your data is kept.
Install with Docker Compose instead
git clone https://github.com/99proteam/selfdeploy && cd selfdeploy
docker compose up -d| Git auto-deploy | Push to GitHub, GitLab, Gitea/Forgejo or Bitbucket and SelfDeploy deploys automatically via signed webhooks. Public and private repos (access token or SSH deploy key), monorepos (base directory). |
| Any stack | Dockerfile, Nixpacks (Node.js, Next.js, Python, Django, Go, PHP/Laravel, Ruby/Rails, Rust, Java, .NET, Elixir, Deno, Bun β¦), static sites and SPAs (Vite, React, Vue, Astro β¦), Docker Compose, or any Docker image. |
| Automatic SSL | Free Let's Encrypt certificates for every domain, issued and renewed automatically, with HTTPβHTTPS redirects. |
| Temporary domains | Every app gets a working URL instantly (app.203.0.113.7.sslip.io), with no DNS setup. |
| Custom & wildcard domains | Multiple domains per app. Set a wildcard domain once and new apps get name.apps.example.com. |
| Zero-downtime deploys | The new version starts next to the old one and must pass its health check before traffic switches. |
| One-click rollback | Every build is kept as an image; roll back to any previous deployment in seconds. |
| Preview deployments | Each pull/merge request gets its own URL (pr12.app.example.com), removed automatically when it closes. |
| Databases | PostgreSQL, MySQL, MariaDB, MongoDB and Redis in one click, with generated credentials and optional public access. |
| Backups | Scheduled (cron) and on-demand database backups, retention, one-click restore, download, and upload to any S3-compatible storage (AWS S3, Cloudflare R2, Backblaze B2, Wasabi β¦). |
| Email server | Your own mail server for custom domains: SMTP, IMAP, DKIM, SPF, DMARC, spam filtering and fail2ban, with the exact DNS records shown for you. Apps can send mail without credentials. |
| One-click services | WordPress, Ghost, n8n, Uptime Kuma, Gitea, Vaultwarden, RustFS (S3), Umami, Nextcloud, Roundcube webmail, Grafana, Adminer. |
| Multiple servers | Manage remote servers over SSH from one dashboard. |
| Environment variables | Runtime and build-time variables, with .env import. |
| Logs & monitoring | Live build logs, runtime logs, CPU/memory/disk and per-container stats. |
| Notifications | Discord, Slack, Telegram, email or any webhook, for deploy and backup events. |
| Teams & API | Multiple users, admin roles, API tokens and a REST API for CI/CD. |
| Lightweight | One Go binary with an embedded dashboard and SQLite. SelfDeploy itself uses about 20 MB of RAM. |
- Create a project, then + App.
- Paste your repository URL (for private repos, add an access token) or a Docker image name.
- Pick a build pack. Auto-detect chooses:
Dockerfileβ Docker Compose β staticindex.htmlβ Nixpacks. - Set the port your app listens on. SelfDeploy also sets
PORTandHOST=0.0.0.0for you. - Click Create. Your app is live at a temporary
sslip.ioURL within a minute or two.
Point an A record (and AAAA for IPv6) at your server's IP, then add the domain to the app (e.g. https://app.example.com) and redeploy. Traefik requests a free Let's Encrypt certificate with the HTTP-01 challenge, renews it automatically and redirects HTTP to HTTPS. Ports 80 and 443 must be reachable from the internet, and if you use Cloudflare, set the record to DNS only (grey cloud) until the certificate is issued. You can list several domains, separated by commas. Prefix a domain with http:// to serve it without TLS.
To give every new app a domain automatically, create a wildcard record *.apps.example.com β your IP and set Settings β Wildcard domain to apps.example.com.
To serve the dashboard over HTTPS, set Settings β Dashboard domain.
Each app has a Git & webhooks tab with ready-to-paste webhook URLs and a secret:
| Provider | Webhook URL | Secret |
|---|---|---|
| GitHub | /webhooks/github/<app-id> |
Webhook secret (HMAC SHA-256 verified) |
| GitLab | /webhooks/gitlab/<app-id> |
"Secret token" |
| Gitea / Forgejo | /webhooks/gitea/<app-id> |
Webhook secret (HMAC verified) |
| Bitbucket | /webhooks/bitbucket/<app-id>?secret=β¦ |
in the URL |
| Any CI | /webhooks/deploy/<app-id>?secret=β¦ |
in the URL |
Enable preview deployments for an app to get a URL for each pull request. For safety, pull requests opened from forks are never built: on a public repository that would run a stranger's code on your server with your app's environment variables.
Set a health check path (e.g. /health) and a new version only goes live once it returns 2xx. If it fails, the previous version keeps serving and you get notified. Roll back from the Deployments tab.
Create a database from a project. Apps on the same server connect with the internal URL shown on the database page (e.g. postgres://selfdeploy:β¦@main-db:5432/app). Add it to your app's environment as DATABASE_URL.
Backups run on a cron schedule (0 3 * * * = daily at 03:00 UTC), keep the last N copies, and can be restored or downloaded from the dashboard. Configure Settings β Backup storage and tick Upload to S3 to keep copies off-server. The bucket is created for you if it doesn't exist.
- Create DNS record
A mail.example.com β your server IP, and set the reverse DNS (PTR) for the IP tomail.example.comat your VPS provider. - Go to Mail server, enter
mail.example.comand install. A TLS certificate is issued automatically. - Add your domain, create a mailbox, then click Generate DKIM key.
- Add the DNS records SelfDeploy shows: MX, SPF, DKIM and DMARC.
Use any mail client (IMAP 993, SMTP 587/465) or deploy Roundcube webmail in one click. Apps send mail through smtp://selfdeploy-mail:25 with no credentials needed.
Many cloud providers block outbound port 25 by default. Ask them to unblock it, or relay through an SMTP provider.
Under Servers, copy SelfDeploy's SSH public key into ~/.ssh/authorized_keys on the remote server (Docker must be installed there), then add the server by IP. Apps, databases and services can then be deployed to it. Builds, logs and backups work the same as locally.
Create a token under Settings β API tokens, then:
# Deploy an app (e.g. from GitHub Actions)
curl -X POST -H "Authorization: Bearer $SELFDEPLOY_TOKEN" https://deploy.example.com/api/apps/1/deploy
# List apps
curl -H "Authorization: Bearer $SELFDEPLOY_TOKEN" https://deploy.example.com/api/appsMain endpoints: /api/projects, /api/apps, /api/apps/{id}/deploy|stop|start|restart|logs|env|deployments, /api/deployments/{id}/rollback, /api/databases, /api/databases/{id}/backup, /api/services, /api/templates, /api/mail, /api/servers, /api/notifications.
| Variable | Default | Description |
|---|---|---|
SELFDEPLOY_DATA |
/data/selfdeploy |
Database, builds, backups and SSH keys |
SELFDEPLOY_ADDR |
:8000 |
Dashboard listen address |
SELFDEPLOY_PUBLIC_IP |
auto-detected | Public IP used for sslip.io domains and DNS instructions |
SELFDEPLOY_BUILD_WORKERS |
2 |
Parallel builds |
Forgot your password? Run docker exec selfdeploy selfdeploy reset-password you@example.com.
βββββββββββββββββ your server ββββββββββββββββββ
git push βββΊβ SelfDeploy (Go, SQLite, dashboard) β
β ββ git clone β docker build / nixpacks β
β ββ docker run (new) β health check β swap β
β ββ docker CLI (local or over SSH) β
browser ββββΊβ Traefik :80/:443 ββ Let's Encrypt βββΊ apps β
mail βββββββΊβ docker-mailserver :25/:587/:993 β
βββββββββββββββββββββββββββββββββββββββββββββββββ
SelfDeploy drives Docker through the Docker CLI, so remote servers only need Docker and SSH. Traefik routes domains to containers using labels and handles certificates. All state lives in one SQLite file in /data/selfdeploy.
go test ./...
go run ./cmd/selfdeploy # needs Docker; dashboard on http://localhost:8000The dashboard is plain HTML/CSS/JS in web/static, embedded into the binary. There's no Node build step.
- Web terminal for containers
- Scheduled tasks (cron jobs) for apps
- GitHub App integration (repo picker, commit statuses)
- Docker Swarm / multi-node scaling
- Restore backups from S3
Contributions are welcome. Open an issue or a pull request.
Is SelfDeploy free? Yes. It is open source under the MIT license. You only pay for your server.
How is it different from Heroku, Vercel, Netlify or Render? It runs on a server you control, so there are no per-app fees or usage limits, and your code and data stay with you.
How does it compare to Coolify, Dokku or CapRover? Same idea, with a focus on being small: one Go binary, SQLite, no Node build step and about 20 MB of RAM, with a mail server and S3 backups included.
What server do I need? Ubuntu or Debian with 1 GB of RAM (2 GB+ recommended) and ports 80/443 open. The installer installs Docker if needed.
Does SSL work with my own domain? Yes. Every domain gets a free Let's Encrypt certificate that renews automatically. Temporary sslip.io URLs are served over plain HTTP because Let's Encrypt rate limits those shared domains.
Do wildcard domains get a wildcard certificate? No. Each app subdomain gets its own certificate via HTTP-01, so no DNS API keys are needed.
SelfDeploy is MIT licensed: you can use it for personal and commercial projects, modify it and redistribute it.
SelfDeploy does not bundle third-party apps. It pulls their official Docker images on your server when you use them, and each keeps its own license, including Traefik (MIT), docker-mailserver (MIT), Nixpacks (MIT) and the one-click apps. Most are permissive or copyleft (GPL/AGPL) and fine for running your own apps. A few are source-available, for example n8n (Sustainable Use License), MongoDB (SSPL) and recent Redis versions, and restrict offering them as a hosted service to others. Check those licenses if you resell hosting.
Keywords: self-hosted PaaS, open source Heroku alternative, Vercel alternative, Netlify alternative, Coolify alternative, Dokku alternative, git push deploy, auto deploy from GitHub, docker deployment platform, self-hosted email server, SMTP server custom domain, free SSL Let's Encrypt, VPS control panel.