Push to any VM you own.
Free SSL included.
One CLI command deploys Docker containers or 14 source-code stacks (FastAPI, Next.js, Django, Rails, Go, Rust…) to any VM via SSH. Let's Encrypt cert issued automatically. Blue-green swap with one-command rollback. No vendor lock-in.
The Heroku workflow you can't have on Heroku anymore
`git push heroku main` and an HTTPS URL — that was the easiest deploy story ever shipped. Then the free tier died, then the company entered sustaining mode. The workflow is what survived. vxcloud rebuilds it on top of any VM you already own.
The PaaS comfort — push code, get HTTPS, ignore servers — has migrated to Vercel, Render, Railway, and Fly over the past five years. Each of them is excellent inside its own walled garden. None of them runs on a VM you control. That means: you can't SSH in. You pay 5-10× the raw cloud cost at scale. You can't run the runtime you actually want. And if the platform ever raises prices or sunsets a region, you re-deploy from scratch on something else.
vxcloud's answer is unglamorous: keep the PaaS-style CLI workflow, but target a regular Linux VM over SSH. The VM can be on AWS, GCP, Azure, Alibaba, Linode, a bare-metal box at Hetzner, or your home lab. The deploy command is the same. The SSL automation is the same. The rollback is the same. You pay your own cloud bill and you keep root.
One command, full lifecycle
Build → push → run → health-check → SSL → rollback. Every step is either default-on or one flag away.
Bring your own VM
Works against any SSH-reachable VM. AWS, GCP, Azure, Alibaba, Linode, Hetzner, OVH, DigitalOcean, your home lab — same flag set.
14 source-code stacks
FastAPI, Django, Flask, Node, Express, React, Next.js, Angular, Vue, Go, Rust, C++, PHP, Laravel, Static + Docker container. Hand-tuned Dockerfile per stack.
Let's Encrypt, automatic
`--enable-ssl --domain X --ssl-email Y` triggers HTTP-01 validation + cert install. Renews on cron. nginx for containers, Traefik for stacks.
Vault-managed keys
Upload your SSH PEM to workspace Vault once; reference it by name in every deploy. Per-keypair RBAC. Rotate without touching deploy scripts.
Blue-green + rollback
Container deploys swap nginx upstream after the new image health-checks. Rollback in one command. Stack deploys hot-reload Traefik.
CI/CD integrated
Webhook your CI to `vxcli deploy` — same command, same output, same audit log. GitHub Actions, GitLab CI, Jenkins, Circle, Drone all wire in.
What it actually looks like
vxcli deploy container \
--image grafana/grafana:latest \
--name grafana \
--ports 3000:3000 \
--env GF_SECURITY_ADMIN_PASSWORD=changeme \
--enable-ssl \
--domain grafana.example.com \
--ssl-email [email protected] \
--host 13.216.243.13 \
--ssh-user ubuntu \
--key-pair-name AWSPRODKEY1
# Done. https://grafana.example.com serves Grafana with a valid cert.vxcli deploy fastapi \
--source-dir ./ \
--app-name studio-backend \
--entry app.app:app \
--requirements requirements.txt \
--app-port 8000 \
--http-port 80 \
--enable-ssl \
--domain api.example.com \
--ssl-email [email protected] \
--host 98.81.167.101 \
--ssh-user ubuntu \
--key-pair-name AWSPRODKEY1import vxsdk
c = vxsdk.Client.load_from_vxcli()
sess = c.deploy.fastapi(
source_dir="./",
app_name="studio-backend",
entry="app.app:app",
requirements="requirements.txt",
app_port="8000", http_port="80",
enable_ssl=True,
domain="api.example.com",
ssl_email="[email protected]",
host="98.81.167.101", ssh_user="ubuntu",
key_pair_name="AWSPRODKEY1",
)
print(sess["session_id"], sess.get("access_url"))# After deploy: manage from anywhere
vxcli services list --host h --ssh-user ubuntu --key-pair-name AWSPRODKEY1
vxcli services status studio-backend --host h --ssh-user ubuntu --key-pair-name AWSPRODKEY1
vxcli services restart studio-backend --host h --ssh-user ubuntu --key-pair-name AWSPRODKEY1
vxcli services logs ollama --tail 200 --host h --ssh-user ubuntu --key-pair-name AWSPRODKEY1
# Host-level — disk + docker cleanup in one command
vxcli services vm disk-cleanup --host h --ssh-user ubuntu --key-pair-name AWSPRODKEY1
vxcli services vm docker-cleanup --host h --ssh-user ubuntu --key-pair-name AWSPRODKEY1When SSH deploy automation is the right answer
- You want the Heroku/Vercel deploy workflow on infrastructure you actually own.
- Your monthly compute bill on a managed PaaS would be >$300/mo — raw cloud VMs are 3-10× cheaper at this point.
- You need SSH access for debugging, custom runtimes, or installing system-level dependencies.
- You run stateful workloads (Postgres, Redis, queues) that managed PaaS providers either don't support or upcharge heavily for.
- You want one deploy script that works against five clouds, bare-metal, and your home lab.
- You're migrating off Heroku, Vercel, or Render and want to preserve the `git push` workflow without rewriting your deploy pipeline.
- Your security team needs to control the VM image, the OS patches, and the network policy directly.
vxcloud vs Coolify vs Dokku vs CapRover vs Heroku
The self-host PaaS space is healthy. The trade-offs cluster around managed-vs-self-host and single-stack-vs-multi-stack.
| Feature | vxcloud | Coolify | Dokku | CapRover |
|---|---|---|---|---|
| Deploy target | Any SSH VM (5 clouds + BYO) | Servers you connect to a Coolify install | Single Dokku server | Single CapRover server |
| Setup cost | Zero — managed control plane | Self-host Coolify first | Self-host Dokku first | Self-host CapRover first |
| Source-code stacks | 14 — Python/Node/Go/Rust/PHP/... | Generic (Nixpacks) | Buildpack-based | Generic templates |
| Let's Encrypt SSL | Built-in, one flag | Built-in | Plugin | Built-in |
| Multi-cloud provisioning | Yes — 5 clouds | Bring-your-own VMs | Bring-your-own VMs | Bring-your-own VMs |
| AI agents for deploy ops | Yes — VxAI + AgentControl | No | No | No |
| Three SDKs (Python / TS / Go) | Yes | No | No | No |
| Terraform provider | Yes | No | No | No |
SSH Deploy Automation FAQ
Deploy your next app to a VM you actually own
Free tier includes 50 deploys per month and the full SSL automation. No credit card to start.