Bikin Image Host Murah Meriah Sendiri di Alibaba Cloud FC + OSS

Tiga hal dulu:
- Image host ini fiturnya sederhana, gampang dikonfigurasi, dan cukup aman. Kalau kurang buat Anda, serahkan source code-nya ke AI — nambah atau ngurangin fitur itu gampang.
- Semua
AccessKey, password, domain, dan nama bucket di artikel ini adalah placeholder — ganti dengan punya Anda sendiri sebelum menyalin apa pun. - Kodenya aplikasi Node.js satu file (sekitar 380 baris), dependensi disuntik lewat Layer FC, nol hardcoding di kode bisnis, dan semua konfigurasi dibaca dari environment variable.
Source code: https://github.com/ezzty/oss-upload
1. Kenapa bikin image host sendiri
Setiap blog statis pada dasarnya butuh image host. Banyak orang ngirit pakai image host gratis selamanya punya orang lain — tapi siapa sih dermawan yang nggak pernah tutup? Dan karena data Anda di tangan orang lain, Anda sama sekali nggak punya kendali, jadi selalu was-was.
Setelah cukup banyak kena pit, saya memutuskan bikin image host sendiri dengan biaya paling murah. Tujuan utamanya: hemat, tanpa batas kapasitas, dan tetap aman!
Kebanyakan setup image host self-hosted butuh server sendiri — puluhan yuan sebulan plus harus nambal sendiri — atau cuma jalan di klien lokal, jadi nggak bisa upload dari komputer lain. Akhirnya saya memutuskan bikin image host cloud serverless: upload di mana saja, kapan saja.
Alibaba Cloud Function Compute FC + OSS + CDN
FC bayar sesuai pemakaian (hampir ¥0 kalau trafiknya rendah) + tanpa database + zero ops, dengan paket deployment sekecil 6KB. Upload yang jarang praktis nggak makan biaya.
Penyimpanan gambar di OSS juga bayar sesuai pemakaian — puluhan GB gambar cuma beberapa yuan sebulan.
Tambah CDN di depannya, gambar loading-nya ngebut banget!
Image host pribadi bukan target serangan yang menggiurkan, tapi saya tetap pasang lapisan keamanan: PoW wajib buat nahan brute force, validasi magic number buat nahan file palsu, cek ukuran tiga kali buat nahan banjir payload, kuota harian buat nahan penyalahgunaan, dan token 2 jam buat nahan pencurian.
Setup ini nggak tanpa kekurangan: nggak ada multi-user, nggak ada manajemen album, nggak ada statistik pemakaian — bahkan nggak bisa hapus gambar tanpa masuk ke konsol OSS.
Tapi kecil, murah, dan lebih dari cukup buat pemakaian pribadi.
2. Arsitektur dan alur request
Browser upload.html
│ ① POST /login {user, pass}
│ ← 200 {token} (valid 24h)
│ ② POST /upload Authorization: Bearer *** + image binary
▼
Alibaba Cloud Function Compute FC (Node.js 18, HTTP trigger)
│ auth / rate limit / magic-number check / size check
│ ③ ossClient.put(key, stream)
▼
OSS Bucket (private read/write, public read disabled)
│ ④ CDN origin fetch (internal network, free)
▼
https://img.example.com/m/26j13/ab12cd.jpg ← public access domain
Tiga trade-off desain:
- Bucket diset private: nggak ada yang bisa baca langsung lewat direct link; gambar cuma bisa diakses lewat URL yang di-bind ke domain CDN. Begitu public read dinyalakan, bucket Anda jadi sumber daya bersama — orang lain bisa enumerasi dan nyedot trafik Anda.
- Wajib login buat upload: kalau nggak, orang bakal nganggap domain API Anda image host gratis dan bikin tagihan serta penyimpanan Anda meledak nggak terkendali.
- Kode bisnis nggak pernah menyentuh secret: AK/SK cuma ada di environment variable — nggak pernah kelihatan di kode atau repo.
3. Persiapan
3.1 Aktifkan produknya
Aktifkan Function Compute FC dan Object Storage OSS (dua-duanya bayar sesuai pemakaian, nggak perlu beli di muka).
3.2 Buat bucket
- Nama: unik secara global, misalnya
my-img - Region: pilih yang dekat dengan Anda/pengguna Anda, misalnya
East China 1 (Hangzhou)→oss-cn-hangzhou - Kontrol akses: Private (penting)
- Tipe penyimpanan: Standard — itu yang cocok buat gambar yang sering diakses. Jangan pilih Infrequent Access atau Archive; dua itu punya durasi penyimpanan minimum dan kalau dihapus lebih awal malah kena biaya.
3.3 Buat RAM user yang dibatasi ke satu bucket (sangat disarankan)
Banyak tutorial nyuruh pakai AccessKey akun root — jangan. AK root bocor berarti seluruh akun Alibaba Cloud Anda jatuh.
Konsol RAM → Policies → Create Policy → tab JSON:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"oss:GetObject",
"oss:PutObject",
"oss:DeleteObject",
"oss:ListObjects",
"oss:HeadObject"
],
"Resource": [
"acs:oss:*:*:my-img",
"acs:oss:*:*:my-img/*"
]
}
]
}
Beri nama policy-nya ImageHostSingleBucket. Lalu:
- RAM → Users → Create User, centang “Use permanent AccessKey for API call”
- Lampirkan hanya policy di atas ke user ini
- Generate AK/SK dan langsung simpan ke password manager lokal Anda
Beberapa trade-off yang disengaja:
- Tanpa
oss:ListBuckets— kalau bocor, penyerang bahkan nggak bisa lihat bucket apa saja yang Anda punya - Tanpa
oss:CopyObject— image host nggak butuh izin copy; kasih sesedikit mungkin - Jangan lampirkan
AliyunOSSFullAccess— itu bakal bikin AK image host Anda bisa baca semua data bucket yang Anda punya
4. Siapkan layer dependensi (Layer)
Kode bisnis cuma bergantung pada ali-oss. Taruh di Layer, paket kodenya tetap beberapa KB.
Opsi A: Unduh asset rilis langsung (disarankan)
Proyeknya sudah menerbitkan Release — layer.zip dan paket kode bisa diunduh langsung:
https://github.com/ezzty/oss-upload/releases/latest
| Asset | Ukuran | Isi |
|---|---|---|
layer.zip |
3,25 MB | ali-oss@6.23.0 dan dependensinya — total 2338 file |
oss-upload-code.zip |
~6 KB | index.js + package.json, paket deployment fungsi |
Keuntungannya: nggak perlu install Node.js, nggak perlu zip manual, dan nggak ada masalah “beda dengan yang sudah diverifikasi penulis” gara-gara npm install lokal Anda narik versi SDK yang lebih baru. Layer-nya cuma berisi source code paket npm, tanpa secret.
Opsi B: Build sendiri
Kalau Anda mau versi dependensi lain, atau nggak percaya paket yang sudah jadi:
mkdir -p layer-build/nodejs
cd layer-build
npm init -y
npm install ali-oss
# Direktori HARUS punya struktur ini:
# nodejs/
# node_modules/
# ali-oss/
# ...dependensi transitifnya
cd nodejs && zip -r ../layer.zip node_modules && cd ..
Upload
Konsol FC → Layer Management → Create Layer:
- Nama:
oss-upload-deps - Runtime: Node.js 18
- Upload
layer.zip
Layer cukup dibuat sekali. Kalau nanti mau upgrade
ali-oss, pack versi baru, publish, lalu arahkan fungsi ke versi layer baru — kode bisnis nggak perlu diubah.
5. Deploy fungsinya
5.1 Ambil kode bisnisnya
Disarankan: pakai asset rilis langsung — unduh oss-upload-code.zip (~6 KB) dari https://github.com/ezzty/oss-upload/releases/latest; unzip dan Anda sudah punya paket deployment standar.
Kalau pack sendiri, root zip harus berisi hanya dua file ini (jangan ada folder pembungkus, kalau nggak Handler nggak bakal nemu index.handler):
code.zip
├── index.js ← source bisnis
└── package.json ← deklarasi dependensi (buat referensi; saat runtime sebenarnya dimuat dari layer)
zip code.zip index.js package.json
5.2 Buat fungsinya
- Runtime: Node.js 18
- Handler:
index.handler - Spesifikasi: 0,05 vCPU / 128 MB memori / 512 MB disk (spesifikasi terkecil yang praktis jalan)
- Konfigurasi Layer: bind layer
oss-upload-depsyang baru Anda buat
Perhatikan setelan memori: kodenya membaca seluruh body ke memori (
bodyBuf), dan decoding base64 bikin salinan lagi. 128 MB cukup buat gambar biasa, tapi kalau Anda naikkan batas upload ke 20 MB dan sering upload gambar mendekati batas, naikkan memorinya juga.
5.3 Environment variable (8 wajib — kurang satu aja nggak bakal start)
Environment variable fungsi ada 8 entri wajib — konfigurasikan seperti di gambar.
AUTH_USERadmin— username loginAUTH_PASS<set password kuat>— password login; pakai string acak panjangJWT_SECRET<string acak 32+ karakter>— secret penandatangan tokenOSS_ACCESS_KEY_IDLTAIxxxxxxxxxxxxxxxx— AK user RAMOSS_ACCESS_KEY_SECRET<AccessKey Secret Anda>— SK user RAMOSS_BUCKETmy-img— nama bucketOSS_REGIONoss-cn-hangzhou— region ID bucketCDN_DOMAINhttps://img.example.com— wajib menyertakan skema protokol; kalau nggak, langsung gagal start
1 opsional:
ALLOWED_ORIGINSexample.com,myblog.net— sumber cross-origin yang diizinkan, dipisah koma. Fungsi tetap start tanpa ini; nilainya cuma dipakai kalau CORS level kode diaktifkan (defaultnya platform cuma mengembalikanOrigin, jadiisValidOriginnggak pernah dipanggil). Kalau Anda memang mengaktifkan CORS level kode, wajib diset, kalau nggak nilai fallbackexample.combakal memblokir semua upload dari browser.

5.4 Bind domain kustom
Konsol FC → Domain Management → Add Domain, lalu ikuti petunjuk untuk konfigurasi CNAME dan sertifikat. Begitulah cara dapat alamat API seperti https://api.example.com.
6. Halaman frontend
upload.html adalah frontend satu file — tinggal taruh di direktori situs Anda.
Satu perubahan wajib — cari _FC_PARTS:
// Ganti ke domain kustom Function Compute Anda
const _FC_PARTS = ['https://', 'api.example.com'];
Batas ukuran harus sama dengan backend (dua-duanya default 20MB):
if (file.size > 20 * 1024 * 1024) { /* block */ }
Ada batas di masing-masing sisi — yang lebih kecil menang. Ubah cuma frontend, file besar bakal kena 413 di server; ubah cuma backend, pengguna diblokir di browser sebelum request-nya keluar.
7. Mau lebih dalam? Detail inti ada di README source
Itu alur lengkap buat menjalankan image host self-hosted. Kenapa kodenya ditulis begini, detail implementasi tiap lapisan proteksi, dan checklist acceptance lengkap semuanya ada di README repo source — rujuk saat butuh:
https://github.com/ezzty/oss-upload → “Core implementation (code level)” dan “Pre-launch acceptance” di README.md
Postingan blog ini cuma mau menjelaskan “kenapa self-host, gimana cara jalankannya, apa yang perlu diperhatikan”. Saat benar-benar deploy, README adalah dokumentasi teknis lengkapnya.
8. Biaya
Bayar sesuai pemakaian, tiga bagian:
| Item | Penagihan | Skala |
|---|---|---|
| Komputasi FC | Compute CU (vCPU + memori × durasi) + jumlah invokasi | Ada kuota gratis; image host pribadi biasanya mendekati kuota itu |
| Penyimpanan OSS | ¥/GB/bulan | Standard storage sekitar ¥0,09–0,12/GB/bulan |
| Request OSS | Per request | Nggak signifikan |
| Trafik CDN | ¥/GB | Lihat di bawah |
Trafik adalah porsi terbesar tagihan, dan paling gampang dioptimalkan:
- Upload ke OSS: gratis
- Jaringan internal OSS (FC ↔ OSS di region sama): gratis
- Egress internet publik OSS: kena biaya (sekitar ¥0,5/GB, tergantung periode dan region)
- Lewat CDN: origin fetch CDN pakai jaringan internal, jadi trafik origin gratis — Anda cuma bayar trafik CDN
Kesimpulan: selalu taruh CDN di depan image host — lebih cepat dan menghindari biaya egress OSS. Perhatikan juga FC dan OSS harus di region yang sama; lintas region lewat internet publik, lambat dan bisa kena biaya trafik tambahan.
Dari pengujian saya sendiri, upload beberapa puluh gambar sebulan biayanya sekitar ¥1 per bulan.
9. Maintenance dan update
Mengubah kode bisnis (misalnya format URL gambar):
- Edit
index.jslokal zip code.zip index.js package.json- Konsol → Code Deployment → Upload → Deploy
- Jalankan probe acceptance dari README buat memastikan versi baru sudah live
Mengubah frontend:
- Edit
upload.html - Upload ke situs Anda; pertimbangkan set
Cache-Control: no-cache, kalau nggak pengguna bisa dapat versi lama
Upgrade dependensi:
- Jalankan ulang
npm install ali-ossdan packlayer.zip - Publish versi layer baru di konsol
- Ganti fungsi ke versi layer baru
Rotasi key (lakukan berkala):
- Generate AK/SK baru di RAM
- Update environment variable FC → deploy
- Setelah memastikan layanan sehat, nonaktifkan AK lama di konsol RAM