Better-PaaS
Getting Started

Installation

A friendly, step-by-step guide to installing Better-PaaS on your server.

This guide walks you through installing Better-PaaS from scratch. We'll explain each step so you know what is happening and why.

Before you begin

You'll need a server to install Better-PaaS on. Almost any of these work:

  • A cloud VPS (DigitalOcean, Hetzner, Linode, AWS EC2, etc.)
  • A home server or spare computer running Linux
  • Your own Mac, for trying it out locally
RequirementRecommendation
Operating systemUbuntu 22.04+ or Debian 11+ (best supported). macOS works for local testing.
Memory (RAM)1 GB minimum, 2 GB+ comfortable
Disk20 GB+ (Docker images add up)
Accessroot or a user with sudo

Why a real server?

Better-PaaS runs your apps as Docker containers and serves them to the internet. A cloud VPS with a public IP address is what makes your apps reachable from anywhere. Local installs are great for learning, but only reachable from your own machine.

The one-command install

SSH into your server and run:

On your server
curl -fsSL https://raw.githubusercontent.com/sumon-ohid/better-paas/main/install.sh | bash

On Linux, run it as root (or with sudo):

sudo bash -c "curl -fsSL https://raw.githubusercontent.com/sumon-ohid/better-paas/main/install.sh | bash"

What the installer does

The script is fully automated. Step by step, it:

Detects your operating system and installs system packages (curl, git, build tools).

Installs Go — the language the control plane is written in.

Installs Docker — runs your apps in isolated containers.

Installs Nixpacks — auto-detects how to build your code.

Installs Caddy — the web server that routes traffic and handles HTTPS.

Installs Node.js + pnpm — needed to build the dashboard.

Builds and starts the backend and frontend as background services.

Installing from a checked-out copy

Prefer to clone the repo yourself first? That works too:

git clone https://github.com/sumon-ohid/better-paas.git
cd better-paas
bash install.sh

If you prefer to run the entire control plane as a containerized stack, you can run it via Docker Compose.

Create a docker-compose.yml file with the following contents:

docker-compose.yml
version: '3.8'

services:
  better-paas:
    image: ghcr.io/sumon-ohid/better-paas:latest
    container_name: better-paas
    # On macOS/Windows (Docker Desktop), use port mapping:
    ports:
      - "80:80"
      - "443:443"
      - "3000:3000"
      - "8080:8080"
      - "9000-9050:9000-9050" # Map a range for deployed user apps
    # On Linux VPS (Production), uncomment network_mode below and comment out ports above:
    # network_mode: host
    volumes:
      # Mount the host's Docker socket to manage containers
      - /var/run/docker.sock:/var/run/docker.sock
      # Mount local data directory to persist the SQLite database, logs, and keys
      - ./data:/app/data
      # Mount builds directory to persist cloned git repositories across runs
      - ./builds:/app/builds
    environment:
      - LISTEN_ADDR=:8080
      - FRONTEND_PORT=3000
      - TRUST_PROXY=true
      # Override the generated admin token (optional)
      # - ADMIN_TOKEN=your-custom-token
      # Secret key for at-rest SQLite database encryption (optional)
      # - BETTER_PAAS_SECRET_KEY=your-32-character-key
    extra_hosts:
      - "host.docker.internal:host-gateway"
    restart: unless-stopped

Once the file is created, pull the image and start the stack:

# Pull the latest image
docker pull ghcr.io/sumon-ohid/better-paas:latest

# Start the stack
docker compose up -d

Alternative: Run with docker run

If you prefer not to use Docker Compose, you can start the container directly using a single docker run command. Note that you must specify all port mappings, volume mounts, and environment variables:

# Pull the latest image
docker pull ghcr.io/sumon-ohid/better-paas:latest

# Start the container
docker run -d \
  --name better-paas \
  --restart unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $(pwd)/data:/app/data \
  -v $(pwd)/builds:/app/builds \
  -p 80:80 \
  -p 443:443 \
  -p 3000:3000 \
  -p 8080:8080 \
  -p 9000-9050:9000-9050 \
  -e LISTEN_ADDR=:8080 \
  -e FRONTEND_PORT=3000 \
  -e TRUST_PROXY=true \
  ghcr.io/sumon-ohid/better-paas:latest

Building manually (for developers)

If you want to run the pieces by hand — useful for contributing — build each part separately.

Backend (it's a multi-file Go package, so build the whole directory, not just main.go):

backend
cd backend
go build -o server .
./server

Frontend:

frontend
cd frontend
pnpm install
pnpm build
pnpm start

After installation

When the installer finishes it prints a summary with two important things:

  1. The dashboard URL — usually http://localhost:3000 or http://YOUR_SERVER_IP:3000.
  2. Your admin token — the secret you'll use to log in.

Keep that admin token safe. It's the only credential protecting your dashboard. You can reprint it any time with cd ~/better-paas/backend && ./server token.

How it runs in the background

On Linux, the installer registers two systemd services so Better-PaaS starts automatically on boot and restarts if it crashes:

# Check status
sudo systemctl status better-paas-backend
sudo systemctl status better-paas-frontend

# Follow the logs live
journalctl -u better-paas-backend -f

On macOS, the processes are started in the background and log to backend/server.log and frontend/frontend.log.

Next step

On this page