DP
Kembali ke Tutorial
DevOpsMenengah

Docker untuk Developer: Containerize Aplikasi Node.js

Pelajari Docker dari dasar dengan contoh aplikasi Node.js: image, container, Dockerfile, volume, network, Docker Compose, environment variable, dan workflow development.

6 menit baca1 Mei 2025oleh Dosen Programming

Docker untuk Developer: Containerize Aplikasi Node.js

Docker membantu developer menjalankan aplikasi dalam container. Container berisi runtime, dependency, konfigurasi dasar, dan proses aplikasi sehingga lingkungan development, testing, dan deployment dapat dibuat lebih konsisten.

Masalah klasik dalam pengembangan aplikasi adalah "jalan di laptop saya, tetapi error di laptop orang lain". Docker tidak menghapus semua masalah, tetapi membantu membuat lingkungan lebih eksplisit dan dapat direplikasi.

Tujuan Belajar

Setelah membaca tutorial ini, kamu diharapkan mampu:

  • Menjelaskan perbedaan image dan container.
  • Membuat Dockerfile untuk aplikasi Node.js sederhana.
  • Menjalankan container dengan port dan environment variable.
  • Memahami volume untuk data yang perlu bertahan.
  • Memakai Docker Compose untuk menjalankan aplikasi dan database bersama.
  • Membaca log container dan melakukan debugging dasar.
  • Menghindari kesalahan umum seperti memasukkan secret ke image.

Image dan Container

Image adalah blueprint. Container adalah proses yang berjalan dari image. Analogi sederhananya: image seperti resep, container seperti masakan yang dibuat dari resep tersebut.

IstilahMakna
ImagePaket berisi filesystem, runtime, dependency, dan instruksi menjalankan aplikasi.
ContainerInstance berjalan dari image.
DockerfileFile instruksi untuk membangun image.
RegistryTempat menyimpan dan mengambil image, misalnya Docker Hub atau registry privat.

Satu image dapat dipakai untuk membuat banyak container.

Aplikasi Node.js Sederhana

Misalkan kita punya aplikasi Express kecil.

json
{
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.18.0"
  }
}

File server.js:

js
const express = require("express");

const app = express();
const port = process.env.PORT || 3000;

app.get("/", (_req, res) => {
  res.json({
    message: "Aplikasi berjalan di Docker",
    time: new Date().toISOString(),
  });
});

app.listen(port, () => {
  console.log(`Server berjalan di port ${port}`);
});

Aplikasi ini membaca PORT dari environment variable. Pola ini penting karena port dan konfigurasi sering berbeda antara development dan production.

Dockerfile Dasar

Dockerfile berikut membangun image untuk aplikasi Node.js.

dockerfile
FROM node:20-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --omit=dev

COPY . .

ENV NODE_ENV=production
ENV PORT=3000

EXPOSE 3000

CMD ["npm", "start"]

Penjelasan singkat:

  • FROM menentukan base image.
  • WORKDIR menentukan folder kerja di dalam container.
  • COPY package*.json ./ menyalin manifest dependency lebih dulu agar cache build lebih efektif.
  • RUN npm ci --omit=dev menginstal dependency production.
  • COPY . . menyalin source code aplikasi.
  • EXPOSE mendokumentasikan port yang dipakai aplikasi.
  • CMD menentukan command default saat container berjalan.

.dockerignore

Jangan menyalin semua file lokal ke image. Buat .dockerignore.

text
node_modules
npm-debug.log
.git
.env
.next
coverage

File .env sebaiknya tidak masuk image. Secret diberikan saat runtime melalui environment variable atau secret manager.

Build dan Run

Bangun image:

bash
docker build -t node-docker-demo .

Jalankan container:

bash
docker run --rm -p 3000:3000 node-docker-demo

Format -p 3000:3000 berarti port 3000 di host diarahkan ke port 3000 di container.

Menjalankan dengan environment variable:

bash
docker run --rm -p 8080:8080 -e PORT=8080 node-docker-demo

Log dan Debugging Dasar

Melihat container berjalan:

bash
docker ps

Melihat log:

bash
docker logs <container-id>

Masuk ke shell container:

bash
docker exec -it <container-id> sh

Pada image Alpine, shell yang tersedia biasanya sh, bukan bash.

Volume: Data yang Bertahan

Container bersifat disposable. Jika container dihapus, perubahan file di dalam container bisa ikut hilang. Volume dipakai untuk data yang perlu bertahan, misalnya data database.

bash
docker volume create pgdata

Contoh menjalankan PostgreSQL dengan volume:

bash
docker run --rm \
  --name demo-postgres \
  -e POSTGRES_PASSWORD=secret \
  -e POSTGRES_DB=app_db \
  -v pgdata:/var/lib/postgresql/data \
  -p 5432:5432 \
  postgres:16

Pada Windows PowerShell, multiline command bisa berbeda. Jika bingung, tulis command dalam satu baris terlebih dahulu.

Network: Komunikasi Antarcontainer

Jika aplikasi dan database berjalan sebagai container terpisah, keduanya perlu berada di network yang sama.

bash
docker network create app-network

Database:

bash
docker run -d \
  --name db \
  --network app-network \
  -e POSTGRES_PASSWORD=secret \
  -e POSTGRES_DB=app_db \
  postgres:16

Aplikasi:

bash
docker run -d \
  --name app \
  --network app-network \
  -p 3000:3000 \
  -e DATABASE_URL=postgresql://postgres:secret@db:5432/app_db \
  node-docker-demo

Perhatikan host database memakai db, yaitu nama container database dalam network yang sama.

Docker Compose

Docker Compose membuat definisi multi-container lebih rapi.

yaml
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://postgres:secret@db:5432/app_db
    depends_on:
      - db

  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app_db
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Jalankan:

bash
docker compose up --build

Hentikan:

bash
docker compose down

Jika ingin menghapus volume juga, gunakan opsi -v dengan hati-hati karena data database akan ikut terhapus.

Development vs Production

Dockerfile production biasanya menginstal dependency production dan menjalankan build final. Untuk development, kita sering butuh hot reload dan bind mount.

Contoh Compose development:

yaml
services:
  app:
    image: node:20-alpine
    working_dir: /app
    command: sh -c "npm install && npm run dev"
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - node_modules:/app/node_modules
    environment:
      NODE_ENV: development

volumes:
  node_modules:

Pola development perlu disesuaikan dengan framework yang digunakan. Tujuannya adalah feedback cepat, bukan image sekecil mungkin.

Kesalahan Umum

KesalahanDampakPerbaikan
Menyalin .env ke imageSecret bisa bocorMasukkan .env ke .dockerignore.
Tidak memakai volume untuk databaseData hilang saat container dihapusGunakan named volume.
Menganggap localhost selalu menunjuk hostDi container, localhost adalah container itu sendiriGunakan nama service/container di network.
Image terlalu besarBuild dan pull lambatGunakan base image sesuai kebutuhan dan .dockerignore.
Menghapus volume tanpa sadarData hilangBaca command sebelum memakai docker compose down -v.

Coba Sendiri

Buat aplikasi Node.js kecil dengan endpoint berikut:

  • GET / mengembalikan pesan aplikasi berjalan.
  • GET /health mengembalikan { "status": "ok" }.
  • Port dibaca dari environment variable PORT.

Kemudian:

  • Buat Dockerfile.
  • Buat .dockerignore.
  • Build image.
  • Jalankan container di port 3000.
  • Ubah port menjadi 8080 melalui environment variable.
  • Tambahkan Compose file dengan service app dan db.

Catat command yang kamu jalankan dan error yang muncul jika ada. Dokumentasi kecil seperti ini akan sangat membantu saat deployment.

Cek Pemahaman

Kuis

Apa perbedaan paling tepat antara image dan container?

Pilih satu jawaban.

Kuis

Mengapa database dalam container biasanya memakai volume?

Pilih satu jawaban.

Ringkasan

Docker membantu membuat lingkungan aplikasi lebih konsisten. Pahami image, container, Dockerfile, .dockerignore, port, environment variable, volume, network, dan Compose. Untuk aplikasi produksi, jaga image tetap bersih dan jangan memasukkan secret. Untuk development, susun workflow yang memberi feedback cepat tanpa mengorbankan pemahaman terhadap container.

#docker#devops#nodejs#deployment#container
Apakah konten ini membantu?

Feedback kamu membantu kami memperbaiki materi berikutnya.

Diskusi (0)

Silakan masuk terlebih dahulu untuk ikut berdiskusi

Login Sekarang