Paket 1 · Fondasi DevOpsModul I — Docker & Containerization

Dockerfile, Docker Compose, dan Application Deployment

Menulis Dockerfile multi-stage, membangun image, menyusun Docker Compose untuk aplikasi dan database, lalu men-deploy-nya.

Setelah memahami komponen Docker, saatnya mengemas aplikasi sendiri. Modul ini membahas Dockerfile, Docker Compose, dan alur deployment aplikasi Node.js.

Dockerfile

Dockerfile adalah resep untuk membangun image.

Instruksi penting

InstruksiFungsi
FROMImage dasar
WORKDIRDirektori kerja
COPYMenyalin file dari build context
RUNMenjalankan perintah saat build
ENVEnvironment variable
EXPOSEDokumentasi port
USERUser saat container berjalan
CMDPerintah default container
ENTRYPOINTEntry point utama
HEALTHCHECKCek kesehatan container

Dockerfile Node.js multi-stage

# Stage 1: dependencies
FROM node:22-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

# Stage 2: build
FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# Stage 3: runtime
FROM node:22-alpine AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --omit=dev && npm cache clean --force
COPY --from=build /app/dist ./dist
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]

Keuntungan multi-stage:

  • Image akhir lebih kecil.
  • Build tools tidak ikut masuk runtime.
  • Mengurangi attack surface.

.dockerignore

node_modules
.git
.env
npm-debug.log
Dockerfile
docker-compose.yml

.dockerignore mencegah file besar/rahasia masuk ke build context dan image.

Jangan COPY .env ke image

File .env berisi rahasia. Masukkan ke .dockerignore dan berikan environment saat runtime melalui Compose, Docker secrets, atau platform deployment.

Build dan jalankan

docker build -t myapp:1.0.0 .
docker images | grep myapp
docker run -d --name myapp -p 3000:3000 --env-file .env myapp:1.0.0
docker logs -f myapp
curl -I http://localhost:3000

Tag juga dengan latest bila sesuai:

docker tag myapp:1.0.0 myapp:latest

Docker Compose

Compose mendefinisikan beberapa container dalam satu file YAML.

Struktur dasar

services:
  app:
    build: .
    container_name: myapp
    restart: unless-stopped
    ports:
      - "3000:3000"
    env_file:
      - .env
    depends_on:
      db:
        condition: service_healthy
    networks:
      - app-net

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - app-net

volumes:
  db-data:

networks:
  app-net:

Environment

Buat .env di direktori Compose:

DB_PASSWORD=ganti-dengan-password-kuat
NODE_ENV=production
PORT=3000

Compose membaca .env otomatis untuk substitusi ${DB_PASSWORD}.

Menjalankan

docker compose up -d
docker compose ps
docker compose logs -f app
docker compose exec app sh
docker compose down
docker compose down -v
PerintahFungsi
up -dBangun dan jalankan di background
psStatus service
logs -fIkuti log
execMasuk ke container
downHentikan dan hapus container
down -vHapus juga volume (hati-hati)
buildBangun ulang image
pullAmbil image terbaru

down -v menghapus data volume

docker compose down -v menghapus named volume. Jangan jalankan pada produksi tanpa backup dan tanpa memahami konsekuensinya.

Deployment dengan Compose

Alur umum di server:

# 1. Ambil kode terbaru
git pull

# 2. Bangun ulang image
docker compose build --pull

# 3. Jalankan dengan zero-downtime terbatas
docker compose up -d

# 4. Cek status dan log
docker compose ps
docker compose logs --tail=100 app

Untuk pembaruan bertahap, beberapa strategi:

  • docker compose up -d --no-deps app untuk hanya recreate service aplikasi.
  • Gunakan reverse proxy dengan health check sebelum mengarahkan trafik.
  • Simpan image versi sebelumnya untuk rollback.

Rollback sederhana

docker tag myapp:1.0.0 myapp:rollback
docker compose up -d --no-deps app

Atau ubah tag image di Compose ke versi sebelumnya lalu up -d.

Integrasi reverse proxy

Di NPM, arahkan proxy host ke http://IP-SERVER:3000 atau http://nama-container:3000 bila NPM berada di jaringan Docker yang sama.

app.example.com → NPM → myapp:3000

Pastikan aplikasi listen di 0.0.0.0 di dalam container.

Troubleshooting

GejalaCek
Container langsung exitdocker logs <container>
port is already allocatedPort host bentrok, docker ps
Aplikasi tidak bisa akses DBNama host, network, healthcheck
Build lambatUrutan layer, cache, .dockerignore
Image besarMulti-stage, base image, file tidak perlu
Data hilangVolume belum dipasang
Permission deniedUSER, owner file, bind mount

Debug container

docker ps -a
docker logs --tail=200 myapp
docker inspect myapp
docker exec -it myapp sh
docker compose config

Praktik: deploy aplikasi + database

  1. Buat Dockerfile multi-stage.
  2. Buat .dockerignore.
  3. Buat docker-compose.yml dengan service app dan db.
  4. Buat .env dan amankan permission.
  5. Jalankan docker compose up -d.
  6. Cek docker compose ps dan log.
  7. Uji health endpoint.
  8. Arahkan reverse proxy ke aplikasi.
  9. Simpan tag image versi rilis untuk rollback.

Ringkasan

  • Dockerfile membangun image; multi-stage menghasilkan image runtime yang kecil.
  • .dockerignore mencegah file rahasia dan tidak perlu masuk image.
  • Compose mengelola aplikasi, database, network, dan volume dalam satu file.
  • Deployment yang baik memakai image bertag, health check, dan rencana rollback.

Selesai — Paket 1

Anda telah menyelesaikan fondasi DevOps: virtualisasi, Linux, jaringan, administrasi server, Tailscale, domain/Cloudflare, deployment PM2, dan Docker. Lanjutkan ke Paket 2 untuk CI/CD, deployment produksi, observability, DevSecOps, otomasi infrastruktur, dan Kubernetes.

On this page