KerjaLab: Simulasi Kerja Multi-Tier dengan Docker Compose di Localhost
Masalah yang Ingin Diselesaikan Banyak mahasiswa dan fresh graduate bingung membayangkan seperti apa pekerjaan nyata di bidang yang mereka incar. Teori di kelas tidak selalu sama dengan praktik di dunia kerja. Di sisi
Masalah yang Ingin Diselesaikan
Banyak mahasiswa dan fresh graduate bingung membayangkan seperti apa pekerjaan nyata di bidang yang mereka incar. Teori di kelas tidak selalu sama dengan praktik di dunia kerja. Di sisi lain, perusahaan sulit menilai kemampuan hard skill maupun soft skill kandidat hanya dari CV.
KerjaLab adalah aplikasi web simulasi kerja yang menjawab masalah itu. Pengguna memilih bidang (Teknologi, Sains, Bisnis, atau Soft Skill), mengerjakan simulasi dengan batas waktu, lalu mendapat koin untuk kustomisasi profil dan XP untuk menaikkan level skill. Jika gagal, pengguna boleh mencoba lagi tanpa penalti, sehingga KerjaLab menjadi ruang aman untuk mencoba pekerjaan impian sebelum berkomitmen.
Fitur utamanya:
- Login Google dengan persetujuan (consent) eksplisit sesuai UU No. 27 Tahun 2022 tentang Pelindungan Data Pribadi.
- 12 simulasi dalam 4 bidang dengan 3 tingkat kesulitan. Semakin sulit, semakin besar hadiahnya.
- Tantangan harian dengan streak sebagai bonus.
- Profil yang menampilkan level hard skill dan soft skill, jumlah dan total waktu simulasi, serta link LinkedIn dan GitHub.
- Hak penghapusan data: pengguna dapat menghapus akun dan seluruh datanya.
Mengapa Proyek Ini
Saya mengarah ke peran Cloud/DevOps Engineer. Aplikasi ini memberi alasan nyata untuk merancang arsitektur multi-tier: frontend, backend, dan database yang masing-masing berjalan di container, lalu dirakit dengan Docker Compose. Fokus penilaiannya ada pada containerization, jadi fitur dibuat secukupnya.
Arsitektur
Tiga tier berjalan pada satu user-defined network bernama kerjalab-net:
| Container | Teknologi | Port ke localhost |
|---|---|---|
| frontend | Next.js | 3000 |
| backend | Node.js (Express) | 4000 |
| db | PostgreSQL 16 | tidak dibuka |
adminer (profile tools) |
Adminer | 8080 |
Alur request: browser mengakses http://localhost:3000, lalu Next.js meneruskan panggilan /api/* ke http://backend:4000. Backend terhubung ke database lewat db:5432. Data disimpan di named volume kerjalab_pgdata. Database tidak dipublikasikan ke localhost, sehingga hanya container di dalam network yang bisa mengaksesnya.
Container dipilih dibanding virtual machine karena berbagi kernel host. Isolasinya memakai namespaces dan pembatasan sumber daya memakai cgroups, sehingga image jauh lebih kecil dan startup hanya hitungan detik, bukan menit seperti VM.
Dockerfile: Multi-Stage Build
Backend memakai dua stage. Stage builder memasang dependency, sedangkan stage runtime hanya membawa hasil yang diperlukan.
FROM node:22.14.0-alpine3.21 AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
COPY src ./src
FROM node:22.14.0-alpine3.21 AS runtime
ENV NODE_ENV=production PORT=4000
WORKDIR /app
COPY --from=builder --chown=node:node /app ./
USER node
EXPOSE 4000
CMD ["node", "src/index.js"]
Penjelasan singkat:
-
Tag versi spesifik (
22.14.0-alpine3.21), bukanlatest, agar build dapat diulang dengan hasil yang sama. -
File dependency disalin lebih dulu sebelum source code. Selama
package.jsontidak berubah, layernpm cidiambil dari cache sehingga build jauh lebih cepat. -
Multi-stage membuat image akhir tidak membawa cache npm dan tool build. Hanya
node_modulesproduksi dansrcyang ikut terbawa. -
COPY, bukanADD.COPYhanya menyalin file.ADDpunya fungsi tambahan (ekstraksi tar dan unduh dari URL) yang membuat perilakunya kurang transparan. -
CMDdalam exec form membuat prosesnodemenjadi PID 1 dan menerima sinyal penghentian langsung dari Docker. -
.dockerignoremencegahnode_modules,.env, dan.gitikut masuk ke konteks build.
Frontend memakai tiga stage (deps, builder, runtime) dengan mode standalone bawaan Next.js, sehingga image runtime hanya berisi server minimal.
Docker Compose
services:
db:
image: postgres:16.6-alpine
volumes:
- kerjalab_pgdata:/var/lib/postgresql/data
networks: [kerjalab-net]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 5s
retries: 10
backend:
build: ./backend
environment:
DB_HOST: db
depends_on:
db:
condition: service_healthy
networks: [kerjalab-net]
adminer:
image: adminer:4.8.1
profiles: ["tools"]
Poin pentingnya:
- Backend memakai
DB_HOST: db, yaitu nama service, bukan IP ataulocalhost. DNS internal Docker yang menerjemahkannya. -
healthcheckpada database dandepends_ondengancondition: service_healthymemastikan backend baru berjalan setelah PostgreSQL benar-benar siap menerima koneksi. -
Named volume menjaga data tetap ada setelah
docker compose down. Hanyadocker compose down -vyang ikut menghapus volume. - Konfigurasi dibaca dari file
.env. Yang masuk repository hanya.env.exampleberisi nilai dummy, sehingga tidak ada secret yang ter-commit. - Service
adminerberada di profiletools, jadi hanya aktif saat dibutuhkan dengandocker compose --profile tools up -d.
Cara Menjalankan di Localhost
git clone https://github.com/valentntnt/KerjaLab.git
cd KerjaLab
cp .env.example .env
docker compose up -d --build
Buka http://localhost:3000. Untuk mengecek kesehatan service:
docker compose ps
curl -i http://localhost:4000/health
Untuk menguji persistensi, buat data lalu jalankan docker compose down dan docker compose up -d. Data masih ada karena tersimpan di named volume.
Pelajaran yang Didapat
- Urutan perintah Dockerfile memengaruhi kecepatan build. Menaruh instruksi yang jarang berubah di atas membuat layer cache terpakai maksimal.
- Multi-stage build adalah cara paling sederhana menjaga image tetap ramping tanpa mengorbankan kemudahan proses build.
-
depends_onsaja tidak cukup. Container yang sudah start belum tentu siap. Healthcheck denganservice_healthymenyelesaikan masalah itu. -
Pemisahan konfigurasi dari kode lewat
.envdan.env.examplemenjaga secret tetap aman sekaligus memudahkan orang lain menjalankan proyek. -
Container memudahkan perpindahan ke cloud. Karena aplikasi sudah dikemas bersama dependensinya, memindahkannya ke VM cloud kelak cukup dengan menginstal Docker lalu menjalankan
docker compose up.
Tautan
- Repository GitHub: https://github.com/valentntnt/KerjaLab
- Video demo YouTube: GANTI_DENGAN_LINK_YOUTUBE
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.

