Installation
This guide walks you through installing Ring on your system.
Prerequisites
Ring requires:
- Docker — official installation guide
- Rust 1.85 or later (for compilation) — Ring uses edition 2024. Install via rustup.
Quick verification:
docker --version rustc --version # if compiling from source
Installing Ring
Option 1: pre-compiled binary
Pre-compiled binaries are not yet published. Compile from source for now.
Option 2: compile from source
# Clone the repository git clone https://github.com/kemeter/ring.git cd ring # Install system dependencies (Ubuntu/Debian) sudo apt update sudo apt install libssl-dev pkg-config # Install system dependencies (CentOS/RHEL) sudo yum install openssl-devel # Install system dependencies (macOS with Homebrew) brew install openssl pkg-config # Compile Ring (needs Rust 1.85+) cargo build --release # Install the binary sudo cp target/release/ring /usr/local/bin/
Option 3: Docker (development)
docker build -t ring . docker run -d \ --name ring-server \ -p 3030:3030 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $(pwd)/data:/app/data \ ring
Docker socket warning — mounting
/var/run/docker.sockgives Ring full control over the host's Docker daemon. Treat the Ring container as privileged.
Verification
ring --version docker ps
Initial setup
1. Initialize the config directory
ring init
This creates ~/.config/kemeter/ring/ (or $RING_CONFIG_DIR if set) and writes an empty auth.json. It does not create the database or seed the admin user — that happens on the first ring server start.
2. Start the server
ring server start
On first start, the server:
- Listens on
127.0.0.1:3030(configurable viaconfig.toml) - Runs SQLite migrations to create
ring.dbin the working directory (override withRING_DATABASE_PATH) - Seeds the default admin user
admin/changeme - Logs to stdout (set
RUST_LOG=infofor visibility)
3. Check the API is up
curl http://localhost:3030/healthz # {"state":"UP"}
4. Log in
ring login --username admin --password changeme
The token is stored in ~/.config/kemeter/ring/auth.json and reused by subsequent CLI commands.
Change the default password immediately.
ring user update --password "your-secure-password"updates the currently authenticated user (whose token is inauth.json). The--usernameflag also lets you rename the admin account at the same time.
Running as a service
systemd (Linux)
Create a service file:
sudo tee /etc/systemd/system/ring.service > /dev/null <<EOF [Unit] Description=Ring container orchestrator After=docker.service Requires=docker.service [Service] Type=simple User=root WorkingDirectory=/opt/ring Environment=RING_SECRET_KEY=your-base64-encoded-key Environment=RUST_LOG=info ExecStart=/usr/local/bin/ring server start Restart=always RestartSec=10 [Install] WantedBy=multi-user.target EOF
Enable and start:
sudo mkdir -p /opt/ring sudo chown $(whoami):$(whoami) /opt/ring cd /opt/ring ring init sudo systemctl enable ring sudo systemctl start ring sudo systemctl status ring
Docker Compose
# compose.yaml services: ring: build: . ports: - "3030:3030" volumes: - /var/run/docker.sock:/var/run/docker.sock - ./data:/app/data restart: unless-stopped environment: - RING_DATABASE_PATH=/app/data/ring.db - RING_SECRET_KEY=${RING_SECRET_KEY}
Configuration
config.toml
Ring reads ~/.config/kemeter/ring/config.toml (or $RING_CONFIG_DIR/config.toml) for client and server settings. See the CLI reference for the full schema. The bind address and port live there.
Environment variables
RING_DATABASE_PATH— path to the SQLite database file (default:./ring.db)RING_DB_POOL_SIZE— maximum SQLite connections in the pool (default:5)RING_CONFIG_DIR— config directory path (default:~/.config/kemeter/ring)RING_SECRET_KEY— 32-byte base64-encoded encryption key for the secrets feature. Required to create or read secrets — without it, the server returns500on secret endpoints.RING_APPLY_TIMEOUT— timeout in seconds for a single schedulerapplycycle (default:300)RING_SCHEDULER_INTERVAL— scheduler tick interval in seconds (overridesscheduler.intervalinconfig.toml)RUST_LOG— log level (e.g.RUST_LOG=infoorRUST_LOG=ring=debug)
Generating the secret key
openssl rand -base64 32
Export it before starting the server:
export RING_SECRET_KEY="your-base64-encoded-key" ring server start
Key management — store this key securely. If lost, encrypted secrets become unrecoverable. If leaked, rotate it and recreate every secret.
Troubleshooting
"Failed to connect to Docker daemon"
Docker is not running, or the user lacks permissions.
sudo systemctl start docker sudo usermod -aG docker $USER # then log out and back in
"Permission denied" on /var/run/docker.sock
User is not in the docker group.
sudo usermod -aG docker $USER # then log out and back in
"Port 3030 already in use"
Another service is bound to 3030. Change the port in config.toml:
[contexts.default] api.port = 3031
Or find and stop the conflicting process:
sudo ss -tlnp | grep 3030
Run ring doctor
ring doctor checks Docker connectivity and Cloud Hypervisor prerequisites (binary, KVM, firmware, virtiofsd). Use it as a first-step diagnostic.
Logs
# Service mode sudo journalctl -u ring -f # Foreground RUST_LOG=info ring server start
Next steps
Uninstall
# Remove binary sudo rm /usr/local/bin/ring # Remove data rm -rf ring.db ring.db-shm ring.db-wal rm -rf ~/.config/kemeter/ring # Remove systemd service sudo systemctl stop ring sudo systemctl disable ring sudo rm /etc/systemd/system/ring.service sudo systemctl daemon-reload