Building a Distributed S3-Compatible Object Storage with Garage on Low-Spec, Repurposed VPS Infrastructure
Introduction: The Challenge of Unused Infrastructure
In the modern enterprise landscape, computing efficiency is paramount. Over time, businesses frequently accumulate a surplus of legacy Virtual Private Servers (VPS)—low-spec instances that are no longer powerful enough to host resource-heavy modern applications or heavy databases. Often, these servers are left underutilized, yet they represent recurring infrastructure costs.
Simultaneously, the demand for reliable, scalable S3-compatible object storage is skyrocketing. Traditional cloud storage providers offer robust solutions, but data egress fees and strict scaling tiers can become unpredictable. What if you could repurpose your aging, low-spec VPS infrastructure into a self-hosted, highly resilient, and distributed object storage system? This is exactly where Garage comes into play.
Garage is a lightweight, open-source distributed object storage service designed specifically to run efficiently on heterogeneous, low-spec hardware. Unlike heavier alternatives like Ceph or MinIO, which demand substantial CPU and RAM overhead, Garage is written in Rust and tailored to maximize the utility of constrained environments.
---Why Garage? Overcoming the Limits of Low-Spec VPS
When dealing with older or budget VPS instances—typically configured with just 1 vCPU, 1GB to 2GB of RAM, and modest disk space—traditional distributed storage engines quickly falter. They consume too much memory or require high-throughput networking links to maintain data consistency.
Garage addresses these constraints through several core architectural principles:
- Lightweight Footprint: Written in Rust, Garage compiles to a single binary with zero external dependencies, maintaining an incredibly low idle memory footprint (often under 50MB per node).
- Heterogeneous Capability: It does not require all nodes to be identical. You can mix and match a 1GB RAM VPS in Singapore with a 2GB RAM VPS in Germany; Garage balances the data distribution based on assigned weights.
- Network Partition Tolerance: It utilizes a Dynamo-style architecture with Conflict-Free Replicated Data Types (CRDTs). This means that even if a budget VPS suffers from transient network instability, the cluster will automatically resynchronize without manual intervention once connectivity is restored.
- Multi-Region Resilience: Because it handles latency gracefully, you can build a geographically distributed cluster, providing high availability across different data centers and providers.
Prerequisites and Architecture Overview
Before launching into the deployment phase, it is vital to establish a clear architectural layout. For a robust setup, a minimum of three distinct nodes is highly recommended to achieve a stable quorum and handle node failures effectively.
Minimum Requirements Per Node
- OS: Any modern Linux distribution (Ubuntu 22.04 LTS or Debian 12 recommended).
- CPU: 1 vCPU (even shared or older architectures work).
- RAM: 1 GB minimum (Garage can run on 512MB, but 1GB provides operational safety).
- Disk Space: Dependent on your storage goals; SSDs are preferred, but HDDs are acceptable.
- Network: Public IPv4 addresses or a secure private overlay network (like WireGuard or Tailscale).
For security and simplicity, we recommend establishing a private VPN overlay network between your nodes using WireGuard or Tailscale. This keeps internal cluster communication isolated from the public internet, preventing unauthorized data access.
---Step-by-Step Deployment Guide
Let us walk through the process of setting up a 3-node Garage cluster. Assume our nodes have the internal overlay IP addresses 10.0.0.1, 10.0.0.2, and 10.0.0.3.
Step 1: Downloading and Installing Garage
Log into each of your VPS instances via SSH and download the latest stable pre-compiled binary. Execute the following commands:
wget [https://garagehq.opera-digital.com/releases/v0.9.0/x86_64-unknown-linux-musl/garage](https://garagehq.opera-digital.com/releases/v0.9.0/x86_64-unknown-linux-musl/garage)
chmod +x garage
sudo mv garage /usr/local/bin/Verify the installation by running garage --version.
Step 2: Configuring the Cluster Nodes
Create a configuration directory and file on each node, typically located at /etc/garage.toml. Below is a production-ready baseline configuration template for Node 1:
Note: Ensure you change the
rpc_secretto a secure, randomly generated hex string. This secret must be identical across all nodes in the cluster to allow them to communicate securely.
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
rpc_secret = "YOUR_SECURE_RANDOM_HEX_STRING_HERE"
[rpc_bind]
address = "10.0.0.1:3901"
public_address = "10.0.0.1:3901"
[s3_api]
api_bind_address = "0.0.0.0:3900"
[s3_web]
web_bind_address = "0.0.0.0:3902"Repeat this configuration on Node 2 and Node 3, updating the address and public_address fields to match each server's respective internal IP.
Step 3: Creating Systemd Services
To ensure Garage automatically starts on boot and runs reliably in the background, create a systemd service file at /etc/systemd/system/garage.service:
[Unit]
Description=Garage Distributed Object Storage
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/garage server -c /etc/garage.toml
Restart=always
User=root
[Install]
WantedBy=multi-user.targetEnable and start the service across all nodes:
sudo systemctl daemon-reload
sudo systemctl enable --now garage---Initializing and Structuring the Cluster
With all three nodes running, they are independent entities waiting to be connected. We will use the Garage CLI tool on any node to connect them and define our storage topology.
1. Connecting the Nodes
From Node 1, run the following commands to instruct it to communicate with the other instances:
garage node connect [Node_2_RPC_ID]@10.0.0.2:3901
garage node connect [Node_3_RPC_ID]@10.0.0.3:3901You can retrieve a node's RPC ID by checking the logs using journalctl -u garage upon startup.
2. Configuring Layout and Weights
Garage uses a 3-step layout configuration to prevent accidental data shifts. First, assign a zone (e.g., geographical location) and a capacity weight to each node. If a node has 50GB of storage, you might give it a weight of 50.
garage layout assign [Node_1_ID] -z zone1 -w 50
garage layout assign [Node_2_ID] -z zone1 -w 50
garage layout assign [Node_3_ID] -z zone1 -w 50Review the changes before applying them:
garage layout planIf the plan looks correct, finalize and apply it to trigger data distribution:
garage layout applyThe nodes will instantly form a resilient mesh network, balancing metadata and setting up data replication policies.
---S3 Integration and Client Configuration
Now that your cluster is fully functional, you can create API credentials to interact with it via standard S3 clients, such as AWS CLI, rclone, or application SDKs.
Creating an Access Key
Generate a new API access key pair:
garage key new --name "production-key"This command outputs an Access Key ID and a Secret Access Key. Keep these secure.
Creating a Bucket
Create a bucket and grant your new key full read/write permissions:
garage bucket create my-business-assets
garage bucket allow my-business-assets --read --write --key "production-key"Connecting with AWS CLI
You can verify access using the standard AWS CLI utility. Configure your local client to use your Garage endpoint:
aws s3 ls --endpoint-url http://[ANY_NODE_IP]:3900 --profile garage---Performance Optimization and Best Practices for Low-Spec Hardware
Running high-availability storage on low-spec VPS environments requires careful optimization to ensure long-term stability. Adhere to these business-critical best practices:
- Optimize Linux Swap Spaces: Because low-spec VPS nodes have limited physical RAM, unexpected spikes in traffic could trigger the Linux Out-Of-Memory (OOM) killer. Configure at least a 2GB swap file on each node to act as a safety buffer.
- Implement a Reverse Proxy / Load Balancer: Avoid exposing the Garage S3 port (3900) directly to production applications. Instead, place an Nginx or HAProxy instance in front of your cluster. This allows for SSL/TLS termination, request caching, and seamless round-robin load balancing across all three nodes.
- Monitor Meta Directory Disk I/O: Garage relies heavily on fast disk I/O for its metadata directory (
metadata_dir). If your VPS has sluggish disk speeds, consider placing the metadata on a RAM disk or ensuring it uses premium NVMe block storage, while utilizing standard HDDs for the bulk data directory. - Automated Backups: While Garage replicates data across nodes to handle hardware failure, it does not prevent accidental file deletion or malicious attacks. Implement offsite snapshot backups of your data at regular business intervals.
Conclusion: Unlocking Hidden Value
Building a distributed S3-compatible object storage cluster using Garage allows enterprises to reclaim valuable computing power from idle, low-spec VPS infrastructure. It offers a cost-effective, self-hosted option for storing backups, serving static web assets, and hosting staging application data without expanding cloud budgets. By following this guide, your organization can effectively lower infrastructure overhead while maintaining a reliable, scalable, and decentralized storage ecosystem.
