This guide describes how to self-host Stellarbridge on a bare-metal or VM Linux server by running the application binary directly, with PostgreSQL, Redis, and S3-compatible storage installed and managed separately.
Choosing an OS
We recommend Alpine Linux for bare-metal self-hosting when possible. Alpine provides a minimal base (musl libc, BusyBox, small package set), which significantly reduces attack surface and patch burden. The steps below include Alpine-specific commands; the same workflow applies on Ubuntu, Debian, or RHEL with the alternative package commands shown.
Prerequisites
- OS: Alpine Linux 3.19+ (recommended for minimal attack surface), or Ubuntu 22.04 LTS, Debian 12, RHEL 9
- Resources: Minimum 2 GB RAM, 2 CPU cores; 4 GB RAM recommended for production
- Port: 8080 (or another port you configure) for the application
- Root or sudo: To install system packages, create a service user, and optionally configure a reverse proxy
Architecture Overview
On bare metal you run:
- Stellarbridge binary: Single process (Go application) listening on HTTP (e.g. port 8080)
- PostgreSQL: Installed and run on the same host or a dedicated server
- Redis: Installed and run on the same host or a dedicated server
- S3-compatible storage: MinIO on the host, or a remote S3/MinIO endpoint
- Reverse proxy (recommended): Caddy in front of the app for TLS and static assets (Nginx is an alternative)
- Process manager: systemd to keep the app running and restart on failure
Step 1: Install Dependencies
PostgreSQL 16
Alpine (recommended):
sudo apk add postgresql16 postgresql16-client
sudo mkdir -p /var/lib/postgresql/data
sudo chown postgres:postgres /var/lib/postgresql/data
sudo -u postgres initdb -D /var/lib/postgresql/data
# Start PostgreSQL (OpenRC): sudo rc-service postgresql start && sudo rc-update add postgresql
# Or with systemd (if installed): sudo systemctl enable postgresql && sudo systemctl start postgresql
sudo -u postgres psql -c "CREATE USER stellarbridge WITH PASSWORD 'STRONG_PASSWORD';"
sudo -u postgres psql -c "CREATE DATABASE stellarbridge OWNER stellarbridge;"
sudo -u postgres psql -d stellarbridge -c 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE EXTENSION IF NOT EXISTS "pgcrypto";'Ubuntu/Debian:
sudo apt update && sudo apt install -y postgresql-16 postgresql-client-16
sudo -u postgres psql -c "CREATE USER stellarbridge WITH PASSWORD 'STRONG_PASSWORD';"
sudo -u postgres psql -c "CREATE DATABASE stellarbridge OWNER stellarbridge;"
sudo -u postgres psql -d stellarbridge -c 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE EXTENSION IF NOT EXISTS "pgcrypto";'Use a strong password and restrict network access (e.g. pg_hba.conf) in production.
Redis 7
Alpine (recommended):
sudo apk add redis
sudo rc-service redis start && sudo rc-update add redis
# Or with systemd: sudo systemctl enable redis && sudo systemctl start redisUbuntu/Debian:
sudo apt install -y redis-server
sudo systemctl enable redis-server
sudo systemctl start redis-serverIf Redis is on another host, use its URL in the app configuration and ensure firewall rules allow access.
S3-compatible storage
Option A – MinIO on the same host:
# Alpine: install wget if needed: sudo apk add wget
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/
sudo adduser -D -H minio-user 2>/dev/null || true # Alpine: adduser; others: useradd -r minio-user
sudo mkdir -p /var/minio/data
sudo chown -R minio-user:minio-user /var/minioRun MinIO as a systemd or OpenRC service (not shown in full here) and create buckets (e.g. local-stllr-dev-1, coc-reports) using the MinIO client mc or the MinIO console. On Alpine, mc is available from the community repo: sudo apk add mc.
Option B – Remote S3 or MinIO: Use your existing endpoint and credentials; no local MinIO install required.
Step 2: Install the Stellarbridge Binary
Use the binary or package provided for self-hosting. Typical options:
From a tarball (Alpine and most Linux):
# Alpine may need: sudo apk add tar gzip
sudo tar -C /usr/local/bin -xzf stellarbridge-Linux-x86_64.tar.gz
sudo chmod +x /usr/local/bin/stllrUse the linux-amd64 or linux-arm64 tarball that matches your host. On Alpine, the static-linked Linux binary is the right choice.
From a .deb or .rpm: On Debian/Ubuntu or RHEL-based systems, install with dpkg -i or rpm -i as appropriate.
Build from source (only if you have the source and build instructions):
cd stellarbridge-app
CGO_ENABLED=0 go build -o stllr -ldflags "-w -s -X stellarbridge/config.Version=$(git describe --tags)" cmd/api/main.go
sudo mv stllr /usr/local/bin/Confirm the binary runs and prints version or usage:
/usr/local/bin/stllr --version
# or
/usr/local/bin/stllr -hStep 3: Configure Environment Variables
The application reads configuration from the environment and optionally from a vars.env file in the current working directory. Create a dedicated config directory and env file:
sudo mkdir -p /etc/stellarbridge
sudo touch /etc/stellarbridge/vars.env
sudo chmod 600 /etc/stellarbridge/vars.envAdd at least the following (replace placeholders with your values):
# /etc/stellarbridge/vars.env
# App
STLLR_PORT=8080
STLLR_APP_ENV=production
STLLR_DOMAIN=https://files.yourcompany.com
STLLR_SUPPORT_EMAIL=support@yourcompany.com
# Database
STLLR_DB_HOST=localhost
STLLR_DB_PORT=5432
STLLR_DB_USERNAME=stellarbridge
STLLR_DB_PASSWORD=STRONG_PASSWORD
STLLR_DB_DATABASE=stellarbridge
STLLR_DB_SCHEMA=public
STLLR_POSTGRES_CONN_STRING=postgresql://stellarbridge:STRONG_PASSWORD@localhost:5432/stellarbridge?sslmode=disable
STLLR_DB_SSL_MODE=false
# Redis
STLLR_REDIS_CONN_STRING=redis://localhost:6379
# S3-compatible storage (MinIO example)
STLLR_AWS_ACCESS_KEY_ID=minioadmin
STLLR_AWS_SECRET_ACCESS_KEY=STRONG_MINIO_PASSWORD
STLLR_AWS_ENDPOINT_URL_S3=http://localhost:9000
STLLR_AWS_ENDPOINT_URL_S3_PUBLIC=https://files.yourcompany.com/minio
STLLR_AWS_REGION=us-east-1
# Secrets (generate strong random values)
STLLR_COOKIE_SECRET=GENERATE_32_BYTES_BASE64
STLLR_JWT_HMAC_SECRET=GENERATE_STRONG_SECRETGenerate secrets, for example:
openssl rand -base64 32 # for STLLR_COOKIE_SECRET
openssl rand -hex 32 # for STLLR_JWT_HMAC_SECRETIf you use Auth0/OIDC for sign-in, add the relevant STLLR_AUTH0_* and STLLR_* OIDC variables as documented for your deployment. For licensed or air-gapped self-hosted, you may set STLLR_SKIP_SUBSCRIPTION_CHECK=true and/or STLLR_IS_ENTERPRISE=true as per your agreement.
Step 4: Database Migrations
The application typically runs schema migrations on startup. If your distribution provides a separate migration command, run it once before starting the app; otherwise start the app once and check logs to confirm migrations completed. Ensure the database user has rights to create and alter schema objects.
Step 5: Create a Service User and systemd Unit
Run the app under a dedicated user:
# Alpine
sudo adduser -D -H -s /sbin/nologin stellarbridge
# Ubuntu/Debian/RHEL
sudo useradd -r -s /bin/false stellarbridge
sudo chown -R stellarbridge:stellarbridge /etc/stellarbridgeCreate a systemd unit so the app starts on boot and restarts on failure (on Alpine, install systemd if you prefer it: apk add systemd; otherwise use an OpenRC runscript or a process manager like s6):
# /etc/systemd/system/stellarbridge.service
[Unit]
Description=Stellarbridge Application
After=network.target postgresql.service redis-server.service
Wants=postgresql.service redis-server.service
[Service]
Type=simple
User=stellarbridge
Group=stellarbridge
WorkingDirectory=/etc/stellarbridge
EnvironmentFile=/etc/stellarbridge/vars.env
ExecStart=/usr/local/bin/stllr
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetIf the binary name is different (e.g. stllr), adjust ExecStart. If you use a vars.env in another path, point EnvironmentFile and WorkingDirectory there. Reload and start:
# systemd
sudo systemctl daemon-reload
sudo systemctl enable stellarbridge
sudo systemctl start stellarbridge
sudo systemctl status stellarbridgeOn Alpine with OpenRC, create /etc/init.d/stellarbridge (or use a supervised runscript) that runs /usr/local/bin/stllr with EnvironmentFile=/etc/stellarbridge/vars.env and add it to the default runlevel: rc-update add stellarbridge.
Step 6: Reverse Proxy and TLS (Recommended)
Expose the app over HTTPS using Caddy (recommended; automatic TLS with Let’s Encrypt). On Alpine, install Caddy from the community repo (apk add caddy) or download the official binary.
files.yourcompany.com {
reverse_proxy localhost:8080
}Caddy obtains and renews certificates automatically. Reload Caddy after changing the config (systemctl reload caddy, rc-service caddy reload, or caddy reload --config /etc/caddy/Caddyfile). If you use Nginx instead, configure TLS (e.g. with certbot) and proxy to http://127.0.0.1:8080 with Host, X-Real-IP, X-Forwarded-For, and X-Forwarded-Proto headers set.
Ensure STLLR_DOMAIN matches the public URL (e.g. https://files.yourcompany.com).
Step 7: Verify Deployment
- Service:
systemctl status stellarbridgeshould showactive (running). - Logs:
journalctl -u stellarbridge -fshould show no database, Redis, or S3 connection errors. - Local HTTP:
curl -I http://localhost:8080should return HTTP 200 or a redirect. - HTTPS: Open
https://files.yourcompany.comin a browser and confirm sign-in and basic usage if OIDC is configured.
Production Hardening
- Alpine: Using Alpine Linux as the host OS reduces attack surface (minimal base, fewer packages and services). Keep the base system updated with
apk upgradeand only enable services you need. - Firewall: Allow only 80/443 on the public interface; keep 8080 bound to localhost or a private IP when using a reverse proxy.
- Secrets: Restrict read access to
/etc/stellarbridge/vars.env(e.g. mode 600, user/group stellarbridge). Consider a secrets manager or vault and inject env vars into the unit or a small wrapper. - Updates: Plan binary and dependency updates; test in a staging environment and use a maintenance window if needed.
- Backups: Back up PostgreSQL and MinIO (or S3) data regularly; test restore procedures.
- Monitoring: Use systemd’s built-in restarts and consider log aggregation and health checks (e.g. HTTP GET to
/or a health path).
Troubleshooting
- App exits immediately: Check
journalctl -u stellarbridge -n 100. Common causes: missing or wrongSTLLR_POSTGRES_CONN_STRINGorSTLLR_REDIS_CONN_STRING, invalid secrets, or wrong file permissions onvars.env. - Database connection refused: Ensure PostgreSQL is running,
pg_hba.confallows the app user from the app host, and firewall allows port 5432. - Redis connection refused: Ensure Redis is running and reachable; use
redis-cli pingfrom the app host. - S3 or upload errors: Verify
STLLR_AWS_*settings and that the app can reach the S3/MinIO endpoint; if using presigned URLs, setSTLLR_AWS_ENDPOINT_URL_S3_PUBLICto the URL clients use to access the bucket.
For more on security and operations, see Security and Managing Your Organization.