Panduan ini mengikuti pola yang sudah kamu pakai di VPS (ilkomith.cloud): Docker multi-container + Nginx reverse proxy + Certbot.
Ikuti pola kamu yang sudah ada:
/home/projects/2026/nama-project/
├── fiber-auth-backend/ # source code backend (copy dari project ini)
├── nextjs-auth-frontend/ # source code frontend (copy dari project ini)
├── dist/
├── mirror.arch.etherthink.xyz/
├── expo-auth-frontend/
├── docker-compose.yml
└── .env
Copy folder fiber-auth/ dan nextjs-auth-frontend/ (yang sudah ada Dockerfile masing-masing) ke VPS, taruh sejajar dengan docker-compose.yml ini. Bisa pakai git clone, scp, atau rsync.
cp .env.example .env
nano .envIsi dengan kredensial database asli dan JWT_SECRET yang kuat (generate misalnya dengan openssl rand -base64 32). Ganti juga PUBLIC_API_URL dan PUBLIC_APP_URL sesuai domain yang akan dipakai.
docker compose up -d --buildIni akan menjalankan 3 container: db (PostgreSQL), backend (Fiber, port 3000 di localhost host), frontend (Next.js, port 3001 di localhost host). Ketiganya hanya bind ke 127.0.0.1, tidak langsung exposed ke publik — akses publik hanya lewat Nginx.
Container db fresh biasanya sudah otomatis owner sesuai POSTGRES_USER, jadi masalah permission denied for schema public yang kamu alami di local biasanya tidak terjadi di setup Docker ini (beda dari install native yang bikin role terpisah dari owner). Kalau tetap terjadi, exec ke container db dan jalankan grant yang sama seperti sebelumnya:
docker compose exec db psql -U <DB_USER> -d <DB_NAME> -c "GRANT ALL ON SCHEMA public TO <DB_USER>;"Pakai contoh di nginx-example.conf — sesuaikan server_name dengan domain/subdomain project ini, lalu:
sudo cp nginx-example.conf /etc/nginx/sites-available/namaproject.ilkomith.cloud
sudo ln -s /etc/nginx/sites-available/namaproject.ilkomith.cloud /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxsudo certbot --nginx -d namaproject.ilkomith.cloudCertbot otomatis update config Nginx untuk HTTPS dan redirect HTTP → HTTPS.
curl https://namaproject.ilkomith.cloud/api/auth/login -X POST \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"salah"}'Kalau balikin JSON error "Email atau password salah" (bukan error koneksi), berarti backend sudah bisa diakses lewat domain publik.
- DB tidak exposed ke publik — cuma bisa diakses dari network internal Docker (
internal), jadi nggak bisa diserang langsung dari luar. - Backend & frontend bind ke
127.0.0.1saja — akses publik wajib lewat Nginx, sehingga Nginx bisa handle SSL, rate limiting, dan logging terpusat. NEXT_PUBLIC_API_URLdi-inject saat build (ARG), bukan runtime — karena Next.js meng-inline environment variable berprefixNEXT_PUBLIC_langsung ke JS bundle saat build time, bukan dibaca ulang saat container jalan.ALLOWED_ORIGINdi backend diarahkan ke domain publik frontend — kalau nanti ada mobile app juga manggil API ini, cukup ubah logic CORS dimain.gountuk terima multiple origin, atau matikan CORS check untuk request tanpa headerOrigin(mobile app native biasanya tidak mengirim header ini).
git pull # atau update source code
docker compose up -d --buildDocker akan rebuild image yang berubah saja dan restart container terkait, minim downtime.
docker compose logs -f backend # log backend real-time
docker compose logs -f frontend # log frontend real-time
docker compose ps # status semua container