DEV Community

farrelwidjaja
farrelwidjaja

Posted on

Building a Cloud-Native Multi-Tier Laundry POS with Docker Compose, WhatsApp Bot, and QR E-Receipts

Oleh: Farrel Widjaja - Mahasiswa Computer Science BINUS University (NIM: 2802408865)

Seiring dengan berkembangnya bisnis jasa cuci pakaian, usaha laundry kiloan dan rumahan sering menghadapi kendala operasional yang berulang. Masalah yang paling sering terjadi adalah pakaian pelanggan yang tertukar akibat nota kertas yang basah atau sobek saat proses pencucian, pemilik laundry yang kewalahan membalas chat WhatsApp pelanggan yang berulang kali menanyakan status cucian mereka, serta penumpukan pakaian di rak penyimpanan karena pelanggan lupa mengambil cuciannya.

Untuk menyelesaikan permasalahan nyata tersebut, saya merancang dan mengembangkan Rels Laundry (https://rels-laundry.vercel.app/
), sebuah platform Point of Sale (POS) dan manajemen operasional laundry berbasis cloud-native. Sistem ini mengintegrasikan kasir digital cepat dengan kalkulasi tarif otomatis, pembuatan E-Receipt ber-QR Code unik yang dapat langsung discan pelanggan untuk melacak status pakaian secara real-time tanpa perlu login, serta Bot WhatsApp cerdas yang aktif 24 jam untuk melayani pengecekan status pesanan dan daftar harga.

Berikut adalah ringkasan teknis mengenai arsitektur sistem, containerisasi Docker, dan penerapan orkestrasi multi-tier yang saya gunakan pada projek ini.

Desain Arsitektur Multi-Tier
Aplikasi Rels Laundry dibangun dengan arsitektur multi-tier yang membagi komponen sistem ke dalam beberapa container terpisah di dalam satu jaringan Docker bridge (laundry_network):

Service Aplikasi (app): Backend Express.js (Node.js 22 LTS) yang melayani REST API (/api/orders, /health, /api/whatsapp) sekaligus menampilkan antarmuka web SPA berbasis Tailwind CSS pada port 3000.
Service Database (db): Database relasional PostgreSQL 16 Alpine yang bertugas menyimpan data transaksi, data pelanggan, dan status pesanan laundry.
Service Caching (cache): Redis 7.2 Alpine yang berfungsi sebagai in-memory cache untuk mempercepat waktu respon query pesanan tanpa membebani database utama.
Service Manajemen (adminer): Antarmuka web Adminer pada port 8080 di bawah profile tools untuk memudahkan inspeksi database saat proses development.
Seluruh container saling berkomunikasi secara aman menggunakan DNS internal Docker (db:5432 dan cache:6379), bukan menggunakan alamat IP statis atau localhost host.

Optimasi Dockerfile Multi-Stage
Untuk meminimalkan celah keamanan dan memperkecil ukuran image, saya menerapkan strategi multi-stage build yang membagi proses menjadi dua tahap: builder dan runtime.

Tahap builder bertugas menyalin file package.json dan menjalankan perintah npm ci --omit=dev untuk mengunduh dependensi produksi. Dengan menyalin package.json sebelum source code aplikasi, proses build dapat memanfaatkan layer caching Docker secara optimal ketika terjadi perubahan kode program.

Tahap runtime menggunakan base image ringan node:22.11.0-alpine3.20. Pada tahap ini, hanya file dependensi yang sudah jadi dan source code aplikasi yang disalin dari stage builder. Untuk menjaga keamanan, aplikasi dijalankan menggunakan user non-root (USER node) sesuai prinsip least privilege. Port 3000 dibuka dan aplikasi dijalankan menggunakan exec form CMD ["node", "src/server.js"] agar dapat menangani sinyal OS untuk graceful shutdown. Saya juga memilih perintah COPY alih-alih ADD untuk mencegah ekstraksi file arsip yang tidak disengaja. Berkat pendekatan multi-stage ini, ukuran image akhir menjadi sangat ramping, yaitu sekitar 184 MB.

Orkestrasi dan Persistensi Data dengan Docker Compose
Seluruh service diatur melalui file docker-compose.yml. Agar data transaksi tidak hilang saat container dihentikan, data PostgreSQL dipetakan ke named volume postgres_data di storage host.

Service app juga dilengkapi konfigurasi depends_on dengan kondisi service_healthy. Konfigurasi ini memastikan aplikasi backend Node.js hanya akan berjalan setelah database PostgreSQL benar-benar siap menerima koneksi berdasarkan probe pg_isready.

Untuk menguji persistensi data, saya membuat pesanan baru melalui kasir POS, kemudian menjalankan perintah docker compose down untuk mematikan seluruh container. Ketika aplikasi dinyalakan kembali dengan perintah docker compose up -d, seluruh data transaksi pesanan yang telah diinput sebelumnya tetap utuh dan tersimpan rapi. Hal ini membuktikan keandalan named volume, berbeda dengan perintah docker compose down -v yang akan menghapus volume dan me-reset seluruh isi database.

Cara Menjalankan di Komputer Lokal
Aplikasi ini dapat dijalankan dengan mudah di komputer lokal menggunakan tiga perintah sederhana:

Pertama, clone repository dari GitHub: git clone https://github.com/farrelwidjaja/rels-laundry.git
cd rels-laundry

Kedua, siapkan file konfigurasi environment: cp .env.example .env

Ketiga, jalankan seluruh container: docker compose up -d --build

Setelah proses selesai, aplikasi web Rels Laundry dapat langsung dibuka melalui browser di alamat http://localhost:3000
.

Pelajaran yang Didapat
Melalui pengerjaan projek ini, saya belajar bahwa containerization bukan sekadar membungkus aplikasi, melainkan tentang standarisasi lingkungan kerja, isolasi jaringan, dan jaminan persistensi data yang andal. Dengan memisahkan service ke dalam arsitektur multi-tier, aplikasi menjadi modular, mudah dipelihara, dan sangat siap dipindahkan ke lingkungan cloud publik seperti AWS, GCP, maupun Vercel.

Tautan Projek:

Repository GitHub: https://github.com/farrelwidjaja/rels-laundry
Live Demo Website: https://rels-laundry.vercel.app/

Top comments (0)