PromptHub
Developer Tools DevOps & Infrastructure

Stop Wrestling with S3 CLIs! garage-webui Makes Object Storage Effortless

B

Bright Coding

Author

14 min read
29 views
Stop Wrestling with S3 CLIs! garage-webui Makes Object Storage Effortless

Stop Wrestling with S3 CLIs! garage-webui Makes Object Storage Effortless

What if managing petabytes of distributed object storage was as simple as checking your email?

Here's the dirty secret nobody tells you about self-hosted infrastructure: the command line is a productivity killer. You've spun up Garage—brilliant, S3-compatible, distributed object storage that puts AWS to shame on privacy and cost. But now you're trapped in a terminal maze of garage subcommands, squinting at JSON outputs, and praying you don't accidentally nuke a bucket policy. Every bucket creation feels like defusing a bomb. Every access key rotation requires cross-referencing three different docs. And don't even get me started on cluster health monitoring—because you won't see problems coming until your nodes are already on fire.

Sound familiar? You're not alone. Thousands of developers adopt Garage for its technical excellence, then silently suffer through operational friction that kills momentum. But what if I told you there's a single binary that transforms this pain into point-and-click simplicity?

Enter garage-webui—the open-source web interface that makes Garage object storage management actually enjoyable. Created by Khairul Hidayat, this tool is spreading through DevOps circles like wildfire for one simple reason: it respects your time. No more memorizing CLI flags. No more parsing cryptic API responses. Just a clean, modern dashboard where clusters, buckets, and access keys bow to your cursor.

Ready to reclaim your sanity? Let's dive deep into why garage-webui is becoming the secret weapon for developers who refuse to let infrastructure management suck their soul dry.


What is garage-webui?

garage-webui is a lightweight, self-hosted administrative web interface purpose-built for Garage—the increasingly popular open-source, S3-compatible distributed object storage service developed by Deuxfleurs. While Garage itself handles the heavy lifting of data replication, erasure coding, and distributed consensus, garage-webui provides the human-friendly control layer that transforms raw infrastructure into manageable resources.

The project emerged from a genuine pain point: Garage's native administration relies heavily on command-line tools and direct API calls. For infrastructure veterans, this is workable. For teams scaling quickly, or for developers wearing multiple hats, it's friction that compounds. Khairul Hidayat recognized this gap and built garage-webui as a single executable binary that bridges Garage's powerful backend with an intuitive React-based frontend.

What makes garage-webui genuinely exciting right now? Three converging trends:

  • The self-hosted renaissance: Post-Snowden, post-ChatGPT-data-scraping-paranoia, organizations are aggressively repatriating data. Garage downloads are spiking, and every new Garage deployment needs management tooling.
  • The "platform engineering" mandate: Companies want internal developer platforms with GUIs, not ticket-ops workflows. garage-webui drops perfectly into this paradigm.
  • Container-native simplicity: With first-class Docker and Docker Compose support, it integrates seamlessly into existing infrastructure-as-code setups without adding operational complexity.

The project is built on a TypeScript/React frontend with a Go backend—a stack chosen for performance, maintainability, and ease of contribution. It's not trying to be Kubernetes-dashboard-complex; it's deliberately focused on doing one thing spectacularly well: making Garage administration effortless.


Key Features That Actually Matter

Let's cut through feature-list fluff. Here's what garage-webui delivers and why each capability saves you real hours:

Real-Time Garage Health Status

Stop SSH-ing into nodes to check if your cluster's heart is still beating. The dashboard surfaces node health, replication status, and potential issues in a single glance. This isn't vanity metrics—it's early warning radar that prevents 3 AM pages.

Cluster & Layout Management

Garage's distributed nature means nodes join, leave, and rebalance. garage-webui visualizes your cluster topology and lets you manage layout assignments without touching garage layout assign commands. Visual cluster surgery beats textual node lists every single time.

Full Bucket Lifecycle Control

Create buckets, update configurations, inspect metadata, and browse contents—all through a clean interface. The integrated objects/bucket browser means you can verify uploads, debug permissions issues, and spot-check data without configuring separate S3 clients like aws-cli or s3cmd.

Access Key Management

Generate, rotate, and assign S3-compatible access keys with proper scoping. This is where garage-webui shines for security hygiene: key rotation becomes a 30-second task instead of a scripted ordeal. No more stale credentials lurking in environment variables for months.

Zero-Config Authentication Option

The optional AUTH_USER_PASS environment variable with bcrypt hashing means you can front your admin panel with basic auth without deploying a separate reverse proxy layer. Perfect for homelabs and rapid prototypes where you need protection without complexity.

Configuration Inheritance

Rather than forcing duplicate configuration, garage-webui reads your existing garage.toml and extracts rpc_public_addr, admin.admin_token, and related values automatically. This design choice reveals mature engineering: the tool respects your existing setup instead of inventing parallel config systems.


Use Cases Where garage-webui Absolutely Dominates

1. Homelab Storage Sovereignty

You're running Garage on a Proxmox cluster or a few Raspberry Pis. You want S3-compatible storage for Nextcloud backups, Plex media, or personal photo archives. But you don't want to maintain mental models of Garage's CLI for a system you touch twice a month. garage-webui gives you set-and-forget management with occasional GUI check-ins.

2. Startup MVP Infrastructure

Your seed-stage company needs cost-effective object storage without AWS egress fee surprises. Garage on Hetzner or OVH plus garage-webui means your non-technical co-founder can create buckets for new features without pinging you on Slack. Democratized infrastructure access without democratized disaster potential.

3. CI/CD Artifact Storage

Garage stores build artifacts, container layers, and release binaries. garage-webui lets you debug failed uploads, verify retention policies, and rotate CI-specific access keys when employees depart—all without breaking your deployment flow to open terminals.

4. Multi-Tenant Platform Engineering

You're building an internal platform where teams request S3 buckets. garage-webui becomes your operator's cockpit: provision resources, audit access patterns, and present cluster health to stakeholders who want dashboards, not log streams. The visual browser proves invaluable when teams claim "our data isn't there"—you verify in seconds.

5. Edge/Offline Deployments

Garage's eventual consistency model works brilliantly in disconnected environments. garage-webui running locally lets field engineers manage storage without internet-dependent cloud consoles. Think research vessels, remote mining operations, or military edge nodes.


Step-by-Step Installation & Setup Guide

Method 1: Docker Compose (Recommended)

This approach integrates garage-webui alongside your existing Garage deployment. Create or extend your docker-compose.yml:

services:
  garage:
    image: dxflrs/garage:v2.0.0
    container_name: garage
    volumes:
      - ./garage.toml:/etc/garage.toml
      - ./meta:/var/lib/garage/meta
      - ./data:/var/lib/garage/data
    restart: unless-stopped
    ports:
      - 3900:3900  # S3 API endpoint
      - 3901:3901  # RPC communication
      - 3902:3902  # S3 web gateway
      - 3903:3903  # Admin API (CRITICAL for webui)

  webui:
    image: khairul169/garage-webui:latest
    container_name: garage-webui
    restart: unless-stopped
    volumes:
      - ./garage.toml:/etc/garage.toml:ro  # Read-only: security best practice
    ports:
      - 3909:3909
    environment:
      API_BASE_URL: "http://garage:3903"    # Points to Garage admin API
      S3_ENDPOINT_URL: "http://garage:3900" # Points to S3 API for browsing

Critical requirement: Ensure your garage.toml has the [admin] section configured with api_bind_addr and admin_token. Without this, garage-webui cannot authenticate to Garage's management API.

Deploy with:

docker compose up -d

Access the interface at http://your-server-ip:3909.

Method 2: Standalone Docker

For quick testing or when Garage runs elsewhere:

docker run -p 3909:3909 \
  -v ./garage.toml:/etc/garage.toml:ro \
  --restart unless-stopped \
  --name garage-webui \
  khairul169/garage-webui:latest

Method 3: Binary Installation (Systemd Production Setup)

When Docker overhead is unacceptable or you're running on constrained hardware:

# Download latest release (check https://github.com/khairul169/garage-webui/releases for newer versions)
wget -O garage-webui https://github.com/khairul169/garage-webui/releases/download/1.1.0/garage-webui-v1.1.0-linux-amd64

# Make executable and install system-wide
chmod +x garage-webui
sudo cp garage-webui /usr/local/bin

# Verify binary works
CONFIG_PATH=./garage.toml garage-webui --help

Create a systemd service for automatic startup and crash recovery:

sudo nano /etc/systemd/system/garage-webui.service

Paste this service definition:

[Unit]
Description=Garage Web UI
After=network.target

[Service]
Environment="PORT=3919"                    # Custom port to avoid conflicts
Environment="CONFIG_PATH=/etc/garage.toml" # System config location
ExecStart=/usr/local/bin/garage-webui
Restart=always                             # Auto-recover from crashes
RestartSec=5

[Install]
WantedBy=default.target

Activate the service:

sudo systemctl daemon-reload
sudo systemctl enable --now garage-webui
sudo systemctl status garage-webui  # Verify healthy startup

Essential Configuration Checklist

Your garage.toml must include these sections for garage-webui functionality:

[admin]
api_bind_addr = "[::]:3903"
admin_token = "YOUR_ADMIN_TOKEN_HERE"  # Treat as root password
metrics_token = "YOUR_METRICS_TOKEN_HERE"

The rpc_public_addr value is also required for cluster operations:

rpc_public_addr = "localhost:3901"  # Must be resolvable by webui

REAL Code Examples from the Repository

Let's examine actual implementation patterns from the garage-webui codebase and documentation, with detailed explanations of what makes each configuration work.

Example 1: Production Docker Compose with Authentication

This is the complete reference deployment from the repository, enhanced with security hardening:

services:
  garage:
    image: dxflrs/garage:v2.0.0
    container_name: garage
    volumes:
      - ./garage.toml:/etc/garage.toml
      - ./meta:/var/lib/garage/meta    # Persistent metadata
      - ./data:/var/lib/garage/data    # Persistent object data
    restart: unless-stopped
    ports:
      - 3900:3900  # S3 API: where applications connect
      - 3901:3901  # Internal RPC: inter-node communication
      - 3902:3902  # S3 web: bucket website hosting
      - 3903:3903  # Admin API: webui lifeline

  webui:
    image: khairul169/garage-webui:latest
    container_name: garage-webui
    restart: unless-stopped
    volumes:
      - ./garage.toml:/etc/garage.toml:ro  # Read-only mount prevents container from corrupting config
    ports:
      - 3909:3909
    environment:
      API_BASE_URL: "http://garage:3903"      # Internal Docker DNS resolution
      S3_ENDPOINT_URL: "http://garage:3900"   # For object browser functionality
      AUTH_USER_PASS: "admin:$2y$10$DSTi9o..."  # bcrypt-secured access (optional but recommended)

Key insights: The ro (read-only) mount on garage.toml is a defense-in-depth measure—even if the webui container is compromised, the attacker cannot modify Garage's core configuration. The API_BASE_URL uses Docker's internal DNS (garage resolves to the service's container IP), keeping admin traffic off public interfaces. The S3_ENDPOINT_URL enables the integrated object browser to fetch actual object listings and metadata.

Example 2: Complete garage.toml Configuration

This configuration from the README represents a production-ready Garage setup:

metadata_dir = "/var/lib/garage/meta"           # Where bucket metadata lives
data_dir = "/var/lib/garage/data"               # Where actual objects are stored
db_engine = "sqlite"                            # Lightweight; use "lmdb" for heavy workloads
metadata_auto_snapshot_interval = "6h"          # Automatic backup of metadata state

replication_factor = 3                          # Copies per object; tolerate 2 node failures
compression_level = 2                           # ZSTD compression; 0=none, 1-9=trade speed/ratio

rpc_bind_addr = "[::]:3901"                     # Listen on all interfaces, IPv6 compatible
rpc_public_addr = "localhost:3901"              # MUST be reachable by webui; use real hostname in production
rpc_secret = "YOUR_RPC_SECRET_HERE"             # Shared secret for cluster node authentication

[s3_api]
s3_region = "garage"                            # Arbitrary region identifier for API compatibility
api_bind_addr = "[::]:3900"
root_domain = ".s3.domain.com"                  # Virtual-hosted buckets: bucketname.s3.domain.com

[s3_web]                                        # Optional: serve buckets as static websites
bind_addr = "[::]:3902"
root_domain = ".web.domain.com"
index = "index.html"                            # Default file for directory requests

[admin]                                         # REQUIRED for garage-webui functionality
api_bind_addr = "[::]:3903"
admin_token = "YOUR_ADMIN_TOKEN_HERE"           # Generate with: openssl rand -hex 32
metrics_token = "YOUR_METRICS_TOKEN_HERE"       # For Prometheus scraping, if needed

Critical understanding: The rpc_public_addr is the most commonly misconfigured value. In Docker contexts, this must be resolvable from the webui container. Using localhost works for single-node testing but fails in distributed setups—use actual hostnames or IP addresses. The admin_token is your root credential; rotate it immediately if exposed.

Example 3: Generating Authentication Credentials

The repository provides this exact pattern for securing your dashboard:

# Generate bcrypt hash of your password
# -n: don't print newline after output
# -b: use password from command line (batch mode)
# -B: force bcrypt encryption
# -C 10: cost factor 10 (adjust for security/performance balance)
htpasswd -nbBC 10 "YOUR_USERNAME" "YOUR_PASSWORD"

Sample output:

admin:$2y$10$DSTi9o9L.KjaAyN6I8wO3O0U1kXqGjKpRtWqZrStUvWxYzAbCdEfGh

Integration into docker-compose.yml:

webui:
  ....
  environment:
    AUTH_USER_PASS: "admin:$2y$10$DSTi9o..."

Security note: The htpasswd utility comes from apache2-utils (Debian/Ubuntu) or httpd-tools (RHEL/CentOS). Cost factor 10 requires ~100ms to verify—tune higher for production, lower if you observe login latency issues. Never commit unhashed passwords to version control; generate hashes in CI/CD or locally.

Example 4: Environment Variable Override Pattern

When garage.toml parsing fails or you need runtime flexibility:

# Override auto-detected values with explicit environment variables
export API_BASE_URL="https://garage-admin.internal:3903"   # HTTPS in production!
export API_ADMIN_KEY="your-admin-token-here"                # Direct token injection
export S3_REGION="us-east-1"                                # Override region for compatibility
export S3_ENDPOINT_URL="https://s3.internal:3900"           # HTTPS S3 endpoint
export BASE_PATH="/storage-admin"                           # Serve under subpath for reverse proxy

# Then launch
garage-webui

When to use overrides: Multi-environment deployments where garage.toml differs per stage; emergency recovery when config parsing breaks; or when running garage-webui on a separate network segment from Garage itself.


Advanced Usage & Best Practices

Reverse Proxy SSL Termination

Never expose garage-webui directly to the internet. Use nginx, Caddy, or Traefik:

server {
    listen 443 ssl;
    server_name storage.example.com;
    
    location / {
        proxy_pass http://localhost:3909;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Backup Your garage.toml Before Major Changes

The webui reads configuration but doesn't validate your edits to the source file. Version control your garage.toml with Git for rollback capability.

Monitor Webui Logs for API Deprecations

Garage evolves rapidly. Watch for warnings about deprecated admin API endpoints—these signal needed garage-webui upgrades.

Use Separate Admin Tokens Per Environment

Don't share production admin tokens with staging. The environment variable override (API_ADMIN_KEY) makes this trivial to implement.

Resource Limits in Docker

Prevent memory exhaustion on shared hosts:

webui:
  deploy:
    resources:
      limits:
        memory: 256M
        cpus: '0.5'

Comparison with Alternatives

Capability garage-webui AWS S3 Console MinIO Console Native Garage CLI
Self-hosted ✅ Yes ❌ Cloud-only ✅ Yes ✅ Yes
Zero cloud cost ✅ Yes ❌ Usage fees ✅ Yes ✅ Yes
Garage-native ✅ Purpose-built ❌ N/A ❌ MinIO-only ✅ Native
Visual cluster mgmt ✅ Full N/A ⚠️ Limited ❌ CLI only
Integrated object browser ✅ Built-in ✅ Yes ✅ Yes ❌ Separate tools
Single binary deploy ✅ ~20MB ❌ N/A ❌ Larger footprint ⚠️ Garage itself
No vendor lock-in ✅ Open source ❌ AWS captive ⚠️ MinIO ecosystem ✅ Open source
Offline capable ✅ Yes ❌ No ✅ Yes ✅ Yes

Verdict: garage-webui fills a unique niche—Garage-specific, lightweight, and deliberately focused. MinIO Console is excellent but couples you to MinIO's architecture. AWS S3 Console requires... AWS. The native Garage CLI remains essential for automation, but garage-webui eliminates it for daily operations.


FAQ: Developer Concerns Answered

Is garage-webui officially part of Garage?

No—it's a community project by Khairul Hidayat. However, it uses Garage's public admin API and tracks official releases closely. Many Garage users treat it as de facto standard tooling.

Can garage-webui manage multiple Garage clusters?

Not simultaneously in one instance. Deploy separate garage-webui containers per cluster, or use environment variable switching with orchestration tools.

What happens if Garage upgrades break the admin API?

garage-webui may need updates for major Garage versions. Pin your Garage version in Docker Compose (dxflrs/garage:v2.0.0 not latest) and test upgrades in staging.

Is the webui itself a security risk?

Any admin interface expands attack surface. Mitigate: use AUTH_USER_PASS, place behind VPN/reverse proxy, run with read-only config mounts, and monitor access logs.

Can I contribute features or report bugs?

Absolutely. The project welcomes contributions. Issues go here. The TypeScript/React + Go stack is approachable for most full-stack developers.

Does garage-webui support SSO or OAuth?

Currently, only bcrypt AUTH_USER_PASS is built-in. For SSO, front with a reverse proxy handling OIDC (Authelia, Authentik, oauth2-proxy) and disable AUTH_USER_PASS.

What's the performance impact on Garage?

Negligible for typical use. The webui is stateless and caches minimally—all heavy operations hit Garage's API directly. Benchmark if managing 10,000+ buckets.


Conclusion: Your Object Storage Deserves Better

Here's the truth: infrastructure tools should reduce cognitive load, not add to it. Garage gives you world-class distributed object storage without cloud vendor shackles. garage-webui completes that promise by removing the final barrier—operational complexity—between you and your data.

I've watched too many talented developers burn hours on CLI archaeology when they could be shipping features. I've seen teams delay self-hosted storage adoption because "nobody wants to manage another black box." garage-webui demolishes both excuses. It's a single binary, a few lines of YAML, and suddenly your object storage is as approachable as any SaaS dashboard—except you own every byte.

The project is actively maintained, sensibly architected, and solving a real problem with elegant restraint. Whether you're running a homelab NAS alternative, building startup infrastructure, or designing internal platforms, this tool earns its place in your stack.

Stop fighting your tools. Start managing storage like a human.

👉 Get garage-webui on GitHub — star it, deploy it, and reclaim your time.

Comments (0)

Comments are moderated before appearing.

No comments yet. Be the first to share your thoughts!

Support us! ☕