Kasih Nama Buat Forgejo Loopback Lewat hosts dan ROOT_URL
Domain lokal via /etc/hosts plus DOMAIN dan ROOT_URL di Forgejo, dan cap upload 100 MB Cloudflare yang membuat jalur SSH lebih masuk akal.
Pukul sepuluh pagi saya commit konfigurasi yang membuka akses LAN ke Forgejo lewat domain, dan satu jam kemudian commit berikutnya menutupnya lagi. Revert dalam satu jam, rekam jejak yang memalukan tapi jujur. Rencananya sederhana: forge HTTP saya hidup di loopback, tinggal kasih nama bagus di laptop, semua beres. Ternyata dua commit itu justru pelajaran bagaimana sebuah nama domain bekerja di tiga tempat berbeda sekaligus: file hosts, konfigurasi aplikasi, dan jalur network yang kita pilih.
Ilusi Jalan Pintas di /etc/hosts
Langkah pertama klasik: tambah satu baris di /etc/hosts laptop, memetakan repo.adityo.web.id ke mesin yang menjalankan container. Formatnya memang sederhana, file teks yang mengasosiasikan alamat IP dengan hostname, satu baris per alamat [6], dan perubahannya biasanya langsung efektif tanpa restart apa pun [6]. Pola ini sah, man page-nya sendiri menyebut pemakaian klasik untuk bootstrapping dan jaringan kecil tanpa DNS [6]. Dari browser, halaman Forgejo langsung terbuka dengan nama yang manis itu. Rasanya seperti sudah menang.
Tapi hosts hanya mengubah sisi klien. Forgejo sendiri tetap tidak tahu nama barunya, dan URL clone yang ditampilkan di UI masih di-generate dari konfigurasi internalnya. Di titik ini saya sempat mengira override klien cukup. Tidak pernah cukup.
DOMAIN dan ROOT_URL: Nama dari Sisi Server
Satu detail format yang gampang bikin orang bingung: env bawaan image ini pakai pemisah dua underscore, FORGEJO__server__DOMAIN, bukan satu. Dua underscore menandai batas section, jadi server lalu DOMAIN [1]. Salah ketik satu underscore dan variabelnya nyangkut di section yang salah, diam-diam tanpa error yang jelas. Saya kena sekali sebelum sadar polanya.
Sisi servernya ada di dua env yang saya tambahkan ke Compose: FORGEJO__server__DOMAIN=repo.adityo.web.id dan FORGEJO__server__ROOT_URL yang menunjuk ke domain yang sama. Dokumentasi menjelaskan ROOT_URL sebagai penimpa URL publik yang di-generate otomatis, berguna justru ketika URL internal dan eksternal tidak cocok, contoh resminya kontainer Docker [3]. Halaman reverse proxy-nya menegaskan arah yang sama: kalau URL yang dilihat pengguna berbeda dari yang dilihat Forgejo, pengaturan ROOT_URL yang menentukan supaya link yang dihasilkan tidak rusak [7]. Setelah kedua env ini masuk dan container di-restart, URL clone di UI akhirnya konsisten dengan nama yang saya ketik di browser. Baru di titik ini nama domainnya bener-bener utuh, di dua sisi sekaligus.
Sisi praktis yang bikin pola ini layak dipertahankan walau cuma untuk satu laptop: tidak ada TTL yang perlu ditunggu dan tidak ada zona DNS yang harus diedit. Begitu barisnya dihapus dari hosts, nama itu hilang tanpa meninggalkan jejak konfigurasi di server [6]. Buat percobaan jangka pendek, sifat sementaranya justru fiturnya.
Kenapa Tetap Saya Revert: Cap 100 MB di Edge
Bagian yang membuat commit tadi pagi mundur terima: rencana membuka jalur HTTP itu berarti menaruhnya di belakang Cloudflare Cloudflare, dan tabel resmi Cloudflare menyebut max upload size untuk plan Free dan Pro cuma 100 MB, Business 200 MB [5]. Dokumentasinya bahkan menawarkan jalan keluarnya: pecah upload jadi chunk lebih kecil, atau pakai record DNS-only yang tidak diproxy [5]. Buat forge yang alasan hidupnya adalah file besar, chunking adalah kerjaan tambahan permanen, dan DNS-only berarti capek-capek kasih domain lalu tinggalkan proteksi edge. Solusi yang masuk akal bukan itu: SSH di port 3122 tidak pernah menyentuh edge Cloudflare sama sekali, jadi HTTP kembali ke loopback, domain tetap hidup lewat hosts plus ROOT_URL untuk browsing ringan, dan semua push berat lewat SSH. Satu jam yang lalu itu terlihat seperti revert. Sekarang terbaca sebagai keputusan routing yang benar.
Yang saya bawa pulang dari satu jam itu: sebuah hostname tidak pernah hidup di satu tempat. Ada yang resolve-nya, ada aplikasi yang menampilkan link-nya, dan ada jalur network yang membawa beban beratnya. Ketiganya bisa, dan mungkin sebaiknya, dikonfigurasi secara terpisah.