Kalau kamu ngikutin obrolan di komunitas self-hosting belakangan ini, pasti ngerasa ada yang beda soal MinIO. Selama ini MinIO jadi pilihan default buat S3-compatible storage sendiri, tapi versi Community Edition-nya makin dipangkas fiturnya – termasuk web console yang dulu gratis. Banyak yang akhirnya cari alternatif, dan salah satu nama yang paling sering muncul adalah Garage. Di artikel ini saya bakal bahas cara install Garage di VPS pakai Docker Compose dari nol, mulai dari konfigurasi sampai bucket-nya siap dipakai buat aplikasi kamu.
Apa Itu Garage Sebenarnya
Garage itu object storage open-source yang kompatibel dengan protokol S3 API. Buat yang belum familiar, S3 API itu standar yang dipopulerkan Amazon Web Services buat nyimpen file (object) di cloud. Banyak aplikasi modern yang support S3 API buat penyimpanan – mulai dari Nextcloud, Immich, sampai tool backup kayak restic dan rclone. Dengan Garage, kamu bisa punya “S3 sendiri” di VPS tanpa bayar ke AWS.
Yang bikin Garage beda dari S3-compatible storage lain:
- Ringan banget: Dikembangin sama tim Deuxfleurs asal Prancis, Garage didesain dari awal buat jalan di hardware kecil. Binary-nya kecil, RAM yang dimakan minimal, cocok buat VPS kelas entry-level
- Single binary: Gak butuh database eksternal. Metadata disimpen lokal pakai LMDB (embedded database). Jadi gak perlu install PostgreSQL atau MySQL terpisah
- Konfigurasi sederhana: Cukup satu file TOML buat semua konfigurasi. Gak ada puluhan file config yang bikin pusing
- S3-compatible: Bisa dipakai sama semua tool yang support S3 API – aws-cli, boto3, rclone, restic, dan lain-lain. Aplikasi kamu gak perlu tau kalau backend-nya bukan AWS
- Support multi-node: Walaupun bisa jalan di satu VPS doang, Garage juga support distributed setup kalau nanti kamu mau scale ke beberapa server

Bedanya Garage Sama MinIO
Karena dua-duanya sama-sama S3-compatible storage, wajar kalau banyak yang bingung mending pilih mana. Perbedaan utamanya ada di filosofi desain dan target pengguna.
MinIO dibikin buat skala enterprise. Fiturnya lengkap – web console, bucket versioning, object locking, tiering otomatis, dan banyak lagi. Tapi sejak versi terbaru, banyak fitur yang dipindahin ke versi berbayar. Community Edition makin terbatas, dan resource yang dimakan juga lebih berat. Kalau kamu cuma butuh S3 storage kecil buat backup atau attachment aplikasi, MinIO kerasa kebesaran.
Garage di sisi lain sengaja dibikin minimalis. Fokusnya cuma satu: nyimpen object dengan reliable dan ringan. Gak ada web console mewah, gak ada fitur enterprise yang bikin berat. Tapi buat kebutuhan personal, backup, atau aplikasi kecil-menengah, ini lebih dari cukup.
Kapan tetep pilih MinIO: kalau kamu butuh fitur enterprise kayak object locking, bucket versioning, atau web console buat manage storage lewat browser. Kapan pilih Garage: kalau kamu cuma butuh S3 endpoint yang ringan, cepet di-setup, dan gak makan banyak resource di VPS kamu.
Prasyarat Sebelum Install Garage di VPS
Sebelum masuk ke instalasi, ada beberapa hal yang wajib disiapin dulu. Garage emang ringan, tapi tetep ada minimum requirement yang harus dipenuhi biar semuanya jalan lancar.
1. VPS dengan Spesifikasi Minimum
Garage tergolong sangat ringan dibanding MinIO. Spek minimum yang dibutuhin:
- RAM: Minimal 1GB nganggur (di luar kebutuhan OS dan service lain). Garage sendiri cuma makan sekitar 100-200MB RAM
- Storage: Tergantung seberapa banyak data yang mau disimpen. Minimal siapin 20GB buat OS dan Garage, sisanya buat data object storage
- CPU: 1 vCPU udah cukup buat penggunaan ringan
- OS: Ubuntu 22.04 atau 24.04 LTS (rekomendasi buat pemula)
Cara cek spek VPS kamu:
free -h # cek RAM tersedia
df -h # cek disk space
nproc # cek jumlah CPU
lsb_release -a # cek versi OS
2. Docker dan Docker Compose Sudah Terinstall
Semua langkah di artikel ini pakai Docker Compose. Kalau belum terinstall, ikutin dulu panduan Cara Install Docker di Ubuntu VPS. Verifikasi dengan:
docker --version
docker compose version
3. Port yang Dibutuhin
Garage pakai empat port, masing-masing punya fungsi berbeda:
- Port 3900 – S3 API endpoint. Ini yang dipakai aplikasi buat upload/download object
- Port 3901 – RPC (Remote Procedure Call) buat komunikasi antar node. Di single-node setup tetep dibutuhin
- Port 3902 – Web endpoint (opsional, buat serve static website dari bucket)
- Port 3903 – Admin API buat manage bucket, key, dan cluster. Jangan pernah buka port ini ke publik
Cek apakah port-port ini masih kosong:
sudo lsof -i :3900
sudo lsof -i :3901
sudo lsof -i :3903
Kalau gak ada output, berarti port masih tersedia.
4. Generate Secret Keys
Garage butuh dua nilai rahasia yang harus di-generate sebelum mulai konfigurasi:
- RPC Secret: Buat enkripsi komunikasi antar node (walaupun cuma satu node, tetep wajib ada)
- Admin Token: Buat autentikasi akses ke Admin API
Generate keduanya sekarang dan simpen hasilnya:
openssl rand -hex 32 # buat rpc_secret
openssl rand -base64 32 # buat admin_token
Catat kedua hasilnya di tempat yang aman, nanti bakal dipakai di file konfigurasi.
5. Domain atau Subdomain (Opsional)
Kalau kamu mau akses S3 API lewat HTTPS (direkomendasikan buat production), siapin subdomain yang A record-nya udah ngarah ke IP VPS. Misalnya s3.contoh.com. Nanti bisa dipasang reverse proxy di depannya buat handle SSL.
Cara Install Garage di VPS Step by Step
Sekarang masuk ke bagian inti. Ikutin langkah-langkah di bawah ini satu per satu.

Step 1 – Buat Folder Project
Login ke VPS lewat SSH, lalu bikin folder khusus buat Garage:
mkdir -p /opt/garage
cd /opt/garage
Folder ini bakal jadi tempat semua konfigurasi Garage. Data object storage-nya sendiri disimpen di Docker volume yang terpisah.
Step 2 – Buat File Konfigurasi garage.toml
Garage dikonfigurasi lewat satu file TOML. Bikin file-nya:
nano garage.toml
Paste isi berikut dan ganti bagian yang perlu disesuaikan:
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
db_engine = "lmdb"
replication_factor = 1
rpc_bind_addr = "[::]:3901"
rpc_public_addr = "127.0.0.1:3901"
rpc_secret = "GANTI_DENGAN_HASIL_OPENSSL_RAND_HEX_32"
[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:3900"
root_domain = ".s3.domainmu.com"
[s3_web]
bind_addr = "[::]:3902"
root_domain = ".web.domainmu.com"
[admin]
api_bind_addr = "[::]:3903"
admin_token = "GANTI_DENGAN_HASIL_OPENSSL_RAND_BASE64_32"
Penjelasan setiap parameter:
- metadata_dir: Folder tempat Garage nyimpen metadata (index, bucket info, key info). Pakai LMDB sebagai embedded database, jadi gak butuh PostgreSQL atau MySQL
- data_dir: Folder tempat file object yang sebenarnya disimpen. Ini yang bakal makan disk space paling banyak
- db_engine: Engine database buat metadata.
lmdbitu pilihan default dan paling stabil buat single-node - replication_factor: Berapa salinan data yang disimpen. Karena kita cuma punya satu node, set
1. Kalau nanti nambah node buat redundansi, naikin angka ini - rpc_bind_addr: Alamat dan port buat komunikasi antar node.
[::]:3901artinya listen di semua interface di port 3901 - rpc_public_addr: Alamat publik node ini yang bisa dijangkau node lain. Buat single-node,
127.0.0.1:3901udah cukup - rpc_secret: Secret key buat enkripsi komunikasi antar node. Ganti dengan hasil
openssl rand -hex 32yang udah kamu generate tadi - [s3_api] api_bind_addr: Port S3 API endpoint. Ini yang dipakai aplikasi buat upload/download object
- [s3_api] s3_region: Nama region, bebas diisi apa aja. Beberapa S3 client butuh ini buat konfigurasi
- [s3_api] root_domain: Domain buat virtual-hosted-style access. Kalau gak pakai, bisa dikosongin atau dihapus baris ini
- [s3_web]: Endpoint buat serve static website dari bucket. Opsional, bisa dihapus kalau gak butuh
- [admin] api_bind_addr: Port Admin API buat manage bucket dan key. Jangan pernah expose port ini ke publik
- [admin] admin_token: Token buat autentikasi Admin API. Ganti dengan hasil
openssl rand -base64 32
Simpan file dengan Ctrl+O lalu Enter, keluar dengan Ctrl+X.
Step 3 – Buat File docker-compose.yml
Masih di folder /opt/garage, bikin file Docker Compose:
nano docker-compose.yml
Paste isi berikut:
services:
garage:
image: dxflrs/garage:v2.3.0
container_name: garage
restart: unless-stopped
ports:
- "3900:3900"
- "3901:3901"
- "3902:3902"
- "3903:3903"
volumes:
- ./garage.toml:/etc/garage.toml
- garage_meta:/var/lib/garage/meta
- garage_data:/var/lib/garage/data
volumes:
garage_meta:
garage_data:
Penjelasan setiap komponen:
- image: dxflrs/garage:v2.3.0: Image resmi Garage dari Deuxfleurs. Pakai versi spesifik (v2.3.0) biar gak kena breaking changes kalau ada update. Cek versi terbaru di dokumentasi resmi
- ports: Expose keempat port Garage ke host. Nanti di bagian keamanan kita bakal bahas port mana yang perlu ditutup dari publik
- ./garage.toml:/etc/garage.toml: Mount file konfigurasi yang tadi kita bikin ke dalam container. Garage baca config dari
/etc/garage.toml - garage_meta: Docker named volume buat metadata. Ini yang nyimpen index dan informasi bucket/key
- garage_data: Docker named volume buat data object yang sebenarnya. Ini yang bakal makan disk space paling banyak
- restart: unless-stopped: Container otomatis nyala lagi kalau VPS di-reboot, kecuali kamu sengaja stop manual
Kenapa pakai Docker Compose dan bukan docker run? Karena Compose bikin data kamu otomatis persist lewat named volume. Jadi gak ilang pas container di-restart atau di-recreate. Plus, konfigurasinya tersimpen di file yang bisa di-version control.
Step 4 – Jalankan Container dan Setup Layout
Jalanin container:
docker compose up -d
Tunggu beberapa detik sampai container running. Cek statusnya:
docker compose ps
Kalau status udah Up, container Garage udah jalan. Tapi belum selesai – Garage masih butuh satu langkah penting sebelum bisa nerima data: setup layout cluster.
Kenapa layout wajib di-setup? Garage didesain buat bisa jalan di beberapa node sekaligus (distributed). Makanya dia perlu tau “peta” cluster-nya – node mana aja yang ada, berapa kapasitas masing-masing, dan di zone mana. Walaupun kamu cuma pakai satu node, langkah ini tetep wajib. Tanpa layout, Garage bakal nolak nyimpen data walaupun API-nya udah kelihatan hidup.
Pertama, cek node ID kamu:
docker exec -it garage /garage status
Output-nya bakal nunjukin node ID yang panjang (string hex). Salin node ID tersebut, lalu assign layout dan apply:
docker exec -it garage /garage layout assign -z dc1 -c 10G NODE_ID_KAMU
docker exec -it garage /garage layout apply --version 1
Penjelasan parameter:
- -z dc1: Nama zone atau datacenter. Buat single-node, bebas namain apa aja. Ini cuma label buat identifikasi
- -c 10G: Kapasitas yang dialokasikan ke node ini. Sesuaikan dengan disk space yang tersedia di VPS kamu. Misalnya kalau punya 50GB kosong, bisa set
-c 40G(sisain buat OS) - –version 1: Versi layout. Setiap kali kamu ubah layout, versi harus dinaikin
Step 5 – Bikin Bucket dan Access Key
Setelah layout beres, sekarang bikin bucket (tempat nyimpen object) dan access key (kredensial buat aplikasi konek ke Garage):
docker exec -it garage /garage bucket create app-bucket
Ini bikin bucket baru dengan nama app-bucket. Ganti namanya sesuai kebutuhan, misalnya backup-bucket, nextcloud-data, atau immich-storage.
Selanjutnya bikin access key:
docker exec -it garage /garage key create app-key
Command ini bakal ngeluarin Access Key ID dan Secret Access Key, formatnya mirip persis sama AWS. Contoh output-nya:
Key name: app-key
Key ID: GK31c2f218a2e44f485b94239e
Secret: b892c0665f0ada8a4755dae98baa3b133590e11dae3bcc1f9d769c2ab7f1548d
Penting: Simpen baik-baik kedua nilai ini di password manager atau catatan yang aman. Secret key cuma ditampilin sekali – kalau hilang, kamu harus bikin key baru.
Terakhir, kasih permission ke key ini buat akses bucket:
docker exec -it garage /garage bucket allow --read --write --owner app-bucket --key app-key
Penjelasan flag permission:
- –read: Key bisa baca (download) object dari bucket
- –write: Key bisa tulis (upload) object ke bucket
- –owner: Key punya akses penuh termasuk manage bucket settings. Kalau cuma butuh read/write tanpa admin access, hapus flag ini
Sekarang kamu punya S3 endpoint yang siap dipakai. Informasi koneksi yang dibutuhin aplikasi:
- Endpoint:
http://ip-vps-kamu:3900 - Region:
garage(sesuai yang di-set di garage.toml) - Access Key ID: dari output key create tadi
- Secret Access Key: dari output key create tadi
- Bucket:
app-bucket
Testing dan Verifikasi
Step 6 – Test Upload dan Download Pakai aws-cli
Cara paling gampang buat test apakah Garage udah berfungsi adalah pakai aws-cli. Install dulu kalau belum ada:
apt install awscli -y
Konfigurasi aws-cli buat konek ke Garage:
aws configure
# AWS Access Key ID: masukkan Key ID dari Step 5
# AWS Secret Access Key: masukkan Secret dari Step 5
# Default region name: garage
# Default output format: json
Sekarang test upload file:
# bikin file test
echo "Hello from Garage!" > test-file.txt
# upload ke bucket
aws --endpoint-url http://localhost:3900 s3 cp test-file.txt s3://app-bucket/test-file.txt
Kalau berhasil, output-nya bakal nunjukin upload: ./test-file.txt to s3://app-bucket/test-file.txt.
Test download balik:
aws --endpoint-url http://localhost:3900 s3 cp s3://app-bucket/test-file.txt downloaded.txt
cat downloaded.txt
Kalau isi file downloaded.txt sama dengan yang di-upload (“Hello from Garage!”), berarti S3 API Garage udah berfungsi dengan bener.
Test list object di bucket:
aws --endpoint-url http://localhost:3900 s3 ls s3://app-bucket/
Flag --endpoint-url wajib ditambahin di setiap command aws-cli karena kita konek ke Garage, bukan ke AWS asli. Kalau nanti akses dari luar VPS, ganti localhost dengan IP atau domain VPS kamu.
Step 7 – Test Koneksi dari Aplikasi
Setelah aws-cli berhasil, coba sambungin Garage ke aplikasi yang beneran bakal pakai. Beberapa contoh konfigurasi:
Buat Nextcloud (External Storage):
- Bucket:
app-bucket - Hostname:
ip-vps:3900 - Port:
3900 - Region:
garage - Enable Path Style: Yes (penting, Garage pakai path-style bukan virtual-hosted)
Buat rclone (backup):
[garage]
type = s3
provider = Other
endpoint = http://ip-vps:3900
access_key_id = KEY_ID_KAMU
secret_access_key = SECRET_KAMU
region = garage
acl = private
Kalau aplikasi berhasil konek dan bisa upload/download file lewat Garage, berarti setup kamu udah production-ready.
Yang Perlu Diperhatiin Setelah Install Garage
Ada beberapa masalah yang sering muncul setelah install. Baca bagian ini biar kamu gak perlu debugging berjam-jam buat masalah yang sebenernya umum.
Garage Nolak Nyimpen Data Padahal Container Udah Jalan
Ini masalah paling umum dan penyebabnya hampir selalu sama: layout belum di-apply. Garage emang didesain buat distributed setup, jadi dia wajib tau “peta” cluster-nya sebelum mau nerima data. Walaupun cuma satu node, langkah layout assign dan layout apply di Step 4 tetep harus dijalanin. Cek statusnya dengan:
docker exec -it garage /garage layout show
Kalau output-nya nunjukin layout kosong atau “No nodes configured”, berarti kamu belum assign layout. Ulangi Step 4 dari bagian layout assign.
aws-cli Error “Access Denied” atau “Bucket Not Found”
Kalau aws-cli nge-return error pas coba upload atau download, cek beberapa hal ini:
- Access Key salah: Pastiin Key ID dan Secret yang dimasukin di
aws configuresama persis dengan output darikey create. Copy-paste, jangan ketik manual - Permission belum di-assign: Pastiin kamu udah jalanin command
bucket allowdi Step 5. Tanpa ini, key gak punya akses ke bucket walaupun key dan bucket-nya udah ada - Endpoint URL salah: Pastiin flag
--endpoint-urlngarah ke alamat yang bener. Kalau dari dalam VPS, pakaihttp://localhost:3900. Kalau dari luar, pakaihttp://ip-vps:3900 - Region gak cocok: Beberapa S3 client strict soal region. Pastiin region di aws configure sama dengan
s3_regiondi garage.toml (default:garage)
Port Tertutup atau Gak Bisa Diakses dari Luar
Kalau dari dalam VPS bisa konek tapi dari luar gak bisa, masalahnya ada di firewall. Buat akses S3 API dari luar, port 3900 harus terbuka:
sudo ufw allow 3900/tcp
Tapi hati-hati: jangan buka semua port Garage ke publik. Yang boleh dibuka ke publik cuma port 3900 (S3 API), dan idealnya lewat reverse proxy dengan SSL. Port lain harus tetep tertutup:
- Port 3901 (RPC): Cuma dibutuhin buat komunikasi antar node. Di single-node, gak perlu dibuka ke publik sama sekali
- Port 3902 (Web): Cuma kalau kamu mau serve static website dari bucket. Kalau gak, tutup
- Port 3903 (Admin): Jangan pernah dibuka ke publik. Ini jalan masuk buat ngatur seluruh cluster. Kalau perlu akses dari luar, lewat SSH tunnel atau VPN
Jangan lupa cek juga firewall di panel provider VPS (DigitalOcean, Vultr, Hetzner) kalau ada.
Keamanan – Amankan Garage Biar Gak Nongol ke Publik
Defaultnya, semua port Garage kebuka ke mana-mana kalau kamu gak lock down firewall-nya. Rekomendasi setup keamanan:
- Pasang reverse proxy: Taruh Garage di belakang Traefik atau Nginx dengan TLS biar koneksi ke S3 API terenkripsi
- Batasi akses pakai UFW: Cuma buka port 3900 ke IP yang emang butuh. Kalau bisa, lewat VPN atau jaringan private aja
- Backup metadata: Jangan lupa backup file
garage.tomldan volume metadata (garage_meta). Kalau metadata hilang, kamu bisa kehilangan akses ke data yang udah kesimpen walaupun disk data-nya masih utuh - Backup data volume: Masukin volume
garage_datake rutinitas backup volume Docker kamu
Kesimpulan
Kalau kamu baru mau mulai pakai S3-compatible storage sendiri atau lagi cari alternatif yang lebih ringan dari MinIO, Garage layak jadi pilihan pertama. Instalasinya straightforward, resource yang dimakan minimal, dan konfigurasinya cuma satu file TOML. Buat skala personal, backup, atau aplikasi kecil-menengah, ini lebih dari cukup.
Perlu ganti dari MinIO yang udah jalan? Kalau setup MinIO kamu masih lancar dan gak kena batasan versi baru, gak ada urgensi buru-buru migrasi. Tapi kalau baru mulai dari nol, Garage bikin prosesnya jauh lebih simpel.
Yang jelas, sekarang kamu punya S3-compatible storage sendiri yang gak bergantung ke provider cloud. Tinggal disambungin ke Nextcloud buat external storage, Immich buat penyimpanan foto, atau tool backup favorit kamu buat push snapshot ke tempat yang terpisah dari server produksi.
Yang paling penting, jangan lupa amankan port-port Garage (terutama port 3903 Admin API) dan backup metadata-nya secara rutin. Kehilangan metadata bisa bikin data yang udah kesimpen gak bisa diakses lagi walaupun disk-nya masih utuh.

























