Self-Hosted Deployment
Deploy runpiper on your own infrastructure using Docker.
Prerequisites
Before you begin, make sure you have:
-
Docker installed and running
Check if Docker is running:
docker ps -
PostgreSQL database
runpiper uses PostgreSQL for data persistence.
Quick Start
The fastest way to run a self-hosted instance:
# 1. Clone the repository
git clone https://codeberg.org/runpiper/runpiper.git
cd runpiper
# 2. Start PostgreSQL
docker compose up -d db
# 3. Create configuration
cp config.toml.example config.toml
# Edit config.toml to set DATABASE_URL
# 4. Create environment file
cp .env.example .env
# Edit .env to set required variables
# 5. Run runpiper
docker run -p 8080:8080 \
-v ./config.toml:/app/config.toml \
--env-file .env \
codeberg.org/runpiper/runpiper:latest
# 6. Bootstrap the instance (in another terminal)
rp init
Configuration
config.toml
Create a configuration file from the example:
cp config.toml.example config.toml
Edit the file to configure your instance:
# Database connection (use environment variable)
database_url = "env:DATABASE_URL"
# Server settings
[server]
host = "0.0.0.0"
port = 8080
# Admin key (use environment variable)
admin_key = "env:runpiper_ADMIN_KEY"
.env
Create an environment file:
cp .env.example .env
Set the required variables:
# Database connection
DATABASE_URL=postgresql://runpiper:runpiper@host.docker.internal:5432/runpiper
# Admin key for bootstrapping
runpiper_ADMIN_KEY=your-secret-admin-key-here
# Config file path
runpiper_CONFIG=/app/config.toml
Running with Docker
Using Docker Compose (Database)
Start the PostgreSQL database:
docker compose up -d db
Wait a few seconds for the database to be ready.
Using Docker Run (Application)
Verify config file exists and is a file (not a directory):
ls -la config.toml
# Should show: -rw-r--r-- ... config.toml
# NOT: drwxr-xr-x ... config.toml
If it’s a directory, remove it first:
rm -rf config.toml && cp config.toml.example config.toml
Run the container:
docker run -p 8080:8080 \
-v ./config.toml:/app/config.toml \
--env-file .env \
codeberg.org/runpiper/runpiper:latest
Your runpiper instance will be available at http://localhost:8080.
Docker Network Configuration
By default, the setup uses host.docker.internal to connect to the database. If you’re running both containers in the same Docker network:
-
Update
DATABASE_URLin.env:DATABASE_URL=postgresql://runpiper:runpiper@runpiper-db:5432/runpiper -
Add
--network <network-name>to the docker run command.
Bootstrapping Your Instance
After your server is running, you need to bootstrap it to create the first admin user.
1. Set the Admin Key
Make sure runpiper_ADMIN_KEY is set in your .env file or exported:
export runpiper_ADMIN_KEY=your-secret-admin-key-here
2. Bootstrap the Instance
rp init
You’ll be prompted for:
- Admin key (the
runpiper_ADMIN_KEYfrom your config) - Server endpoint (e.g.,
http://localhost:8080) - Admin email address
- Organization name
3. Create Invite Codes
After bootstrapping, you’ll be automatically logged in. Create invite codes for other users:
rp invite create user@example.com
rp invite create user2@example.com --expires-days 30
Users can redeem invite codes by running:
rp auth login
and entering their invite code.
Managing Your Instance
Start the Server
rp serve
Create Users
As the admin, create invite codes:
rp invite create user@example.com
List all invite codes:
rp invite list
Revoke an invite:
rp invite revoke user@example.com
Production Deployment
Security Considerations
-
Use strong admin keys
runpiper_ADMIN_KEY=$(openssl rand -hex 32) -
Use environment variables for secrets
- Never hardcode credentials in config.toml
- Use
.envfiles that are not committed to git
-
Enable HTTPS
- Use a reverse proxy like nginx or Caddy
- Obtain SSL certificates via Let’s Encrypt
-
Database security
- Use strong database passwords
- Restrict database access to the application only
-
Firewall rules
- Only expose necessary ports
- Use a VPN or bastion host for admin access
Reverse Proxy Example (nginx)
server {
listen 443 ssl http2;
server_name runpiper.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/runpiper.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/runpiper.yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Monitoring
Consider adding:
- Logs - Configure logging to a file or centralized service
- Metrics - Add Prometheus metrics export
- Health checks - Implement
/healthendpoint monitoring
Troubleshooting
“Cannot connect to the Docker daemon”
Start Docker Desktop or your Docker service.
“Config read error: No such file or directory”
If config.toml doesn’t exist:
cp config.toml.example config.toml
If config.toml is a directory:
ls -la config.toml
# If it shows drwxr-xr-x:
rm -rf config.toml
cp config.toml.example config.toml
“database connection failed: error with configuration: relative URL without a base”
The DATABASE_URL environment variable is not set or is empty:
- Start the database first:
docker compose up -d db - Set
DATABASE_URLin your.envfile - Use
--env-file .envin your Docker command
“admin_key not configured”
The server needs the runpiper_ADMIN_KEY environment variable set:
- Set it in your
.envfile - Use
--env-file .envin your Docker command - When running with
rp serve, export it:export runpiper_ADMIN_KEY=your-secret-key
“Can’t login locally without an invite code”
You need to bootstrap the instance first with rp init. This creates the first admin user without requiring an invite code.
Database connection issues
If the application can’t connect to the database:
- Check the database is running:
docker compose ps db - Check database logs:
docker compose logs db - Verify
DATABASE_URLmatches database credentials - For Docker networking, ensure both containers are on the same network
Next Steps
- Tasks: Learn about tasks
- Capabilities: Configure external integrations
- CLI Reference: Complete CLI command documentation