Back to writing
Originally published on Dev.toView canonical on Dev.to

Install a Self-Hosted PaaS on a $5 VPS in Five Minutes (Levelrail)

Install a Self-Hosted PaaS on a $5 VPS in Five Minutes (Levelrail) You have a fresh Linux...

6 min read

Install a Self-Hosted PaaS on a $5 VPS in Five Minutes (Levelrail)

You have a fresh Linux server and an app you would rather not pay Vercel or Heroku to run. This post gets a deployment platform onto that server and a first app live on it. No Kubernetes, no YAML maze.

The platform is Levelrail, a self-hosted platform I am building. It is in beta with no stable release yet, and I will flag where that matters.

http://levelrail.com/

TL;DR

Step What you do Time
1 Check the server meets the basics 1 min
2 Run the install command 2 min
3 Open the dashboard with your setup token 30 sec
4 Deploy the sample app from the wizard 1 min
5 Point a domain at it for HTTPS your DNS speed

Pick your path

Levelrail ships three ways. Most people want the first one.

Path Pick it when Command lives in
install.sh You have a real server and want it running as a service this post
Docker Everything else on the box already runs as containers the Docker page in the docs
Build from source You are hacking on Levelrail or testing an unreleased commit the getting started page

What you need first

The server needs Linux on amd64 or arm64 with systemd. CI tests the install script on Ubuntu 24.04 and Debian 12. Other distros should work, but nobody has tested them.

It also needs root, curl, and ports 80 and 443 open to the internet. Port 80 matters because Let's Encrypt uses it to prove you own the domain.

For size, 1 vCPU, 1 GB of RAM and 10 GB of disk is enough to boot it. Your apps and builds need room on top, so 2 vCPU and 2 GB is more comfortable. The installer warns under 1 GB of RAM and stops under 10 GB of free disk.

Step 1: run the installer

curl -fsSL https://levelrail.com/install.sh | sudo sh

Here is what it does, in order:

preflight checks  ->  install Docker if missing  ->  download release
      ->  verify SHA-256  ->  write systemd unit  ->  wait for /healthz
      ->  test ports 80/443  ->  print URLs and setup token

It checks your OS, architecture, Docker version, RAM, disk and ports before touching anything. If a check fails, it stops and tells you why. You can push past a failed check with --force, though I would read the message first.

The script checks the binary's SHA-256 before it installs. If cosign is on the machine and the release ships a signature, it verifies that too.

Beta note: with no stable release yet, the script installs the newest pre-release. Pin one yourself with LEVELRAIL_VERSION, or pick a channel with LEVELRAIL_CHANNEL=stable or beta.

Checkpoint: the script ends by printing dashboard links and a one-time setup token. Keep that terminal open.

Ports 80 and 443 are the only ones the installer will never move on its own. Let's Encrypt only talks to those two. If something else already holds them, such as an old reverse proxy or another Coolify or Dokploy instance, preflight fails and tells you what to change.

The dashboard port is different. The default is 8080. If something else holds it, the installer picks the next free port and prints the real number. Use the port from your own output, not the one in this post.

Step 2: sign in with the setup token

Open the link the installer printed. It has your server's IP, the dashboard port and the token:

SERVER_IP:8080/login?setup=TOKEN

Type it into the browser with the plain HTTP scheme in front.

The token lets you create the first admin account. If you lost the terminal output, print the token again on the server:

sudo APP_DATA_DIR=/var/lib/levelrail-data levelrail setup-token

You will see a "connection is not encrypted" banner. Expect it. You stay on plain HTTP until you give the dashboard a domain in step 4.

Back up master.key in the data directory now. It protects your stored secrets, and the installer reminds you for a reason.

Step 3: let the setup wizard do the first deploy

On a fresh instance, the dashboard opens a setup wizard instead of an empty list. It walks five stages.

Stage What happens
Server check Runs the same checks as levelrail-cli doctor. A failing check shows a copyable fix command.
Dashboard domain Optional. Shows the exact DNS record to create, then watches DNS and the certificate.
Git provider Optional. Links to each provider's connect flow.
First app Deploys a sample, a template, or your own repo, and waits for a healthy status.
Done Summarizes what you set up.

Pick the sample app. It runs nginx:alpine with a health check, so it works on any server with no repo needed. The wizard waits for the readiness probe before it calls the deploy healthy. If something breaks, it shows a diagnosis and a link to the logs.

Checkpoint: the sample app shows a healthy status in the dashboard.

Step 4: put a domain on the dashboard

Use a subdomain made for the dashboard, like console.example.com. Do not reuse a domain an app already serves. One of the two will lose the conflict, silently.

In the wizard, enter the domain and an email for certificate notices. Create the A record it shows you, wait for the green checks, and the dashboard moves to HTTPS. Once you save an HTTPS dashboard URL, the server refuses plain HTTP sign-in.

Warning: if the HTTPS URL breaks later and locks you out, set APP_ALLOW_INSECURE_LOGIN=true with sudo systemctl edit levelrail, then restart the service.

Step 5: deploy your own app from the CLI

The app spec is one small file in your repo, app.yaml:

version: 1
services:
  web:
    build:
      type: dockerfile
    port: 8080

Set your repo and the registry path for the built image, then create and deploy with the CLI:

REPO_URL=your-git-repo-url
IMAGE_REPO=your-registry-path

levelrail-cli apps create \
  --name your-app \
  --file app.yaml \
  --repo "$REPO_URL" \
  --image-repo "$IMAGE_REPO"

Check on it with levelrail-cli apps status your-app. Tail logs with levelrail-cli apps logs your-app -f. If a deploy goes wrong, levelrail-cli apps rollback your-app returns to the previous version.

Not sure what the spec needs? Run levelrail-cli apps create --interactive and answer the prompts. Or paste a repo URL, a docker run command or a compose file into the "Import anything" box in the dashboard and read the plan before it creates anything.

What you get on day one, free

Levelrail has one edition under Apache 2.0, with no license key. The binary you just installed includes sign-in with Google, GitHub, Microsoft or any OIDC provider, TOTP two-factor and passkeys, IAM policies, an audit log you can export as CSV, scheduled backups with verification, and deploy approvals.

It does not include SAML or SCIM. If you need either, Levelrail is not ready for you yet.

Levelrail App

What I would check before trusting it

Levelrail is beta. It has fewer users and less production time than the platforms it competes with. TLS defaults to an internal issuer, and the public Let's Encrypt path has had less field testing than the rest of the ingress. It runs only on Linux.

But we are working to get it to first stable launch soon getting it ready for production and capture benchmarks !!

Remove it cleanly

One command removes the service, the unit file and the binary, and keeps your data directory:

curl -fsSL https://levelrail.com/install.sh | sudo sh -s uninstall

Add --purge to delete the data directory too. That wipes app and deploy state and the master key, so every stored secret becomes unreadable. Containers, images and volumes your apps created stay behind until you remove them yourself.

What would make you move a side project off a managed host: price, control, or just curiosity? Tell me in the comments, and tell me what broke if the install stumbled.

Try it, and tell me what breaks

Levelrail is open source under Apache 2.0. It is young, so every bug report changes what gets built next.

glincker/levelrail

If this post saved you time, a star on the repo helps other self-hosters find it.


GDS K S · thegdsks.com · building Glincker · follow on X @thegdsks

Five minutes to a running platform is only useful if the next five minutes keep it running.

This article was syndicated from Dev.to. The canonical copy lives at https://dev.to/thegdsks/install-a-self-hosted-paas-on-a-5-vps-in-five-minutes-levelrail-3f8j.
Contact