ERP & infrastruktur
Odoo 19 Community di VPS
Menyiapkan ERP Odoo 19 pada VPS yang berada di belakang NAT — hanya port SSH yang terbuka — sehingga akses HTTPS harus lewat terowongan keluar, tanpa menyentuh konfigurasi jaringan host.
Masalah
Kebutuhannya sederhana: menjalankan ERP Odoo 19 Community beserta basis data PostgreSQL di sebuah VPS, dan membuatnya bisa dibuka lewat browser dengan HTTPS. Masalahnya ada di jaringan. VPS itu berada di belakang NAT dan hanya port SSH yang diteruskan — port 80 dan 443 tidak bisa dijangkau dari internet.
Artinya cara biasa tidak berlaku. Record A atau CNAME yang menunjuk ke IP VPS tidak akan pernah tersambung, dan memasang sertifikat TLS di server pun tidak ada gunanya kalau tidak ada yang bisa mencapai port 443. Ditambah lagi, instance ini akan menyimpan data keuangan, jadi membuka port dan mengekspos basis data bukan pilihan.
Peran & batasan
Menyiapkan stack, konfigurasi jaringan, dan memastikan aplikasi bisa diakses dengan aman dari luar. Batasan yang tidak bisa ditawar: tidak boleh mengubah konfigurasi jaringan host, tidak boleh mengekspos PostgreSQL, dan semua kredensial harus tinggal di server — bukan di repositori.
Solusi
- Docker Compose menjalankan Odoo 19 Community dan PostgreSQL 15 pada network terpisah dengan volume persisten, sehingga pembaruan container bisa diulang tanpa menyentuh basis data.
- Terowongan keluar, bukan port masuk. Karena tidak ada domain yang terdaftar di akun Cloudflare dan port 80/443 tertutup, jalur Cloudflare Tunnel tidak bisa dipakai. Solusinya memakai Tailscale Funnel: VPS membuka koneksi keluar, dan trafik masuk dilayani dari sisi Tailscale. NAT tidak jadi hambatan.
- HTTPS tanpa certbot. Sertifikat TLS diterbitkan dan diperbarui otomatis oleh Tailscale, sehingga tidak ada perpanjangan manual yang bisa terlupa.
- Nginx tetap disiapkan sebagai lapisan proxy internal, dan Odoo
dikonfigurasi dengan
web.base.urlyang benar serta mode proxy aktif agar tautan dan aset tidak keluar sebagaihttp://localhost. - Pengerasan dasar: daftar basis data dimatikan
(
--no-database-list),admin_passwddisimpan sebagai variabel lingkungan di server, dan kredensial tidak pernah masuk repositori.
Tantangan & keputusan
Keputusan tersulit bukan teknis, melainkan menerima kenyataan bahwa rencana awal
tidak bisa dijalankan. Rencana pertama memakai Cloudflare Tunnel karena lebih rapi
untuk domain tetap. Setelah terbukti tidak ada zona domain di akun yang dipakai dan
port publik tertutup, saya berhenti memaksakan jalur itu dan memilih Tailscale Funnel
yang bisa langsung hidup. Sisa konfigurasi Cloudflare (proxy Nginx untuk
odoo.conf) tetap disimpan di server agar siap dipakai kalau nanti ada
domain sendiri.
Persistensi juga diuji, bukan diasumsikan: container terowongan direstart dan Funnel dicek tetap aktif, karena akses yang mati setelah reboot akan lebih buruk daripada tidak punya akses sama sekali.
Hasil
Odoo dapat diakses lewat HTTPS pada alamat tetap, dengan basis data berjalan terpisah dari aplikasi. Alur pembaruan container bisa diulang tanpa menyentuh jaringan host, dan sertifikat TLS terbarui sendiri. Instance ini sekarang menyimpan data akuntansi nyata: ribuan pelanggan, puluhan faktur, dan saldo kas per lokasi.
Pelajaran
Di infrastruktur, batasan sering datang lebih dulu daripada solusi. Yang menyelamatkan proyek ini bukan memaksakan satu teknologi, tetapi mengenali lebih awal bahwa hambatannya adalah NAT dan kepemilikan domain — lalu memilih jalan yang benar-benar bisa ditempuh, sambil menyisakan jalur alternatif kalau kondisi berubah.