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.

  • Odoo 19
  • Docker Compose
  • PostgreSQL 15
  • Nginx
  • Tunnel
  • Dashboard Akuntansi Odoo 19: kartu Penjualan, Pembelian, saldo bank, dan dompet pembayaran.
    Dashboard Akuntansi — ringkasan penjualan, pembelian, dan saldo tiap rekening.
  • Daftar Pelanggan di Odoo 19 dengan kolom nama, email, telepon, dan jumlah aktivitas.
    Daftar Pelanggan — 6.844 baris data nyata di instance yang sama.
  • Menu aplikasi Odoo 19 menampilkan modul terpasang seperti Penjualan, Pembelian, dan POS.
    Menu aplikasi — modul yang berjalan: Penjualan, Pembelian, Penagihan, Inventaris, POS.

Gambar 1 dari 3

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.url yang benar serta mode proxy aktif agar tautan dan aset tidak keluar sebagai http://localhost.
  • Pengerasan dasar: daftar basis data dimatikan (--no-database-list), admin_passwd disimpan 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.

← Semua proyek Hubungi Saya