Kebutuhan penyimpanan object di server sendiri makin sering muncul di ruang kerja sysadmin: target backup database, penampung media aplikasi, sampai artifact CI/CD. Selama bertahun-tahun MinIO menjadi jawaban default untuk kebutuhan itu. Setelah upstream menutup community edition dan memangkas web console-nya, banyak deployment yang sudah berjalan di produksi kehilangan jalur pembaruan resmi. Silo hadir sebagai fork komunitas yang mengambil alih peran tersebut, lengkap dengan console yang dikembalikan utuh. Artikel ini menelusuri apa itu Silo, alasan forking-nya, lalu praktik langsung memasangnya di satu server Linux memakai Docker Compose dan Nginx, sampai ke jalur migrasi bagi yang sudah terlanjur berjalan di atas MinIO.
1. Silo dan Posisinya
1.1 Definisi Silo
Silo adalah object storage server yang kompatibel dengan protokol S3, dirilis sebagai perangkat lunak bebas dan dipelihara oleh Pigsty. Namanya merupakan akronim dari S3 Interface Libre Object storage. Silo bukan proyek yang ditulis dari nol, melainkan fork dari MinIO yang dilanjutkan secara independen setelah repositori community MinIO diarsipkan. Basis perbandingannya adalah kode upstream per 3 Desember 2025, jadi proyek ini tergolong masih sangat muda.
Posisi Silo di ekosistem cukup jelas: penerus jalur komunitas MinIO, bukan produk komersial baru. Lisensinya tetap AGPLv3, sama seperti upstream, dan maintainer menyatakan tidak memakai lisensi itu sebagai alat tekanan komersial. Pigsty sendiri memakai Silo di produksi sebagai target backup PostgreSQL, jadi rilis yang mereka terbitkan juga mereka pakai sendiri.
Perlu dicatat, Silo tidak berafiliasi dan tidak didukung oleh MinIO, Inc. Kompatibilitas protokol dan format tetap dijaga sejauh memungkinkan, tapi secara organisasi keduanya terpisah.
1.2 Keunggulan Utama Silo
Tiga hal membuat Silo menarik bagi sysadmin yang sudah terlanjur berjalan di atas MinIO.
- Kompatibilitas S3 yang dijaga sebagai kontrak. Silo mempertahankan S3 API, penamaan variabel lingkungan
MINIO_*, metrics, headerx-minio-*, route/minio/*, namespace policyarn:minio:*, serta format data on-disk termasuk direktori.minio.sys. Volume data lama bisa dipakai langsung tanpa rename. - Web console yang dikembalikan utuh. Antarmuka manajemen yang sempat dipangkas upstream dihidupkan lagi, mencakup pengelolaan bucket, identity, policy, monitoring, sampai site replication.
- Artefak rilis siap pakai. Tersedia binary prebuilt, paket RPM/DEB/APK, dan container image multi-arsitektur untuk
linux/amd64maupunlinux/arm64, disertai checksum SHA-256, SBOM, dan tanda tangan Sigstore.
Sifat drop-in replacement inilah nilai jual utamanya, meski dokumentasi resmi menyebutnya secara hati-hati sebagai conditional drop-in replacement. Sebagian besar aplikasi yang memakai S3 API standar bisa berpindah tanpa perubahan kode, tapi ada delapan area yang tetap perlu diperiksa sesuai bentuk deployment masing-masing. Bab 8 membahas daftar periksa itu.
2. Latar Belakang Fork
2.1 Alasan Upstream Ditinggalkan
Fork tidak lahir dari selera teknis, tapi dari kebutuhan operasional. Manifesto Silo menyebut tiga pemicu konkret: web console yang dipreteli fungsinya, penghentian distribusi binary prebuilt, dan pengarsipan repositori community MinIO.
Bagi sysadmin, tiga hal itu berujung pada satu masalah yang sama: cluster yang sudah berjalan kehilangan jalur pembaruan keamanan resmi. Data tetap aman di disk, tapi tidak ada lagi patch CVE yang bisa ditarik tanpa membangun sendiri dari source. Keberlanjutan perangkat lunak bebas di lapisan storage bukan soal idealisme semata, melainkan soal siapa yang menambal lubang keamanan enam bulan lagi.
Menariknya, Silo memposisikan diri sebagai fork pragmatis, bukan pesaing permanen. Maintainer menyatakan akan mempersempit cakupan proyek dan menawarkan perbaikan mereka kembali ke upstream jika community edition MinIO dipulihkan.
2.2 Komitmen Manifesto Silo
Manifesto Silo mengunci beberapa janji yang layak dibaca sebelum kita menaruh data produksi di atasnya.
- Kontrak kompatibilitas. API, variabel lingkungan, dan format on-disk dipertahankan. Setiap rilis mendokumentasikan target rollback-nya, dan fitur baru tidak menyentuh format penyimpanan kecuali ditandai eksplisit sebagai non-reversible.
- Lisensi yang tidak bisa diubah. AGPLv3 tanpa CLA. Tidak ada entitas tunggal yang memegang hak cipta cukup besar untuk melakukan relicensing sepihak.
- Disiplin perubahan. Hanya empat kategori perubahan yang diterima: perbaikan keamanan, perbaikan bug, pemulihan fitur komunitas, dan penambahan yang sifatnya opsional. Perubahan API yang merusak hanya dilakukan atas alasan keamanan.
- Daftar larangan permanen. Proyek berjanji tidak akan pernah mengunci fitur yang sudah ada di balik bayaran, tidak mewajibkan registrasi untuk mengunduh, tidak mengirim telemetri, tidak menuntut CLA, tidak mengganti lisensi, dan tidak menjadikan merek dagang sebagai senjata.
Pada sisi keamanan, Silo menerbitkan advisory publik yang mencantumkan versi terdampak dan cara reproduksinya, bukan sekadar catatan rilis singkat. Jalur phone-home bawaan upstream juga dihapus, termasuk mekanisme callhome SUBNET dan pembaruan mandiri.
3. Arsitektur dan Kebutuhan Hardware
3.1 Topologi SNSD dan SNMD
Sebelum memasang, kita perlu memilih topologi. Dua istilah yang paling sering muncul di dunia MinIO dan tetap relevan di Silo adalah SNSD dan SNMD.
Single-Node Single-Drive (SNSD) menjalankan satu proses server di atas satu drive atau satu direktori. Mode ini paling sederhana dan cocok untuk home lab, lingkungan pengembangan, atau target backup berskala kecil. Konsekuensinya jelas: tidak ada redundansi di lapisan Silo, sehingga keselamatan data sepenuhnya bergantung pada disk di bawahnya beserta backup di luar server.
Single-Node Multi-Drive (SNMD) menjalankan satu node dengan beberapa drive terpisah. Silo mengelompokkan drive ke dalam erasure set dan menerapkan erasure coding, sehingga object tetap bisa dibaca meski sebagian drive rusak. Pada konfigurasi paritas maksimum, EC:8 memecah object menjadi 8 blok data dan 8 blok paritas yang disebar ke seluruh drive. Mode ini menahan kegagalan disk, bukan kegagalan server: motherboard yang mati tetap membuat seluruh layanan berhenti.
Penulisan multi-drive memakai notasi rentang pada argumen server, misalnya server /mnt/drive-{1...4}, dan setiap drive dipasang sebagai mount terpisah ke dalam container.
Satu catatan penting dari dokumentasi resmi: untuk produksi yang harus tetap melayani saat ada node mati, Silo menyarankan perencanaan minimal 4 host dengan spesifikasi seragam. Deployment container satu server yang kita bahas di artikel ini secara eksplisit ditujukan untuk pengembangan dan evaluasi, bukan topologi produksi multi-node. Pemakaian di luar itu tetap mungkin, tapi risikonya kita tanggung sendiri dan wajib diimbangi backup ke luar server.
3.2 Pemisahan Port dan Layer
Silo memisahkan dua jalur trafik ke dua port berbeda, dan pemisahan ini yang nanti menentukan bentuk konfigurasi Nginx kita.
- Port
9000melayani S3 API. Ini endpoint yang dipakai aplikasi, SDK, dan client CLI. - Port
9001melayani web console. Port ini kita tentukan sendiri lewat flag--console-address ":9001". Tanpa flag tersebut, console memakai port acak yang berganti setiap kali server dinyalakan, yang tentu merepotkan untuk reverse proxy.

Di depan keduanya kita letakkan Nginx sebagai lapisan ketiga yang menangani terminasi TLS dan routing berbasis nama domain. Pola tiga lapis ini membuat container Silo cukup mendengarkan di localhost, sementara dunia luar hanya berbicara ke Nginx.
Perlu diingat, pemisahan port bukan pemisahan hak akses. Console dan S3 API memakai basis identity yang sama, jadi membatasi salah satunya di lapisan jaringan tidak otomatis mengamankan yang lain.
3.3 Kebutuhan Hardware
Dokumentasi resmi Silo menerbitkan angka acuan untuk deployment produksi berbasis baremetal maupun virtual host. Tabel berikut merangkum baris-baris utamanya.
| Komponen | Minimum | Rekomendasi |
|---|---|---|
| Host baremetal atau virtual khusus | 4 host | 8 host atau lebih |
| Drive per server | 4 drive | 8 drive atau lebih |
| Jaringan | 25GbE | 100GbE |
| CPU per host | 8 CPU atau vCPU | 16 CPU atau vCPU ke atas |
| Memori tersedia per host | 32 GB | 128 GB ke atas |
Kebutuhan memori juga naik mengikuti kapasitas penyimpanan yang dikelola satu host, bukan sekadar mengikuti jumlah request.
| Total storage per host | Memori yang disarankan |
|---|---|
| Sampai 1 TiB | 8 GB |
| Sampai 10 TiB | 16 GB |
| Sampai 100 TiB | 32 GB |
| Sampai 1 PiB | 64 GB |
| Lebih dari 1 PiB | 128 GB |
Jaringan justru dianggap faktor paling menentukan performa, bukan CPU. Jumlah request bersamaan yang sanggup dilayani dibatasi memori, mengikuti perhitungan kasar totalRam / ramPerRequest. Dokumentasi memuat tabel rujukan yang memetakan jumlah drive dan RAM bebas ke jumlah request bersamaan, dengan rentang mulai sekitar 1.074 request pada konfigurasi 4 drive dengan RAM 32 GB sampai sekitar 17.190 request pada 4 drive dengan RAM 512 GB. Angka-angka ini disebut sebagai garis dasar, bukan pengganti uji performa pada beban nyata.
Seluruh tabel di atas ditulis untuk produksi terdistribusi dan jelas berlebihan untuk satu server SNSD di home lab. Sebagai patokan praktis, bukan sebagai spesifikasi resmi, satu instance SNSD untuk backup dan media storage skala kecil umumnya nyaman di 1 sampai 2 CPU core dengan RAM 1 sampai 2 GB, sedangkan 2 sampai 4 core dengan RAM 4 sampai 8 GB memberi ruang lebih lega untuk upload paralel. Angka ini perlu kita uji ulang sesuai beban nyata masing-masing, karena dokumentasi resmi tidak menerbitkan baseline khusus untuk skenario satu node.
Beberapa syarat penyimpanan berikut bersifat mutlak dan berlaku di semua skala:
- Silo harus punya akses eksklusif ke drive atau volume yang dipakainya. Jangan berbagi direktori data dengan proses lain, dan jangan menyunting isinya secara manual.
- Dokumentasi menyarankan drive berformat XFS yang disajikan sebagai JBOD, tanpa lapisan RAID atau pooling di bawahnya. Erasure coding sudah menangani redundansi, sehingga RAID di bawahnya hanya menambah biaya tulis tanpa manfaat berarti.
- Silo tidak dapat menjamin konsistensi data di atas NFS atau network-attached storage sejenis. Pakai disk lokal.
Untuk sisi perangkat lunak, kita butuh Linux (Ubuntu, Debian, atau Rocky Linux), Docker beserta plugin Compose, Nginx, serta satu domain atau subdomain yang mengarah ke server. Contoh pada artikel ini mengacu pada Ubuntu Server 26.04 LTS dan rilis Silo RELEASE.2026-09-16T00-00-00Z. Sesuaikan tag rilis dengan versi terbaru saat artikel ini dipraktikkan.
Dapatkan Kredit DigitalOcean $25
Klaim Kredit $254. Instalasi Docker Compose
4.1 Pemasangan Docker Engine
Server yang belum punya Docker Engine bisa memakai skrip instalasi resmi dari Docker. Skrip ini mendeteksi distribusi, menambahkan repositori resmi, lalu memasang engine beserta plugin Compose dalam satu jalan.
Unduh skrip dan periksa dulu rencana kerjanya tanpa mengubah apa pun:
curl -fsSL https://get.docker.com -o get-docker.sh sudo sh ./get-docker.sh --dry-runMode
--dry-runmencetak perintah yang akan dijalankan. Kebiasaan membaca dulu isi skrip yang dijalankan sebagai root layak dipertahankan, apalagi skrip yang diunduh dari internet.Jalankan pemasangannya:
sudo sh get-docker.shPastikan service aktif dan ikut menyala saat boot:
sudo systemctl enable --now dockerVerifikasi engine beserta plugin Compose:
sudo docker version sudo docker compose version
Docker sendiri memberi beberapa peringatan soal skrip ini, dan semuanya relevan untuk server produksi. Skrip butuh hak root, memasang dependensi tanpa konfirmasi, hampir tidak menyediakan parameter yang bisa disesuaikan, selalu mengambil rilis stabil terbaru sehingga berpotensi menaikkan versi mayor secara tidak sengaja, serta tidak dirancang untuk mengupgrade instalasi Docker yang sudah ada. Server yang sudah punya Docker sebaiknya diupgrade lewat package manager, bukan lewat skrip ini.
Perintah Docker secara bawaan menuntut hak root. Menambahkan user ke grup docker memang menghapus keharusan mengetik sudo, tapi anggota grup itu praktis setara root karena bisa me-mount direktori mana pun ke dalam container. Artikel ini memakai sudo secara eksplisit pada setiap perintah Docker.
4.2 Penyiapan Disk Data
Object storage pantas menempati disk tersendiri, terpisah dari disk sistem. Pemisahan ini mencegah data yang tumbuh liar ikut memenuhi partisi root lalu membuat seluruh server tersendat, sekaligus memudahkan kita menambah kapasitas tanpa menyentuh sistem operasi. Contoh berikut memakai volume storage 100 GB yang dilampirkan ke sebuah cloud server dan terbaca sebagai /dev/sda.
Petakan dulu disk yang tersedia beserta titik mount-nya:
lsblkContoh keluaran pada server yang kita pakai:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 100G 0 disk vda 253:0 0 25G 0 disk ├─vda1 253:1 0 23.9G 0 part / ├─vda13 253:13 0 1023M 0 part /boot ├─vda14 253:14 0 4M 0 part └─vda15 253:15 0 106M 0 part /boot/efi vdb 253:16 0 488K 1 diskBaca keluaran itu dari bawah ke atas. Disk
vdaberukuran 25 GB adalah disk sistem, terlihat dari partisinya yang memegang/,/boot, dan/boot/efi. Diskvdbberukuran 488 KB adalah perangkat kecil bawaan penyedia cloud yang biasanya berisi metadata instance, dan tidak boleh disentuh. Sisanyasdaberukuran 100 GB tanpa partisi maupun mount point, dan inilah target kita.Pastikan disk target benar-benar kosong sebelum ditimpa:
sudo wipefs /dev/sdaPerintah tanpa flag hanya menampilkan tanda tangan filesystem yang terdeteksi, tanpa mengubah apa pun. Keluaran yang kosong berarti disk memang belum berisi filesystem. Keluaran yang justru menampilkan sesuatu berarti disk itu masih memuat data, jadi berhenti dan periksa ulang sebelum melanjutkan.
Pasang perkakas partisi dan utility XFS bila belum tersedia:
sudo apt install parted xfsprogsPaket
xfsprogsmenyediakanmkfs.xfsbeserta perkakas perawatannya. Pilihan XFS bukan selera pribadi: dokumentasi Silo memang menyarankan drive berformat XFS yang disajikan sebagai JBOD, tanpa lapisan RAID atau pooling di bawahnya.Buat tabel partisi GPT beserta satu partisi yang memakai seluruh kapasitas disk:
sudo parted /dev/sda --script mklabel gpt mkpart primary xfs 0% 100%Penulisan
0%dan100%membuat parted menyelaraskan awal partisi ke batas yang tepat, jauh lebih aman daripada menyebut nomor sektor secara manual. Kataprimaryhanya menjadi label pada tabel GPT.Periksa hasilnya, dan pastikan partisi
sda1sudah muncul:lsblk /dev/sdaFormat partisi tersebut sebagai XFS:
sudo mkfs.xfs /dev/sda1Perintah ini menghapus seluruh isi partisi, jadi baca sekali lagi nama perangkat yang diketik sebelum menekan enter. Salah menunjuk
vda1berarti memformat disk sistem.Siapkan titik mount lalu pasang partisinya:
sudo mkdir -p /srv/silo sudo mount /dev/sda1 /srv/siloPastikan filesystem benar-benar terpasang dan tipenya sesuai:
df -hT /srv/siloKolom tipe harus menunjukkan
xfsdengan kapasitas mendekati 100 GB.Ambil UUID partisi sebagai penanda permanen:
sudo blkid -s UUID -o value /dev/sda1Nama perangkat seperti
/dev/sda1bisa bergeser saat urutan deteksi disk berubah, misalnya setelah volume lain dilampirkan. UUID tidak ikut bergeser, jadi inilah yang kita pakai pada konfigurasi mount permanen.Daftarkan mount permanen di
/etc/fstab. Sunting berkasnya, lalu tambahkan satu baris di bagian bawah dengan UUID hasil langkah sebelumnya:sudo nano /etc/fstabUUID=ganti-dengan-uuid-hasil-blkid /srv/silo xfs defaults,noatime,nofail 0 0Uji konfigurasi tanpa perlu reboot:
sudo systemctl daemon-reload sudo umount /srv/silo sudo mount -a findmnt /srv/siloPerintah
mount -amemasang seluruh entri/etc/fstabyang belum terpasang, sehingga kesalahan penulisan langsung ketahuan sekarang, bukan nanti saat server gagal boot. Keluaranfindmntyang menampilkan sumber/dev/sda1menandakan konfigurasi sudah benar.
Tiga opsi mount pada baris fstab di atas dipilih dengan alasan masing-masing:
noatimemematikan pembaruan waktu akses setiap kali berkas dibaca. Object storage banyak melakukan operasi baca, dan penulisan metadata yang tidak perlu itu hanya menambah beban tulis tanpa manfaat.nofailmembuat proses boot tetap berjalan meski volume belum terpasang. Opsi ini penting pada cloud server, karena volume yang terlepas atau terlambat terdeteksi dapat menahan boot sampai batas waktu habis dan menyisakan server yang tidak bisa diakses.- Angka
0 0di akhir baris mematikan dump dan pemeriksaan saat boot. XFS memang tidak mengandalkan pemeriksaan boot semacam itu, karenafsck.xfshanya program kosong yang selalu melaporkan sukses. Perbaikan XFS dilakukan manual memakaixfs_repairpada filesystem yang sedang tidak terpasang.
Server yang memakai beberapa drive untuk mode SNMD mengulang seluruh langkah di atas untuk setiap disk, dengan titik mount berpola seperti /mnt/drive-1 sampai /mnt/drive-4, lalu memetakan masing-masing ke dalam container secara terpisah.
4.3 Persiapan Direktori
Disk sudah siap, jadi kita lanjut ke struktur direktori di atasnya. Memisahkan berkas konfigurasi dari volume data memudahkan backup dan upgrade di kemudian hari.
Buat direktori kerja untuk berkas Compose. Direktori ini cukup berada di disk sistem karena isinya hanya berkas teks:
sudo mkdir -p /opt/siloBuat direktori data di dalam disk yang tadi dipasang, yang nanti di-mount ke dalam container:
sudo mkdir -p /srv/silo/dataPastikan direktori data benar-benar berada di disk baru, bukan di partisi root:
df -h /srv/silo/dataKolom filesystem harus menunjuk
/dev/sda1. Bila yang muncul justru partisi root, kemungkinan besar direktori terlanjur dibuat sebelum disk terpasang, sehingga isinya tertutup oleh mount point.
Catat juga kepemilikan direktori data memakai ls -ld /srv/silo/data. UID dan GID yang tidak cocok dengan proses di dalam container adalah penyebab paling umum Silo gagal menulis saat pertama kali dinyalakan.
4.4 Berkas docker-compose.yml
Seluruh definisi layanan Silo tinggal di satu berkas. Buat berkasnya di direktori kerja yang tadi disiapkan:
Pastikan direktori kerja sudah ada, lalu masuk ke dalamnya:
sudo mkdir -p /opt/silo cd /opt/siloBuat dan buka berkas Compose memakai editor teks:
sudo nano /opt/silo/docker-compose.ymlEditor
nanotersedia secara bawaan di Ubuntu Server. Setelah isinya diketik, simpan denganCtrl+OlaluEnter, dan keluar denganCtrl+X.
Berikut isi berkas docker-compose.yml untuk deployment SNSD, disusun mengikuti contoh resmi Silo dengan penyesuaian pada volume, binding port, dan health check.
services:
silo:
image: docker.io/pgsty/silo:RELEASE.2026-09-16T00-00-00Z
container_name: silo
restart: unless-stopped
command: server /data --console-address ":9001"
ports:
- "127.0.0.1:9000:9000"
- "127.0.0.1:9001:9001"
environment:
MINIO_ROOT_USER: silo-admin
MINIO_ROOT_PASSWORD: ganti-dengan-secret-yang-kuat
MINIO_BROWSER_REDIRECT_URL: https://console.example.com/
volumes:
- /srv/silo/data:/data
healthcheck:
test: ["CMD", "/usr/bin/silo", "healthcheck", "ready"]
interval: 30s
timeout: 10s
retries: 3
start_period: 2mBeberapa bagian layak dibedah satu per satu, karena di sinilah kesalahan paling sering terjadi.
MINIO_ROOT_USERdanMINIO_ROOT_PASSWORD. Silo sengaja mempertahankan awalanMINIO_pada seluruh variabel lingkungan demi kompatibilitas. Tidak ada variabel bernamaSILO_ROOT_USER. Kredensial ini adalah akun root deployment, jadi perlakukan seperti password root server dan ganti sebelum container pertama kali dijalankan.- Tag image yang dikunci. Rilis Silo memakai format tanggal, misalnya
RELEASE.2026-09-16T00-00-00Z. Tag bergulir sepertilatestmemang tersedia, tapi menyebut tag eksplisit membuat restart container tidak diam-diam menarik versi baru. Silo juga menonaktifkan self-update di dalam proses server, sehingga upgrade dilakukan dengan mengganti tag image. - Binding ke
127.0.0.1. Port sengaja diikat ke loopback supaya S3 API dan console tidak terekspos langsung ke internet. Hanya Nginx di mesin yang sama yang boleh menjangkaunya. Tanpa pembatasan ini, attacker bisa melewati lapisan TLS dan memukul port9000secara langsung. Perlu diingat, publikasi port oleh Docker menulis aturan langsung ke tabelnatiptables dan kerap melewati aturan ufw, jadi binding loopback jauh lebih andal daripada mengandalkan firewall saja. MINIO_BROWSER_REDIRECT_URL. Variabel ini memberi tahu console alamat publik tempat ia dilayani. Nilainya wajib diisi saat console berada di balik reverse proxy, jika tidak proses login akan melempar pengguna ke alamat internal yang tidak bisa dijangkau browser. Sesuaikanconsole.example.comdengan domain sebenarnya. Selama Nginx dan sertifikat belum siap, akses console lewat domain memang belum berfungsi; verifikasi tahap ini cukup lewat endpoint health.- Volume bind mount. Penggunaan
/srv/silo/datamemudahkan kita memeriksa dan mem-backup data dari host. Contoh resmi memakai named volume, dan keduanya sama-sama sah selama datanya persisten. - Blok
healthcheck. Silo membawa subperintah health check bawaan di dalam binary servernya, sehingga container bisa memeriksa dirinya sendiri tanpa binary tambahan. Pilihan pemeriksaannyalive,ready,cluster, dancluster-read. Nilaistart_periodyang longgar mencegah container dinyatakan tidak sehat saat proses pemindaian awal disk masih berjalan.
Dua hal yang sengaja tidak dipasang juga perlu dijelaskan. Variabel MINIO_UPDATE=off muncul di banyak contoh warisan MinIO, tapi di Silo pembaruan mandiri sudah dinonaktifkan di dalam proses server dan variabel tersebut tidak mengaktifkannya kembali. Selain itu tersedia varian image distroless bertag RELEASE.2026-09-16T00-00-00Z-distroless yang hanya berisi binary silo, tanpa shell maupun package manager. Varian itu memperkecil permukaan serangan, tapi menutup kemungkinan masuk ke container untuk diagnosis, jadi lebih cocok setelah konfigurasi kita mapan.
Satu catatan tentang path pada blok health check: contoh resmi memakai /usr/bin/silo. Bila container justru dinyatakan tidak sehat padahal servernya jelas melayani, periksa lokasi binary di dalam image yang kita pakai dengan sudo docker compose exec silo which silo, lalu sesuaikan path tersebut.
4.5 Menjalankan dan Verifikasi Container
Setelah berkas tersimpan, jalankan langkah berikut secara berurutan dari direktori /opt/silo.
Nyalakan container di latar belakang:
sudo docker compose up -dPeriksa status container:
sudo docker compose psKolom status harus menunjukkan container dalam keadaan berjalan dan sehat, bukan restarting. Status yang berputar-putar biasanya menandakan salah ketik pada
commandatau direktori data yang tidak bisa ditulisi.Baca log untuk memastikan server siap melayani:
sudo docker compose logs -f siloLog startup menampilkan alamat S3 API dan alamat console yang aktif. Tekan
Ctrl+Cuntuk keluar dari mode ikuti log.Uji endpoint liveness dari host:
curl -I http://127.0.0.1:9000/minio/health/liveEndpoint ini mengembalikan
200 OKsaat proses server sedang melayani. Respons selain itu berarti server belum siap atau tidak terjangkau.
Silo menyediakan beberapa endpoint health dengan cakupan berbeda, dan memilih yang tepat menghindari alarm palsu:
/minio/health/livemenjawab satu pertanyaan saja, yaitu apakah proses ini sedang melayani. Inilah yang pantas dipakai sebagai probe per container./minio/health/clustermemeriksa kuorum tulis tingkat cluster dan mengembalikan503saat kuorum tidak terpenuhi./minio/health/cluster/readmemeriksa kuorum baca, juga dengan503sebagai penanda gagal./minio/health/cluster?maintenance=truememeriksa apakah cluster tetap punya kuorum bila node ini dimatikan untuk perawatan, dan mengembalikan412bila jawabannya tidak.
Perlu digarisbawahi, live dan ready hanya sinyal tingkat proses. Keduanya tidak menjamin node benar-benar sanggup melayani object, jadi pemantauan produksi tetap butuh endpoint cluster dan metrics.
Sampai tahap ini Silo sudah hidup, tapi hanya bisa diakses dari dalam server. Lapisan berikutnya yang membuatnya berguna dari luar.
5. Nginx Reverse Proxy dan SSL
5.1 Alasan Memakai Reverse Proxy
Menaruh Nginx di depan Silo memberi empat keuntungan yang sulit didapat dari container saja.
- Terminasi TLS di satu tempat. Sertifikat cukup dikelola dan diperpanjang di lapisan proxy, tidak perlu ditanam ulang ke dalam container setiap kali kedaluwarsa.
- URL bersih tanpa nomor port. Client cukup menghafal
https://s3.example.comalih-alih alamat IP beserta port. - Permukaan serangan yang menyempit. Hanya port 80 dan 443 yang terbuka ke publik, sementara port aplikasi tetap di loopback.
- Ruang untuk kebijakan tambahan. Rate limiting, pembatasan IP, dan logging akses terpusat bisa diterapkan di lapisan ini.
Satu batasan penting dari dokumentasi resmi perlu digarisbawahi sejak awal: proses verifikasi signature S3 tidak bekerja jika Silo dilayani di sub-path seperti /s3/. S3 API harus berada di root sebuah domain atau subdomain khusus. Karena itu kita memakai dua subdomain terpisah, s3.example.com untuk API dan console.example.com untuk antarmuka web.
5.2 Pemasangan dan Server Block
Server yang belum menjalankan Nginx perlu memasangnya lebih dulu, lalu menyiapkan berkas konfigurasi khusus Silo.
Pasang Nginx dari repositori resmi distribusi:
sudo apt update sudo apt install nginxPastikan service berjalan dan ikut menyala setiap kali server boot:
sudo systemctl enable --now nginx sudo systemctl status nginxTekan
quntuk keluar dari tampilan status.Buat berkas konfigurasi khusus Silo:
sudo nano /etc/nginx/sites-available/silo.confSimpan dengan
Ctrl+OlaluEnter, dan keluar denganCtrl+X. Menaruh konfigurasi di berkas tersendiri, bukan menyunting/etc/nginx/nginx.conf, membuat kita bisa menonaktifkan seluruh konfigurasi Silo cukup dengan menghapus satu symlink.
Konfigurasi berikut mengadopsi contoh resmi Silo untuk pola dua subdomain, disederhanakan menjadi satu upstream per layanan karena kita hanya punya satu node. Inilah isi berkas /etc/nginx/sites-available/silo.conf yang barusan dibuat.
upstream silo_s3 {
server 127.0.0.1:9000;
}
upstream silo_console {
server 127.0.0.1:9001;
}
server {
listen 80;
listen [::]:80;
server_name s3.example.com;
ignore_invalid_headers off;
client_max_body_size 0;
proxy_buffering off;
proxy_request_buffering off;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 300;
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://silo_s3;
}
}
server {
listen 80;
listen [::]:80;
server_name console.example.com;
ignore_invalid_headers off;
client_max_body_size 0;
proxy_buffering off;
proxy_request_buffering off;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
real_ip_header X-Real-IP;
proxy_connect_timeout 300;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
chunked_transfer_encoding off;
proxy_pass http://silo_console/;
}
}Direktif-direktif di atas bukan sekadar salinan template. Berikut alasan di balik yang paling menentukan:
client_max_body_size 0;menghapus batas ukuran body request. Nilai bawaan Nginx hanya 1 MB, dan tanpa penyesuaian ini upload object besar akan ditolak dengan galat 413.proxy_buffering off;danproxy_request_buffering off;membuat Nginx meneruskan aliran data apa adanya, tanpa menampungnya lebih dulu di disk. Object berukuran puluhan gigabyte tidak akan menghabiskan ruang buffer sementara di/var/lib/nginx.ignore_invalid_headers off;menjaga header khusus S3 tetap diteruskan utuh, karena sebagian di antaranya ikut dihitung dalam signature request.proxy_set_header Host $http_host;mempertahankan nama host asli dari client. Skema AWS Signature V4 menghitung headerHostsebagai bagian dari signature, sehingga menggantinya membuat semua request ditolak dengan galat signature mismatch. Perhatikan pemakaian$http_host, bukan$host, karena$hostmembuang nomor port yang ikut ditandatangani client.chunked_transfer_encoding off;mencegah Nginx menambahkan encoding yang bisa merusak perhitungan signature pada body request.proxy_http_version 1.1;dipasangkan denganConnection ""pada blok S3 supaya koneksi keepalive ke upstream tetap hidup dan tidak diturunkan ke HTTP/1.0.- Pasangan
UpgradedanConnection "upgrade"pada blok console dibutuhkan agar koneksi WebSocket untuk monitoring dan trace di antarmuka web tetap hidup. proxy_connect_timeout 300;memberi kelonggaran pada operasi yang lambat merespons, misalnya listing bucket berisi jutaan object.
Aktifkan konfigurasi dan muat ulang Nginx:
Buat symlink ke direktori
sites-enabled:sudo ln -s /etc/nginx/sites-available/silo.conf /etc/nginx/sites-enabled/Nonaktifkan situs bawaan Nginx supaya halaman selamat datang tidak lagi melayani request yang nyasar:
sudo rm /etc/nginx/sites-enabled/defaultPerintah ini hanya menghapus symlink pengaktifnya. Berkas aslinya tetap tersimpan di
/etc/nginx/sites-available/defaultdan bisa diaktifkan lagi kapan saja.Uji sintaks konfigurasi sebelum menerapkannya:
sudo nginx -tMuat ulang Nginx tanpa memutus koneksi yang sedang berjalan:
sudo systemctl reload nginx
5.3 Sertifikat Let's Encrypt
Pastikan kedua subdomain sudah mengarah ke IP server dan port 80 terbuka, karena Certbot memverifikasi kepemilikan domain lewat HTTP.
Pasang Certbot beserta plugin Nginx:
sudo apt install certbot python3-certbot-nginxCertbot juga mendistribusikan versi snap yang biasanya lebih mutakhir. Pilih salah satu jalur saja, jangan memasang keduanya berdampingan.
Terbitkan sertifikat untuk kedua subdomain sekaligus:
sudo certbot --nginx -d s3.example.com -d console.example.comPlugin Nginx akan menyunting server block yang tadi kita buat, menambahkan blok
listen 443 sslbeserta path sertifikat, dan menawarkan pengalihan otomatis dari HTTP ke HTTPS. Terima tawaran pengalihan tersebut supaya client tidak pernah mengirim kredensial lewat jalur polos.Periksa hasil suntingan Certbot, lalu muat ulang:
sudo nginx -t && sudo systemctl reload nginxUji mekanisme perpanjangan otomatis:
sudo certbot renew --dry-runPaket Certbot memasang timer systemd yang menjalankan perpanjangan secara berkala, jadi tidak perlu menambahkan entri cron sendiri. Status timernya bisa dilihat lewat
systemctl list-timers | grep certbot.Pastikan nilai
MINIO_BROWSER_REDIRECT_URLpadadocker-compose.ymlsudah memakai skemahttps, lalu terapkan ulang:sudo docker compose up -d
Verifikasi akhir cukup dari terminal mana pun:
curl -I https://s3.example.com/minio/health/live5.4 Pembatasan Akses Firewall
Lapisan proxy baru berguna kalau tidak ada jalan pintas di sekitarnya. Kunci akses jaringan server ke tiga port saja.
Izinkan SSH dan profil aplikasi Nginx yang mencakup port 80 serta 443:
sudo ufw allow OpenSSH sudo ufw allow 'Nginx Full'Aktifkan firewall dan periksa hasilnya:
sudo ufw enable sudo ufw status verbosePastikan port aplikasi benar-benar tertutup dari luar. Jalankan dari mesin lain:
curl -m 5 -I http://s3.example.com:9000/minio/health/liveKoneksi yang gagal atau kehabisan waktu justru hasil yang kita harapkan. Respons
200berarti port9000masih terbuka ke publik dan binding loopback pada berkas Compose perlu diperiksa ulang.
Pemeriksaan pada langkah ketiga bukan formalitas. Docker menulis aturan port publikasi langsung ke tabel nat iptables pada chain DOCKER, yang diproses sebelum aturan ufw, sehingga container yang mem-publish port ke 0.0.0.0 tetap bisa dijangkau meski ufw tampak memblokirnya. Binding ke 127.0.0.1 menutup celah itu di sumbernya.
6. Pengelolaan Object lewat Console
6.1 Login Pertama Kali
Buka https://console.example.com di browser. Silo Console adalah antarmuka grafis yang tertanam langsung di dalam server, dengan cakupan kemampuan yang sebanding dengan client baris perintah. Chrome, Edge, Safari, Firefox, dan Opera termasuk browser yang didukung, kecuali Opera Mini.
Halaman login menerima kredensial root yang tadi kita set lewat MINIO_ROOT_USER dan MINIO_ROOT_PASSWORD. Saat identity provider eksternal dikonfigurasi, halaman yang sama menyediakan dropdown untuk memilih metode autentikasi lain.
Setelah masuk, halaman pertama yang tampil adalah object browser, berisi daftar bucket yang boleh diakses akun tersebut. Daftar ini mengikuti policy, jadi akun terbatas hanya melihat bucket yang memang menjadi haknya.
Kebiasaan yang baik sejak hari pertama: pakai akun root hanya untuk membuat user dan policy, lalu beralih ke akun terbatas untuk pekerjaan sehari-hari. Kredensial root sebaiknya tidak pernah menyentuh berkas konfigurasi aplikasi. Console juga bisa dimatikan sepenuhnya lewat MINIO_BROWSER=off bila server hanya melayani lalu lintas API.
6.2 Pembuatan Bucket Pertama
Bucket adalah wadah teratas tempat object disimpan. Pembuatannya lewat console berjalan singkat, tapi ada satu keputusan yang tidak bisa diralat belakangan.
- Dari object browser, pilih Create Bucket.
- Isi nama bucket. Pakai huruf kecil, angka, dan tanda hubung saja, misalnya
backup-postgresataumedia-assets. Nama bucket ikut muncul di URL object, jadi pilih yang deskriptif sejak awal. - Aktifkan Versioning bila bucket akan menyimpan data yang perlu bisa dipulihkan setelah tertimpa atau terhapus.
- Aktifkan Object Locking bila ada kebutuhan kepatuhan yang melarang object diubah atau dihapus selama periode tertentu. Opsi ini menuntut versioning aktif.
- Isi Quota bila ingin membatasi ukuran total bucket, dan atur Retention bila butuh periode retensi minimum.
- Simpan, lalu bucket langsung muncul di daftar.
Inilah bagian yang perlu digarisbawahi: dokumentasi resmi menyatakan opsi replikasi, locking, dan versioning wajib ditentukan saat bucket dibuat dan tidak bisa diubah setelahnya. Salah pilih di tahap ini berarti membuat bucket baru lalu memindahkan isinya, yang jauh lebih mahal daripada berpikir sebentar di awal.
Versioning yang menyala juga menuntut pasangannya, yaitu aturan lifecycle. Bucket dengan versioning aktif tanpa aturan kedaluwarsa akan tumbuh terus meski isi logisnya tetap, karena setiap penimpaan menyisakan versi lama. Aturan lifecycle diatur belakangan lewat tab tersendiri, dan biasanya cukup satu aturan yang menghapus versi non-current setelah 30 atau 90 hari.
6.3 Upload dan Pengaturan Object
Masuk ke bucket yang baru dibuat untuk mulai mengisi data. Tombol upload berada di sisi kanan atas object browser dan menerima berkas maupun folder. Selama proses berjalan, ikon pengelola object di pojok kanan atas menampilkan progres upload dan download sepanjang sesi berlangsung.
- Pilih bucket tujuan dari daftar.
- Gunakan tombol upload untuk memilih berkas, atau pilih opsi folder untuk mengunggah satu direktori sekaligus. Object browser juga menyediakan pembuatan folder sebagai prefix.
- Klik salah satu object untuk membuka panel detailnya, yang menampilkan nama, ukuran, tag, hold, aturan retensi yang berlaku, serta metadata object.
Halaman detail bucket menyediakan beberapa tab yang menampung pengaturan paling sering dipakai sehari-hari:
- Summary untuk melihat dan mengubah access policy, enkripsi, quota, serta tag bucket.
- Events untuk memasang notifikasi yang terpicu saat object dibuat, diakses, atau dihapus.
- Lifecycle untuk menyusun aturan kedaluwarsa atau transisi object ke tier penyimpanan lain.
- Replication untuk replikasi bucket di sisi server.
- Access untuk meninjau policy dan user yang punya hak atas bucket tersebut.
- Anonymous untuk mengatur akses tanpa autentikasi pada bucket atau prefix tertentu.
Tab Anonymous pantas diperlakukan dengan hati-hati. Aturan di sana membuka object ke siapa pun yang tahu URL-nya, tanpa kredensial sama sekali. Pemakaian yang wajar biasanya terbatas pada prefix aset publik, misalnya media-assets/public/, bukan pada seluruh bucket.
6.4 Berbagi Tautan Object
Kebutuhan berbagi satu berkas ke pihak luar tidak perlu dijawab dengan membuka bucket ke publik. Silo menyediakan presigned URL, yaitu tautan yang sudah membawa kredensial tertanam dan berhenti berlaku setelah tenggat tertentu.
Dari console, pilih object yang dimaksud lalu gunakan opsi berbagi pada panel detailnya, dan tentukan masa berlakunya. Jalur yang sama tersedia dari baris perintah dan lebih mudah diulang untuk banyak berkas:
mcli share download --expire 48h silo/media-assets/laporan-q3.pdfBeberapa hal yang perlu diketahui sebelum menyebarkan tautan semacam ini:
- Masa berlaku bawaan adalah 168 jam alias 7 hari bila flag
--expiretidak disebutkan. Format durasinya mengikuti pola##h##m##s, dan penulisan seperti30djuga diterima. - Tautan berlaku untuk siapa pun yang memegangnya selama belum kedaluwarsa. Perlakukan sebagai rahasia, bukan sebagai tautan biasa.
- Menambahkan flag
--recursivemembuat tautan untuk seluruh object dalam sebuah bucket atau prefix sekaligus. - Pada bucket dengan versioning aktif, flag
--version-idmenunjuk versi object tertentu. - Arah sebaliknya juga tersedia lewat
mcli share upload, yang menghasilkan URL presigned untuk mengunggah object memakai metode PUT. Cara ini berguna saat pihak luar perlu mengirim berkas tanpa kita beri kredensial.
Untuk aset yang memang harus terbuka permanen, misalnya gambar di halaman publik, kebijakan anonymous lebih tepat daripada presigned URL yang harus diperbarui terus:
mcli anonymous set download silo/media-assets/publicPerintah tersebut membuka akses baca tanpa autentikasi hanya pada prefix public. Nilai lain yang tersedia adalah upload untuk tulis saja, public untuk baca sekaligus tulis, dan none untuk mencabut seluruhnya. Hindari public pada bucket yang dapat dijangkau internet, karena nilai itu mengizinkan siapa pun menulis object ke dalamnya. Daftar tautan publik yang dihasilkan bisa dilihat lewat mcli anonymous links silo/media-assets/public.
6.5 Access Key dan Identity
Bagian keamanan console mencakup pengelolaan access key, akun user beserta keanggotaan grup, policy, dan konfigurasi identity provider.
Aplikasi pihak ketiga sebaiknya memakai pasangan access key dan secret key yang dibuat khusus, bukan kredensial root. Secret key hanya ditampilkan sekali saat pembuatan dan tidak bisa dipulihkan, jadi simpan langsung ke pengelola rahasia yang kita pakai.
Kontrol akses Silo mengikuti model PBAC (Policy-Based Access Control) yang memakai dokumen policy JSON bergaya IAM. Tersedia empat policy bawaan, yaitu readonly, readwrite, writeonly, dan diagnostics, dan kita bisa menambahkan policy sendiri. Terapkan prinsip hak akses minimum: satu aplikasi backup cukup diberi izin tulis ke satu bucket, tanpa hak menghapus bucket lain atau membaca seluruh deployment.
User yang baru dibuat sama sekali tidak punya policy, sehingga belum bisa melakukan apa pun sampai sebuah policy dilampirkan atau user tersebut dimasukkan ke grup yang sudah punya policy. Perilaku ini aman secara bawaan, tapi kerap disalahartikan sebagai kredensial yang rusak.
7. Integrasi lewat mcli dan SDK
7.1 Instalasi Client mcli
Pigsty mendistribusikan client resminya dengan nama mcli. Sintaksnya identik dengan mc milik MinIO, sehingga skrip lama umumnya cukup diganti nama perintahnya.
Pemasangan binary standalone di Linux x86_64 berjalan dalam empat langkah.
Unduh arsip rilis dari repositori resmi:
curl -fLO https://github.com/pgsty/mc/releases/download/RELEASE.2026-09-16T00-00-00Z/mcli_20260916000000.0.0_linux_amd64.tar.gzCocokkan checksum dengan berkas SHA-256 yang diterbitkan pada halaman rilis yang sama:
sha256sum mcli_20260916000000.0.0_linux_amd64.tar.gzEkstrak arsipnya:
tar -xzf mcli_20260916000000.0.0_linux_amd64.tar.gzPasang binary ke direktori yang ada di
PATH:sudo install -m 0755 mcli /usr/local/bin/mcli
Pengguna distribusi berbasis paket bisa memilih berkas .deb untuk Debian dan Ubuntu, .rpm untuk RHEL, Rocky, dan Alma, atau .apk untuk Alpine, semuanya tersedia pada rilis yang sama. Versi macOS untuk Intel maupun Apple Silicon serta versi Windows juga diterbitkan.
7.2 Penyiapan Access Key
Client membutuhkan sepasang kredensial sebelum bisa menyentuh server. Access key berperan seperti nama pengguna, sedangkan secret key berperan seperti kata sandinya. Keduanya dikirim pada setiap request dan dipakai menghitung signature, jadi keduanya harus sudah ada sebelum alias didaftarkan.
Ada dua jalan memperolehnya, dan pilihannya menentukan seberapa besar risiko yang kita tanggung.
Jalan pertama memakai kredensial root yang tadi disetel lewat MINIO_ROOT_USER dan MINIO_ROOT_PASSWORD. Pasangan itu memang sah dipakai sebagai access key dan secret key, tapi hak aksesnya penuh atas seluruh deployment. Pakai hanya untuk perkenalan awal atau untuk membuat identity yang sebenarnya, jangan untuk pekerjaan rutin apalagi untuk skrip otomatis.
Jalan kedua, dan inilah yang dianjurkan, menerbitkan access key tersendiri lewat console. Kredensial semacam ini bisa dicabut kapan saja tanpa mengganggu akun lain.
- Login ke
https://console.example.commemakai kredensial root. - Buka bagian Access Keys, lalu pilih Create Access Key.
- Biarkan access key dan secret key dibuat otomatis, atau isi sendiri bila memakai pola penamaan tertentu. Beri nama dan keterangan yang menjelaskan pemakaiannya, misalnya
workstation sysadmin. - Batasi masa berlakunya bila kredensial itu hanya dipakai sementara.
- Salin kedua nilai sebelum menutup dialog. Secret key hanya ditampilkan satu kali dan tidak bisa dipulihkan.
Cara yang sama bisa ditempuh dari baris perintah, tapi menuntut alias yang sudah terdaftar lebih dulu. Urutan yang rapi untuk server baru: daftarkan alias sementara memakai kredensial root, buat user beserta policy-nya seperti pada subbab 7.5, lalu timpa alias tersebut dengan kredensial yang hak aksesnya terbatas.
Satu catatan tentang access key yang dibuat lewat console: kredensial itu mewarisi izin akun yang menerbitkannya. Access key yang dibuat saat login sebagai root tetap membawa hak penuh, jadi untuk aplikasi tetap buat user tersendiri dengan policy terbatas.
7.3 Alias dan Perintah Dasar
Setelah kredensial di tangan, daftarkan alias, yaitu nama pendek yang mewakili endpoint beserta kredensialnya. Ganti kedua nilai di bawah dengan access key dan secret key hasil langkah sebelumnya.
mcli alias set silo https://s3.example.com ACCESS_KEY SECRET_KEYPeriksa hasilnya, lalu lihat daftar alias yang sudah terdaftar:
mcli alias list
mcli ls silo/Perintah mcli ls yang mengembalikan daftar bucket, atau keluaran kosong pada server yang memang masih kosong, menandakan kredensial sudah diterima. Pesan Access Denied berarti kredensialnya benar tapi policy-nya belum mengizinkan apa pun, sedangkan SignatureDoesNotMatch menunjuk ke secret key yang salah atau ke konfigurasi proxy seperti yang dibahas pada subbab 9.1.
Alias tersimpan di berkas konfigurasi client dan berisi secret key dalam bentuk yang bisa dibaca. Batasi izin direktori konfigurasi tersebut pada server yang dipakai bersama, dan pertimbangkan akun sistem terpisah untuk proses backup otomatis. Mengganti kredensial cukup dengan menjalankan ulang mcli alias set memakai nama alias yang sama, sedangkan mcli alias remove silo menghapusnya.
7.4 Upload dan Akses Object
Alur kerja sehari-hari berkisar pada empat perintah: membuat bucket, mengunggah, menelusuri, dan mengunduh.
Buat bucket baru:
mcli mb silo/backup-postgresUnggah satu berkas. Tanda garis miring di akhir tujuan menandakan bucket atau prefix, bukan nama object:
mcli cp dump.sql.gz silo/backup-postgres/Unggah satu direktori beserta isinya:
mcli cp --recursive /var/www/uploads/ silo/media-assets/Periksa hasilnya, lengkap dengan ukuran dan waktu unggah:
mcli ls silo/backup-postgres/ mcli stat silo/backup-postgres/dump.sql.gz
Mengambil kembali object memakai perintah yang sama dengan arah terbalik, karena mcli cp menerima sumber dan tujuan dalam bentuk path lokal maupun path bucket.
mcli cp silo/backup-postgres/dump.sql.gz /tmp/
mcli cp --recursive silo/media-assets/ /var/www/uploads/
mcli cat silo/backup-postgres/catatan.txtPerintah mcli mirror pantas mendapat perhatian khusus untuk pekerjaan backup. Perintah ini menyinkronkan direktori sumber ke bucket tujuan, sehingga cocok dijalankan berkala lewat cron atau timer systemd:
mcli mirror /var/www/uploads silo/media-assetsUji dulu setiap pola sinkronisasi baru pada bucket percobaan, terutama bila kita berniat menambahkan flag penghapusan, karena mirror bisa menghapus object di tujuan agar cocok dengan sumber. Perlakukan mcli rm dengan hati-hati juga, karena penghapusan pada bucket tanpa versioning bersifat permanen:
mcli rm silo/backup-postgres/dump-lama.sql.gz7.5 Perintah Administratif
Ekstensi mcli admin menangani pekerjaan di sisi server yang tidak tersentuh perintah object biasa. Alur membuat identity khusus aplikasi terdiri atas tiga perintah berurutan.
Buat user baru. Perintah ini menerima tiga argumen wajib, yaitu alias, access key yang berperan sebagai nama user, dan secret key-nya:
mcli admin user add silo backup-agent 'S3cret-Panjang-Dan-Acak'Dokumentasi menyarankan secret key yang unik, lebih dari 12 karakter, dan mencampur huruf, angka, serta simbol. Secret key ini tidak bisa dipulihkan kalau hilang.
Lampirkan policy, karena user baru belum punya izin apa pun:
mcli admin policy attach silo readwrite --user backup-agentFlag
--userdan--groupsaling meniadakan, jadi pilih salah satu. Beberapa policy bisa dilampirkan sekaligus dengan menyebutkannya berurutan.Terbitkan access key turunan bila aplikasi butuh kredensial berumur pendek:
mcli admin accesskey create silo backup-agent --name "cron backup harian" --expiry-duration 720hAccess key turunan tidak pernah bisa melampaui izin user induknya, sehingga aman dipakai sebagai kredensial yang dirotasi berkala.
Perintah mcli admin info silo menampilkan kondisi server dan menjadi titik awal pemeriksaan kesehatan rutin. Pada deployment terdistribusi, perintah ini melaporkan status setiap node.
Beberapa subperintah lain yang sering terpakai di lapangan: mcli admin heal untuk memindai dan memperbaiki object yang rusak, mcli admin logs untuk membaca log server, mcli admin group untuk mengelola grup, dan mcli admin service untuk merestart server. Struktur umumnya konsisten, yaitu mcli admin COMMAND ALIAS [ARGUMENTS].
Perhatikan bahwa policy attach hanya bekerja pada identity yang dikelola Silo sendiri. User yang datang dari OpenID atau LDAP memakai jalur perintah berbeda.
7.6 Akses dari SDK
Karena Silo mempertahankan S3 API, hampir semua tooling S3 yang sudah ada bisa langsung menunjuk ke endpoint kita. Kuncinya satu: arahkan endpoint kustom ke https://s3.example.com dan isi region dengan nilai apa pun yang konsisten, umumnya us-east-1.
Contoh pemakaian AWS CLI setelah kredensial dikonfigurasi:
aws --endpoint-url https://s3.example.com s3 ls
aws --endpoint-url https://s3.example.com s3 cp dump.sql.gz s3://backup-postgres/Client GUI seperti Cyberduck dan alat sinkronisasi seperti Rclone memakai pola yang sama, yakni memilih provider S3 generik lalu mengisi endpoint kustom. Aplikasi backend berbasis Node.js, Python, atau Go cukup memakai SDK S3 resmi masing-masing bahasa dengan parameter endpoint yang diarahkan ke server kita. Silo juga menyediakan halaman SDK tersendiri untuk Go, Python, .NET, Java, JavaScript, Haskell, dan Rust.
Satu penyesuaian yang kerap dibutuhkan pada beberapa SDK adalah mengaktifkan path-style addressing. Format virtual-host menaruh nama bucket di depan domain, misalnya https://media.s3.example.com, sehingga menuntut DNS wildcard beserta sertifikat wildcard yang belum tentu tersedia pada deployment satu server. Path-style menaruh nama bucket di path, yang jauh lebih sederhana untuk dilayani satu sertifikat biasa.
Presigned URL juga tetap bekerja seperti di MinIO, jadi pola berbagi tautan unduhan berbatas waktu dari sisi aplikasi tidak perlu diubah.
8. Migrasi dari Deployment MinIO
8.1 Pemeriksaan Sebelum Pindah
Deployment MinIO yang sudah berjalan tidak perlu ekspor dan impor object satu per satu. Layout object tetap kompatibel, termasuk direktori .minio.sys dan format erasure, sehingga disk data lama bisa dipakai langsung. Yang berpindah hanyalah image containernya.
Sebelum menyentuh apa pun, catat kondisi berjalan saat ini: digest image yang sedang dipakai, versi paket, status unit systemd, serta UID dan GID pemilik direktori data. Catatan ini yang nanti jadi jalan pulang kalau ada yang meleset.
Pastikan juga kondisi cluster sehat lewat mc admin info pada alias yang sudah ada, dan pastikan semua node online. Migrasi di atas cluster yang sedang pincang hanya menumpuk masalah.
8.2 Tabel Periksa Migrasi
Perbedaan antara yang bertahan dan yang berubah paling gampang dibaca dalam bentuk tabel. Gunakan daftar berikut sebagai lembar periksa sebelum menyentuh server produksi.
| Aspek | Status setelah migrasi | Tindakan yang perlu |
|---|---|---|
Data object dan direktori .minio.sys | Tetap kompatibel | Mount volume yang sama, tanpa ekspor impor |
| Bucket, versi object, user, policy, konfigurasi enkripsi | Tetap terpakai | Verifikasi ulang setelah container menyala |
| Hostname dan port endpoint (9000 dan console) | Tetap | Tidak ada |
Variabel lingkungan MINIO_* | Tetap | Tidak ada |
Route /minio/* dan header x-minio-* | Tetap | Tidak ada |
Namespace policy arn:minio:* | Tetap | Tidak ada |
SDK, mc/mcli, dan presigned URL | Tetap kompatibel | Uji satu aplikasi nyata sebagai sampel |
| Image container | Berubah | Ganti ke docker.io/pgsty/silo dengan tag rilis |
| Nama paket dan executable | Berubah | minio menjadi silo pada instalasi native |
| Direktori konfigurasi bawaan | Berubah | ~/.minio menjadi ~/.silo, tapi ~/.minio/certs lama tetap dihormati |
| Auto-update dan callhome SUBNET | Dinonaktifkan | Upgrade lewat penggantian tag image |
| Policy kustom dan tool admin buatan sendiri | Perlu diperiksa | Uji terpisah sebelum migrasi produksi |
| Branding, paginasi console, dan sebagian field respons API | Berbeda tampilan | Sesuaikan ekspektasi, tanpa perubahan teknis |
8.3 Penggantian Image
Sunting
docker-compose.ymldan ganti barisnya. Image lama bisa berupaminio/minio,quay.io/minio/minio, ataupgsty/minio, dan semuanya digantikan satu image:image: docker.io/pgsty/silo:RELEASE.2026-09-16T00-00-00ZTarik image baru lebih dulu supaya jeda layanan sependek mungkin:
sudo docker compose pullTerapkan perubahan:
sudo docker compose up -d
Satu peringatan yang wajib dipegang erat: jangan pernah menjalankan docker compose down -v dalam proses ini. Flag -v menghapus volume beserta seluruh object di dalamnya.
Peringatan kedua berlaku untuk cluster: semua node harus berpindah serentak. Mencampur binary lama dan baru membuat cluster tertahan di status activating disertai galat checksum mismatch. Perlakukan hal yang sama pada site replication, yakni koordinasikan upgrade antar-site alih-alih menaikkan satu per satu tanpa rencana.
8.4 Verifikasi dan Rollback
Migrasi belum selesai saat container menyala. Uji empat hal berikut sebelum menyatakan beres:
- Unduh satu object yang isinya sudah diketahui, lalu cocokkan checksum-nya.
- Jalankan satu aplikasi nyata lewat SDK yang biasa dipakainya.
- Restart layanan satu kali.
- Ulangi pemeriksaan integritas object setelah restart tersebut.
Rollback hanya realistis kalau digest image asli dan konfigurasi lama masih tersimpan, kombinasi versi tersebut sudah pernah diuji terpisah, serta penyimpanan IAM sudah diekspor lengkap. Beberapa rilis tidak mendukung penurunan versi secara bergulir, jadi baca catatan pemulihan versi terkait lebih dulu. Satu larangan mutlak: jangan pernah menjalankan node versi lama dan versi baru secara bersamaan di atas data yang sama.
Bagi yang berpindah dari rilis 6 Agustus 2026 atau sebelumnya, ada lima perubahan perilaku yang perlu diperiksa: penghapusan versi object secara eksplisit kini menuntut izin s3:DeleteObjectVersion, operasi enable dan disable dipisah menjadi aksi admin tersendiri, policy baru menolak prefix ARN telanjang seperti "arn:aws:s3:::", target notifikasi berbasis database butuh connection string eksplisit, serta CORS per bucket kini ditegakkan dan sebaiknya dikonfigurasi setelah seluruh node selesai upgrade.
8.5 Prosedur Upgrade Rutin
Upgrade Silo ke rilis berikutnya memakai alur yang sama seperti migrasi, hanya lebih ringkas. Ganti tag image ke rilis terverifikasi, tarik image, lalu terapkan ulang. Jalur pembaruan mandiri dari dalam server sengaja dimatikan, jadi tidak ada perintah update dari sisi client yang perlu dijalankan.
Biasakan membaca catatan rilis sebelum menaikkan versi, terutama bagian target rollback yang selalu didokumentasikan setiap rilis. Simpan juga digest image versi sebelumnya, karena tag saja tidak menjamin kita mendapatkan bit yang persis sama di kemudian hari.
9. Masalah Umum dan Penanganannya
9.1 Galat Signature Mismatch
Client menolak dengan pesan bernada SignatureDoesNotMatch padahal kredensial sudah benar. Akar masalahnya hampir selalu ada di lapisan proxy, karena skema AWS Signature V4 ikut menandatangani header Host beserta sejumlah header lain.
Periksa tiga hal berurutan: pastikan proxy_set_header Host $http_host; terpasang dan tidak memakai $host, pastikan ignore_invalid_headers off; ada sehingga header S3 tidak dibuang, dan pastikan S3 API dilayani di root subdomain, bukan di sub-path. Kalau ketiganya sudah benar, periksa selisih waktu antara client dan server, karena signature memuat timestamp dan akan ditolak bila jamnya melenceng terlalu jauh.
9.2 Upload Berhenti di Galat 413
Galat 413 Request Entity Too Large datang dari Nginx, bukan dari Silo. Nilai bawaan client_max_body_size hanya 1 MB, jauh di bawah ukuran object pada umumnya.
Pasang client_max_body_size 0; pada konteks server seperti pada contoh konfigurasi di bab 5. Bila galat tetap muncul, kemungkinan ada blok server atau location lain yang lebih spesifik dan menimpa nilai tersebut, atau berkas /etc/nginx/nginx.conf memasang nilai berbeda pada konteks http. Upload yang berhenti di tengah pada object besar biasanya soal lain, yaitu buffering yang belum dimatikan.
9.3 Console Gagal Login atau Redirect
Console yang memantulkan browser ke alamat internal, atau berputar di halaman login tanpa pernah masuk, umumnya berakar pada MINIO_BROWSER_REDIRECT_URL yang kosong atau tidak cocok dengan domain publik.
Samakan nilainya persis dengan URL yang diketik pengguna, lengkap dengan skema https dan garis miring penutup, lalu terapkan ulang container. Bila halaman termuat tapi grafik monitoring diam saja, periksa pasangan header Upgrade dan Connection "upgrade" pada blok console, karena bagian itu yang menopang koneksi WebSocket.
9.4 Container Gagal Menyala
Container yang berulang kali restart paling sering disebabkan tiga hal: direktori data tidak bisa ditulisi oleh proses di dalam container, argumen pada command salah ketik, atau path drive pada mode multi-drive tidak cocok dengan volume yang di-mount.
Mulai dari log, karena pesannya biasanya cukup gamblang:
sudo docker compose logs --tail=50 siloLanjutkan dengan memeriksa kepemilikan direktori data di host memakai ls -ld /srv/silo/data, lalu cocokkan dengan UID yang dipakai proses di dalam container. Kasus lain yang mirip gejalanya: container berjalan tapi berstatus tidak sehat. Bila servernya jelas melayani saat diuji lewat curl, yang bermasalah justru definisi health check-nya, bukan servernya, dan path binary pada blok tersebut perlu diperiksa ulang.
10. Kesimpulan
Silo menjawab masalah yang nyata: deployment MinIO yang sudah berjalan butuh kelanjutan pemeliharaan setelah community edition upstream ditutup. Kompatibilitas API, variabel lingkungan, dan format on-disk yang dijaga sebagai kontrak membuat perpindahan terasa seperti mengganti tag image, bukan migrasi besar. Console yang dikembalikan utuh, artefak rilis bertanda tangan, serta manifesto yang mengunci lisensi AGPLv3 tanpa CLA memberi dasar yang cukup kuat untuk dipertimbangkan sebagai fondasi penyimpanan jangka panjang. Usianya yang masih muda tetap perlu diperhitungkan, jadi verifikasi mandiri sebelum memindahkan data produksi tetap wajib.
Skenario yang paling pas untuk deployment seperti ini adalah target backup database, penyimpanan media aplikasi, penampung dump terjadwal, dan artifact build internal. Skala yang lebih besar, terutama yang menuntut ketersediaan saat satu node mati, sebaiknya direncanakan sejak awal sebagai topologi multi-node dengan minimal empat host sesuai anjuran dokumentasi resmi.
Tiga langkah yang layak dikerjakan segera setelah instalasi ini berjalan: menyusun policy per aplikasi supaya tidak ada satu pun proses yang memakai kredensial root, mengaktifkan versioning beserta aturan lifecycle pada bucket penting, dan menjadwalkan mcli mirror sebagai rutinitas backup ke penyimpanan di luar server ini. Object storage yang hanya punya satu salinan di satu mesin tetaplah titik kegagalan tunggal, sebagus apa pun perangkat lunak di atasnya.




