Setup S3 Lokal yang Bisa Diakses Internet Pakai Cloudflare Tunnel (MinIO)
Setup S3 Lokal yang Bisa Diakses Internet Pakai Cloudflare Tunnel (MinIO)
Use case: kamu pengen punya object storage model S3 di rumah/local server (buat upload file, backup, media, asset app), tapi tetap bisa diakses aman dari internet tanpa buka port router.
Artikel ini full step-by-step dari nol sampai bisa dipakai produksi skala kecil–menengah. Semua contoh pakai MinIO + Cloudflare Tunnel.
TL;DR
- Jalankan MinIO di local (S3-compatible)
- Pasang Cloudflare Tunnel untuk expose endpoint HTTPS
- Kunci akses dengan credential kuat + policy bucket yang benar
- Test pakai
aws-cliendpoint custom
Arsitektur Sederhana
Internet Client
↓ HTTPS
Cloudflare Tunnel (cloudflared)
↓
MinIO (local/home server)
↓
Disk local (HDD/SSD)
Kelebihan model ini: - gak perlu port forwarding - dapat HTTPS domain publik - relatif aman kalau policy + auth beres
1) Prasyarat
- Domain aktif di Cloudflare
- Cloudflare account + Zero Trust aktif
- Server lokal (Linux) dengan Docker/Compose
- RAM minimal 1–2 GB untuk setup ringan
Contoh domain: - storage.terminalstory.my.id
Catatan: kalau kamu belum punya domain, bikin dulu di Cloudflare dan set nameserver ke Cloudflare.
2) Jalankan MinIO di Local (Docker Compose)
Bikin file docker-compose.yml:
services:
minio:
image: minio/minio:latest
container_name: minio
restart: unless-stopped
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: "ganti-user-root-yang-kuat"
MINIO_ROOT_PASSWORD: "ganti-password-panjang-dan-random"
volumes:
- ./minio-data:/data
ports:
- "9000:9000" # S3 API
- "9001:9001" # MinIO Console
Jalankan:
docker compose up -d
Cek:
docker ps
curl http://127.0.0.1:9000/minio/health/live
Kalau return OK, berarti MinIO up.
3) Bikin User S3 (Bukan Root)
Masuk ke MinIO Console: http://localhost:9001.
- Login pakai root user
- Users → Create User
- Buat user khusus (contoh:
app-minio) + password kuat - Policies → Create Policy
- misal: hanya read/write ke satu bucket tertentu
Contoh policy minimal:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::terminalstory-assets",
"arn:aws:s3:::terminalstory-assets/*"
]
}
]
}
4) Install cloudflared
Ubuntu/Debian (contoh):
# lihat docs resmi cloudflare untuk versi terbaru
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared stable main' | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt update && sudo apt install cloudflared -y
Login cloudflared:
cloudflared tunnel login
5) Buat Tunnel + Route DNS
cloudflared tunnel create minio-tunnel
cloudflared tunnel route dns minio-tunnel storage.terminalstory.my.id
Buat config /etc/cloudflared/config.yml:
tunnel: minio-tunnel
credentials-file: /root/.cloudflared/<TUNNEL_ID>.json
ingress:
- hostname: storage.terminalstory.my.id
service: http://127.0.0.1:9000
- service: http_status:404
Run service:
sudo cloudflared service install
sudo systemctl enable cloudflared
sudo systemctl restart cloudflared
sudo systemctl status cloudflared
6) Test Endpoint Publik
curl -I https://storage.terminalstory.my.id
Harus dapat response HTTPS aktif.
7) Integrasi AWS CLI (Endpoint Custom)
Install AWS CLI, lalu set profile khusus:
aws configure --profile minio-public
# isi access key + secret key dari MinIO user
# region: us-east-1 (atau bebas konsisten)
# output: json
List bucket:
aws --profile minio-public --endpoint-url https://storage.terminalstory.my.id s3 ls
Upload test:
echo "hello from terminalstory" > test.txt
aws --profile minio-public --endpoint-url https://storage.terminalstory.my.id s3 cp test.txt s3://terminalstory-assets/test.txt
8) Bikin Bucket Public (Opsional)
Kalau kamu butuh public assets (gambar/blog/media):
- Buat bucket
public-assets - Set policy public read
Contoh policy public read:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::public-assets/*"]
}
]
}
Warning: jangan pakai public untuk bucket backup/private data.
9) Security Wajib (Jangan Diskip)
- Jangan pakai root credential untuk aplikasi
- bikin user policy terbatas (read/write bucket tertentu)
- Password wajib kuat
- panjang, random, unik
- Batasi bucket public
- default private
- Aktifkan versioning bucket
- bantu recovery kalau file ketimpa
- Tambahkan Cloudflare Access (opsional tapi recommended)
- khusus endpoint admin/console
- Pisahkan endpoint API vs console
- misal
storage.untuk API,storage-admin.untuk console - Backup rutin data MinIO
- local disk failure itu real
10) Problem Umum + Solusi
A) Upload gagal signature mismatch
- pastikan endpoint benar
- cek clock/time server sinkron (NTP)
- cek akses key/secret key
B) URL bisa dibuka tapi gak bisa auth
- cek policy user
- cek bucket permission
- pastikan app pakai endpoint HTTPS publik yang sama
C) Tunnel aktif tapi domain error
- cek DNS route tunnel
- cek service
cloudflaredstatus - cek file credential tunnel
11) Kapan Setup Ini Cocok?
Cocok kalau kamu: - punya home server/local VPS sendiri - pengen kontrol data storage sendiri - butuh endpoint S3-compatible buat app/backup - pengen expose aman tanpa buka port publik langsung
Kurang cocok kalau kamu: - gak mau maintain infra sama sekali - butuh SLA enterprise ketat dari hari pertama
Kesimpulan
Setup S3 lokal + Cloudflare Tunnel itu sweet spot buat creator/indie builder: - biaya relatif hemat - tetap punya endpoint internet-ready - kontrol data ada di tangan kamu
Yang paling penting: auth + policy + backup.
Kalau tiga itu beres, setup ini udah cukup kuat buat dipakai production skala kecil–menengah.