Deploy to your VPS in six steps
Rivet turns a plain Linux VPS into a self-hosted PaaS. Install the control plane once, then ship any app that has a Dockerfile — from your laptop, with one command.
- → A Linux VPS with Docker Engine installed
-
→
A domain for the Rivet console (e.g.
rivet.example.com) pointed at the VPS with ports 80 and 443 open. App domains you ship later use the same VPS IP — see Step 6. -
→
An app with a
Dockerfilein its project root - → Your local machine needs Docker too — the CLI builds the image before uploading it
Prepare your VPS
Rivet runs on the server through Docker. Install Docker Engine on your VPS if you haven't already — Rivet does not install it for you.
Follow the official guide for your distro: docs.docker.com/engine/install. Then confirm it works:
docker run hello-world
Point your Rivet domain's DNS A record at the VPS IP. Rivet uses Caddy to provision HTTPS automatically once the install finishes.
Install the Rivet control plane
SSH into your VPS and run the installer. It pulls three containers — Caddy (routing + SSL), the Rivet API server, and the web console — and wires them together on a shared Docker network.
Interactive install (the script will prompt for your domain and secret key):
curl -fsSL https://getrivet.app/install.sh | sh
Or pass everything up front for a non-interactive install:
curl -fsSL https://getrivet.app/install.sh | \
RIVET_DOMAIN=rivet.example.com \
RIVET_SECRET_KEY=$(openssl rand -hex 32) \
RIVET_INTERACTIVE=0 \
sh
When it finishes, open
https://rivet.example.com — you should see the Rivet
console. The secret key encrypts project secrets at rest; store it somewhere safe.
Install the Rivet CLI
The CLI runs on your laptop (or CI machine). It signs you in, builds your Docker image locally, uploads it to your Rivet server, and triggers a deploy.
Option A — download a release
Grab the latest binary for your OS from
GitHub Releases, rename it to rivet, and put it on your
PATH.
Option B — build from source
Requires Go 1.25+:
git clone https://github.com/devmin8/rivet.git
cd rivet
go build -o rivet ./cmd/rivetctl
sudo mv rivet /usr/local/bin/
Point the CLI at your Rivet server:
export RIVET_SERVER_URL=https://rivet.example.com
Add that line to your shell profile so you don't have to set it every session.
Create an account and sign in
The first user you create becomes the admin. You can sign up from the web console or the CLI — pick whichever is easier.
From the CLI
rivet signup
# Username, email, password — then you're signed in automatically
rivet signin
# Use this on later sessions
Your session is saved locally. Once signed in, you're ready to deploy.
Add a Dockerfile to your app
Rivet builds and runs your app from a
Dockerfile in the project directory. When you ship,
the CLI runs docker build locally, uploads the
image, and Rivet starts the container on your VPS.
A minimal example for a Node app:
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Make sure the port you expose matches the port you'll tell Rivet when creating the project. Rivet routes HTTPS traffic to that container port.
Ship your app
From your app directory, run:
cd my-app
rivet ship
The CLI walks you through a short setup:
-
New or existing project
— choose
newfor your first deploy -
Name — a label
for the project (e.g.
api) -
Domain — the
public URL for this app (e.g.
api.example.com) -
Port — the
port your container listens on (e.g.
3000) - Auto sleep — optional idle timeout in seconds (minimum 60). Leave empty to keep the container always running.
Point the domain at your VPS
Rivet routes traffic by hostname on the same VPS where the control plane runs. The domain you enter must resolve to that server's IP — the same way your Rivet console domain does. Once DNS is in place, Caddy provisions HTTPS and sends requests to your container.
Pick whichever fits your setup:
-
→
Wildcard
— one record for all subdomains:
*.example.com→ A → your VPS IP. Shipapi.example.com,staging.example.com, and so on without touching DNS again. -
→
Per-app record
— add an A record for each domain:
api.example.com→ A → your VPS IP.
Then Rivet builds the image, uploads it, and deploys. When it's done, your app is live at the domain you chose — with HTTPS handled automatically.
Deploying again to the same project? Run
rivet ship, choose
existing, and enter the project ID.
On an ARM VPS, pass the target platform:
rivet ship --platform linux/arm64
Environment variables
If your project has a .env file, Rivet imports it
automatically during rivet ship before deploy. Add
.env to .dockerignore
so Docker does not copy those values into your image.
DATABASE_URL=postgres://localhost/mydb
RIVET_SECRET_API_KEY=sk_live_abc123
Regular keys become plain env vars. Keys prefixed with
RIVET_SECRET_ are stored encrypted — the prefix is
stripped before injection. You can also manage env vars and secrets from the web
console at any time.
What's next
Open the Rivet console at your server domain to monitor CPU, memory, and network for each project. Start, stop, redeploy, and edit env vars from the dashboard — or keep using the CLI.