rivet

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 Dockerfile in 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:

  1. New or existing project — choose new for your first deploy
  2. Name — a label for the project (e.g. api)
  3. Domain — the public URL for this app (e.g. api.example.com)
  4. Port — the port your container listens on (e.g. 3000)
  5. 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. Ship api.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.