Cara Deploy Silo Object Storage (Fork MinIO) dengan Docker Compose & Nginx

Cara Deploy Silo Object Storage (Fork MinIO) dengan Docker Compose & Nginx

Bitnesia Infrastructure Sep 19, 2026 2 EN

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, header x-minio-*, route /minio/*, namespace policy arn: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/amd64 maupun linux/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.

SNSD memakai satu drive tanpa redundansi, sedangkan SNMD menyebar data dan paritas ke beberapa drive dalam satu node.
SNSD memakai satu drive tanpa redundansi, sedangkan SNMD menyebar data dan paritas ke beberapa drive dalam satu node.

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 9000 melayani S3 API. Ini endpoint yang dipakai aplikasi, SDK, dan client CLI.
  • Port 9001 melayani 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.
Tiga lapis yang dipakai artikel ini: client, Nginx sebagai terminasi TLS, lalu container Silo yang hanya mendengarkan di loopback.
Tiga lapis yang dipakai artikel ini: client, Nginx sebagai terminasi TLS, lalu container Silo yang hanya mendengarkan di loopback.

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.

KomponenMinimumRekomendasi
Host baremetal atau virtual khusus4 host8 host atau lebih
Drive per server4 drive8 drive atau lebih
Jaringan25GbE100GbE
CPU per host8 CPU atau vCPU16 CPU atau vCPU ke atas
Memori tersedia per host32 GB128 GB ke atas

Kebutuhan memori juga naik mengikuti kapasitas penyimpanan yang dikelola satu host, bukan sekadar mengikuti jumlah request.

Total storage per hostMemori yang disarankan
Sampai 1 TiB8 GB
Sampai 10 TiB16 GB
Sampai 100 TiB32 GB
Sampai 1 PiB64 GB
Lebih dari 1 PiB128 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.

Bersponsor

Dapatkan Kredit DigitalOcean $25

Deploy aplikasi secara instan langsung dari Git atau bangun workload AI Anda di layanan cloud andalan jutaan developer. Daftar hari ini dan saldo $25 akan masuk ke dashboard Anda.

Klaim Kredit $25

4. 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.

  1. 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-run

    Mode --dry-run mencetak perintah yang akan dijalankan. Kebiasaan membaca dulu isi skrip yang dijalankan sebagai root layak dipertahankan, apalagi skrip yang diunduh dari internet.

  2. Jalankan pemasangannya:

    sudo sh get-docker.sh
  3. Pastikan service aktif dan ikut menyala saat boot:

    sudo systemctl enable --now docker
  4. Verifikasi 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.

  1. Petakan dulu disk yang tersedia beserta titik mount-nya:

    lsblk

    Contoh 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 disk

    Baca keluaran itu dari bawah ke atas. Disk vda berukuran 25 GB adalah disk sistem, terlihat dari partisinya yang memegang /, /boot, dan /boot/efi. Disk vdb berukuran 488 KB adalah perangkat kecil bawaan penyedia cloud yang biasanya berisi metadata instance, dan tidak boleh disentuh. Sisanya sda berukuran 100 GB tanpa partisi maupun mount point, dan inilah target kita.

  2. Pastikan disk target benar-benar kosong sebelum ditimpa:

    sudo wipefs /dev/sda

    Perintah 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.

  3. Pasang perkakas partisi dan utility XFS bila belum tersedia:

    sudo apt install parted xfsprogs

    Paket xfsprogs menyediakan mkfs.xfs beserta 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.

  4. 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% dan 100% membuat parted menyelaraskan awal partisi ke batas yang tepat, jauh lebih aman daripada menyebut nomor sektor secara manual. Kata primary hanya menjadi label pada tabel GPT.

  5. Periksa hasilnya, dan pastikan partisi sda1 sudah muncul:

    lsblk /dev/sda
  6. Format partisi tersebut sebagai XFS:

    sudo mkfs.xfs /dev/sda1

    Perintah ini menghapus seluruh isi partisi, jadi baca sekali lagi nama perangkat yang diketik sebelum menekan enter. Salah menunjuk vda1 berarti memformat disk sistem.

  7. Siapkan titik mount lalu pasang partisinya:

    sudo mkdir -p /srv/silo
    sudo mount /dev/sda1 /srv/silo
  8. Pastikan filesystem benar-benar terpasang dan tipenya sesuai:

    df -hT /srv/silo

    Kolom tipe harus menunjukkan xfs dengan kapasitas mendekati 100 GB.

  9. Ambil UUID partisi sebagai penanda permanen:

    sudo blkid -s UUID -o value /dev/sda1

    Nama perangkat seperti /dev/sda1 bisa bergeser saat urutan deteksi disk berubah, misalnya setelah volume lain dilampirkan. UUID tidak ikut bergeser, jadi inilah yang kita pakai pada konfigurasi mount permanen.

  10. Daftarkan mount permanen di /etc/fstab. Sunting berkasnya, lalu tambahkan satu baris di bagian bawah dengan UUID hasil langkah sebelumnya:

    sudo nano /etc/fstab
    UUID=ganti-dengan-uuid-hasil-blkid  /srv/silo  xfs  defaults,noatime,nofail  0  0
  11. Uji konfigurasi tanpa perlu reboot:

    sudo systemctl daemon-reload
    sudo umount /srv/silo
    sudo mount -a
    findmnt /srv/silo

    Perintah mount -a memasang seluruh entri /etc/fstab yang belum terpasang, sehingga kesalahan penulisan langsung ketahuan sekarang, bukan nanti saat server gagal boot. Keluaran findmnt yang menampilkan sumber /dev/sda1 menandakan konfigurasi sudah benar.

Tiga opsi mount pada baris fstab di atas dipilih dengan alasan masing-masing:

  • noatime mematikan 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.
  • nofail membuat 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 0 di akhir baris mematikan dump dan pemeriksaan saat boot. XFS memang tidak mengandalkan pemeriksaan boot semacam itu, karena fsck.xfs hanya program kosong yang selalu melaporkan sukses. Perbaikan XFS dilakukan manual memakai xfs_repair pada 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.

  1. Buat direktori kerja untuk berkas Compose. Direktori ini cukup berada di disk sistem karena isinya hanya berkas teks:

    sudo mkdir -p /opt/silo
  2. Buat direktori data di dalam disk yang tadi dipasang, yang nanti di-mount ke dalam container:

    sudo mkdir -p /srv/silo/data
  3. Pastikan direktori data benar-benar berada di disk baru, bukan di partisi root:

    df -h /srv/silo/data

    Kolom 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:

  1. Pastikan direktori kerja sudah ada, lalu masuk ke dalamnya:

    sudo mkdir -p /opt/silo
    cd /opt/silo
  2. Buat dan buka berkas Compose memakai editor teks:

    sudo nano /opt/silo/docker-compose.yml

    Editor nano tersedia secara bawaan di Ubuntu Server. Setelah isinya diketik, simpan dengan Ctrl+O lalu Enter, dan keluar dengan Ctrl+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: 2m

Beberapa bagian layak dibedah satu per satu, karena di sinilah kesalahan paling sering terjadi.

  • MINIO_ROOT_USER dan MINIO_ROOT_PASSWORD. Silo sengaja mempertahankan awalan MINIO_ pada seluruh variabel lingkungan demi kompatibilitas. Tidak ada variabel bernama SILO_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 seperti latest memang 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 port 9000 secara langsung. Perlu diingat, publikasi port oleh Docker menulis aturan langsung ke tabel nat iptables 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. Sesuaikan console.example.com dengan 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/data memudahkan 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 pemeriksaannya live, ready, cluster, dan cluster-read. Nilai start_period yang 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.

  1. Nyalakan container di latar belakang:

    sudo docker compose up -d
  2. Periksa status container:

    sudo docker compose ps

    Kolom status harus menunjukkan container dalam keadaan berjalan dan sehat, bukan restarting. Status yang berputar-putar biasanya menandakan salah ketik pada command atau direktori data yang tidak bisa ditulisi.

  3. Baca log untuk memastikan server siap melayani:

    sudo docker compose logs -f silo

    Log startup menampilkan alamat S3 API dan alamat console yang aktif. Tekan Ctrl+C untuk keluar dari mode ikuti log.

  4. Uji endpoint liveness dari host:

    curl -I http://127.0.0.1:9000/minio/health/live

    Endpoint ini mengembalikan 200 OK saat 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/live menjawab satu pertanyaan saja, yaitu apakah proses ini sedang melayani. Inilah yang pantas dipakai sebagai probe per container.
  • /minio/health/cluster memeriksa kuorum tulis tingkat cluster dan mengembalikan 503 saat kuorum tidak terpenuhi.
  • /minio/health/cluster/read memeriksa kuorum baca, juga dengan 503 sebagai penanda gagal.
  • /minio/health/cluster?maintenance=true memeriksa apakah cluster tetap punya kuorum bila node ini dimatikan untuk perawatan, dan mengembalikan 412 bila 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.com alih-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.

  1. Pasang Nginx dari repositori resmi distribusi:

    sudo apt update
    sudo apt install nginx
  2. Pastikan service berjalan dan ikut menyala setiap kali server boot:

    sudo systemctl enable --now nginx
    sudo systemctl status nginx

    Tekan q untuk keluar dari tampilan status.

  3. Buat berkas konfigurasi khusus Silo:

    sudo nano /etc/nginx/sites-available/silo.conf

    Simpan dengan Ctrl+O lalu Enter, dan keluar dengan Ctrl+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; dan proxy_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 header Host sebagai bagian dari signature, sehingga menggantinya membuat semua request ditolak dengan galat signature mismatch. Perhatikan pemakaian $http_host, bukan $host, karena $host membuang 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 dengan Connection "" pada blok S3 supaya koneksi keepalive ke upstream tetap hidup dan tidak diturunkan ke HTTP/1.0.
  • Pasangan Upgrade dan Connection "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:

  1. Buat symlink ke direktori sites-enabled:

    sudo ln -s /etc/nginx/sites-available/silo.conf /etc/nginx/sites-enabled/
  2. Nonaktifkan situs bawaan Nginx supaya halaman selamat datang tidak lagi melayani request yang nyasar:

    sudo rm /etc/nginx/sites-enabled/default

    Perintah ini hanya menghapus symlink pengaktifnya. Berkas aslinya tetap tersimpan di /etc/nginx/sites-available/default dan bisa diaktifkan lagi kapan saja.

  3. Uji sintaks konfigurasi sebelum menerapkannya:

    sudo nginx -t
  4. Muat 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.

  1. Pasang Certbot beserta plugin Nginx:

    sudo apt install certbot python3-certbot-nginx

    Certbot juga mendistribusikan versi snap yang biasanya lebih mutakhir. Pilih salah satu jalur saja, jangan memasang keduanya berdampingan.

  2. Terbitkan sertifikat untuk kedua subdomain sekaligus:

    sudo certbot --nginx -d s3.example.com -d console.example.com

    Plugin Nginx akan menyunting server block yang tadi kita buat, menambahkan blok listen 443 ssl beserta path sertifikat, dan menawarkan pengalihan otomatis dari HTTP ke HTTPS. Terima tawaran pengalihan tersebut supaya client tidak pernah mengirim kredensial lewat jalur polos.

  3. Periksa hasil suntingan Certbot, lalu muat ulang:

    sudo nginx -t && sudo systemctl reload nginx
  4. Uji mekanisme perpanjangan otomatis:

    sudo certbot renew --dry-run

    Paket 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.

  5. Pastikan nilai MINIO_BROWSER_REDIRECT_URL pada docker-compose.yml sudah memakai skema https, lalu terapkan ulang:

    sudo docker compose up -d

Verifikasi akhir cukup dari terminal mana pun:

curl -I https://s3.example.com/minio/health/live

5.4 Pembatasan Akses Firewall

Lapisan proxy baru berguna kalau tidak ada jalan pintas di sekitarnya. Kunci akses jaringan server ke tiga port saja.

  1. Izinkan SSH dan profil aplikasi Nginx yang mencakup port 80 serta 443:

    sudo ufw allow OpenSSH
    sudo ufw allow 'Nginx Full'
  2. Aktifkan firewall dan periksa hasilnya:

    sudo ufw enable
    sudo ufw status verbose
  3. Pastikan port aplikasi benar-benar tertutup dari luar. Jalankan dari mesin lain:

    curl -m 5 -I http://s3.example.com:9000/minio/health/live

    Koneksi yang gagal atau kehabisan waktu justru hasil yang kita harapkan. Respons 200 berarti port 9000 masih 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.

  1. Dari object browser, pilih Create Bucket.
  2. Isi nama bucket. Pakai huruf kecil, angka, dan tanda hubung saja, misalnya backup-postgres atau media-assets. Nama bucket ikut muncul di URL object, jadi pilih yang deskriptif sejak awal.
  3. Aktifkan Versioning bila bucket akan menyimpan data yang perlu bisa dipulihkan setelah tertimpa atau terhapus.
  4. Aktifkan Object Locking bila ada kebutuhan kepatuhan yang melarang object diubah atau dihapus selama periode tertentu. Opsi ini menuntut versioning aktif.
  5. Isi Quota bila ingin membatasi ukuran total bucket, dan atur Retention bila butuh periode retensi minimum.
  6. 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.

  1. Pilih bucket tujuan dari daftar.
  2. Gunakan tombol upload untuk memilih berkas, atau pilih opsi folder untuk mengunggah satu direktori sekaligus. Object browser juga menyediakan pembuatan folder sebagai prefix.
  3. 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.pdf

Beberapa hal yang perlu diketahui sebelum menyebarkan tautan semacam ini:

  • Masa berlaku bawaan adalah 168 jam alias 7 hari bila flag --expire tidak disebutkan. Format durasinya mengikuti pola ##h##m##s, dan penulisan seperti 30d juga diterima.
  • Tautan berlaku untuk siapa pun yang memegangnya selama belum kedaluwarsa. Perlakukan sebagai rahasia, bukan sebagai tautan biasa.
  • Menambahkan flag --recursive membuat tautan untuk seluruh object dalam sebuah bucket atau prefix sekaligus.
  • Pada bucket dengan versioning aktif, flag --version-id menunjuk 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/public

Perintah 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.

  1. 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.gz
  2. Cocokkan checksum dengan berkas SHA-256 yang diterbitkan pada halaman rilis yang sama:

    sha256sum mcli_20260916000000.0.0_linux_amd64.tar.gz
  3. Ekstrak arsipnya:

    tar -xzf mcli_20260916000000.0.0_linux_amd64.tar.gz
  4. Pasang 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.

  1. Login ke https://console.example.com memakai kredensial root.
  2. Buka bagian Access Keys, lalu pilih Create Access Key.
  3. 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.
  4. Batasi masa berlakunya bila kredensial itu hanya dipakai sementara.
  5. 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_KEY

Periksa 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.

  1. Buat bucket baru:

    mcli mb silo/backup-postgres
  2. Unggah satu berkas. Tanda garis miring di akhir tujuan menandakan bucket atau prefix, bukan nama object:

    mcli cp dump.sql.gz silo/backup-postgres/
  3. Unggah satu direktori beserta isinya:

    mcli cp --recursive /var/www/uploads/ silo/media-assets/
  4. 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.txt

Perintah 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-assets

Uji 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.gz

7.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.

  1. 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.

  2. Lampirkan policy, karena user baru belum punya izin apa pun:

    mcli admin policy attach silo readwrite --user backup-agent

    Flag --user dan --group saling meniadakan, jadi pilih salah satu. Beberapa policy bisa dilampirkan sekaligus dengan menyebutkannya berurutan.

  3. Terbitkan access key turunan bila aplikasi butuh kredensial berumur pendek:

    mcli admin accesskey create silo backup-agent --name "cron backup harian" --expiry-duration 720h

    Access 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.

Migrasi menyentuh baris image pada berkas Compose, sementara volume data beserta seluruh isinya dipakai kembali apa adanya.
Migrasi menyentuh baris image pada berkas Compose, sementara volume data beserta seluruh isinya dipakai kembali apa adanya.

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.

AspekStatus setelah migrasiTindakan yang perlu
Data object dan direktori .minio.sysTetap kompatibelMount volume yang sama, tanpa ekspor impor
Bucket, versi object, user, policy, konfigurasi enkripsiTetap terpakaiVerifikasi ulang setelah container menyala
Hostname dan port endpoint (9000 dan console)TetapTidak ada
Variabel lingkungan MINIO_*TetapTidak ada
Route /minio/* dan header x-minio-*TetapTidak ada
Namespace policy arn:minio:*TetapTidak ada
SDK, mc/mcli, dan presigned URLTetap kompatibelUji satu aplikasi nyata sebagai sampel
Image containerBerubahGanti ke docker.io/pgsty/silo dengan tag rilis
Nama paket dan executableBerubahminio menjadi silo pada instalasi native
Direktori konfigurasi bawaanBerubah~/.minio menjadi ~/.silo, tapi ~/.minio/certs lama tetap dihormati
Auto-update dan callhome SUBNETDinonaktifkanUpgrade lewat penggantian tag image
Policy kustom dan tool admin buatan sendiriPerlu diperiksaUji terpisah sebelum migrasi produksi
Branding, paginasi console, dan sebagian field respons APIBerbeda tampilanSesuaikan ekspektasi, tanpa perubahan teknis

8.3 Penggantian Image

  1. Sunting docker-compose.yml dan ganti barisnya. Image lama bisa berupa minio/minio, quay.io/minio/minio, atau pgsty/minio, dan semuanya digantikan satu image:

    image: docker.io/pgsty/silo:RELEASE.2026-09-16T00-00-00Z
  2. Tarik image baru lebih dulu supaya jeda layanan sependek mungkin:

    sudo docker compose pull
  3. Terapkan 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:

  1. Unduh satu object yang isinya sudah diketahui, lalu cocokkan checksum-nya.
  2. Jalankan satu aplikasi nyata lewat SDK yang biasa dipakainya.
  3. Restart layanan satu kali.
  4. 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 silo

Lanjutkan 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.

Dukung keberlanjutan tutorial open source Bitnesia melalui link di bawah ini.

Kirim Donasi

Related Posts