MenengahCloud & Infrastructure

Docker

Docker

Platform untuk develop, ship, dan run aplikasi dalam containers yang isolated, portable, dan lightweight.

#container#virtualization#devops#deployment#microservices

Apa itu Docker?

Docker adalah platform open-source untuk menjalankan aplikasi di dalam container. Container berisi aplikasi beserta dependency penting yang dibutuhkan, sehingga aplikasi yang sama bisa dijalankan di laptop developer, server staging, atau production dengan perilaku yang lebih konsisten.

Analogi yang sering dipakai memang kontainer pengiriman barang, dan itu cukup membantu. Isi di dalamnya bisa berbeda-beda, tetapi bentuk pengemasannya tetap sama. Di software, ide dasarnya juga mirip: aplikasi dibungkus dengan cara yang lebih seragam supaya lebih mudah dipindahkan dan dijalankan.

Masalah yang Dipecahkan Docker

"It Works on My Machine"

Sebelum Docker, masalah klasiknya sederhana: aplikasi berjalan mulus di laptop developer, tapi bermasalah saat pindah ke server.

Beberapa penyebab yang sering muncul:

  • Versi dependency berbeda
  • Konfigurasi environment tidak sama
  • OS atau library sistem tidak cocok

Docker membantu dengan cara membungkus aplikasi bersama komponen yang dibutuhkan. Hasilnya bukan berarti semua masalah hilang, tetapi perbedaan antar-environment jadi jauh lebih kecil.

Docker vs Virtual Machines

| Aspek | Docker Container | Virtual Machine | |-------|-----------------|-----------------| | Size | MB (megabytes) | GB (gigabytes) | | Startup | Detik | Menit | | Performance | Near-native | Overhead significant | | Isolation | Process-level | Hardware-level | | OS | Share host kernel | Full OS per VM | | Resource Usage | Efficient | Heavy |

Visualisasi

Virtual Machine:
┌─────────────────────────┐
│   App A   │   App B     │
├───────────┼─────────────┤
│  Guest OS │  Guest OS   │
├───────────┴─────────────┤
│     Hypervisor          │
├─────────────────────────┤
│     Host OS             │
├─────────────────────────┤
│     Hardware            │
└─────────────────────────┘

Docker:
┌─────────────────────────┐
│   App A   │   App B     │
├───────────┼─────────────┤
│ Container │ Container   │
├───────────┴─────────────┤
│    Docker Engine        │
├─────────────────────────┤
│      Host OS            │
├─────────────────────────┤
│      Hardware           │
└─────────────────────────┘

Konsep Penting Docker

1. Docker Image

Image adalah template read-only yang berisi instruksi untuk membuat container. Seperti "blueprint" atau "snapshot" dari aplikasi.

# Download image dari Docker Hub
docker pull nginx:latest
docker pull node:18-alpine
docker pull postgres:15

2. Docker Container

Container adalah running instance dari image. Satu image bisa digunakan untuk membuat banyak containers.

# Jalankan container dari image
docker run -d -p 8080:80 nginx:latest

# List running containers
docker ps

# Stop container
docker stop <container_id>

3. Dockerfile

File instruksi untuk build Docker image. Seperti "recipe" untuk membuat image.

# Contoh Dockerfile untuk Node.js app
FROM node:18-alpine

# Set working directory
WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm ci --production

# Copy source code
COPY . .

# Expose port
EXPOSE 3000

# Set environment
ENV NODE_ENV=production

# Command to run
CMD ["node", "server.js"]

4. Docker Compose

Tool untuk define dan run multi-container applications.

# docker-compose.yml
version: '3.8'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://db:5432/myapp
    depends_on:
      - db
      - redis
  
  db:
    image: postgres:15
    environment:
      - POSTGRES_PASSWORD=secret
      - POSTGRES_DB=myapp
    volumes:
      - postgres_data:/var/lib/postgresql/data
  
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  postgres_data:
# Jalankan semua services
docker-compose up -d

# Stop semua services
docker-compose down

Docker Commands Essentials

Image Management

# List images
docker images

# Build image dari Dockerfile
docker build -t myapp:v1 .

# Tag image
docker tag myapp:v1 username/myapp:v1

# Push ke registry
docker push username/myapp:v1

# Remove image
docker rmi myapp:v1

Container Management

# Run container
docker run -d --name myapp -p 8080:3000 myapp:v1

# Run dengan environment variables
docker run -d -e DATABASE_URL=postgres://... myapp:v1

# Run dengan volumes
docker run -d -v /host/path:/container/path myapp:v1

# Execute command di running container
docker exec -it myapp /bin/sh

# View logs
docker logs myapp
docker logs -f myapp  # Follow logs

# Stop container
docker stop myapp

# Start stopped container
docker start myapp

# Remove container
docker rm myapp

# Remove all stopped containers
docker container prune

System Commands

# Show Docker info
docker info

# Show disk usage
docker system df

# Clean up unused resources
docker system prune -a

# View container resource usage
docker stats

Dockerfile Best Practices

1. Gunakan Official Base Images

Kurang tepat:

FROM ubuntu
RUN apt-get update && apt-get install -y nodejs

Lebih baik:

FROM node:18-alpine

2. Minimize Layers

Kurang efisien:

RUN apt-get update
RUN apt-get install -y git
RUN apt-get install -y curl

Lebih efisien:

RUN apt-get update && apt-get install -y \
    git \
    curl \
    && rm -rf /var/lib/apt/lists/*

3. Multi-Stage Builds

Untuk mengurangi final image size:

# Build stage
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 3000
CMD ["node", "dist/server.js"]

4. .dockerignore File

Exclude files dari build context:

# .dockerignore
node_modules
npm-debug.log
.git
.env
.DS_Store
dist
coverage
*.md

5. Security Best Practices

# Don't run as root
FROM node:18-alpine

# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

WORKDIR /app
COPY --chown=nodejs:nodejs . .
RUN npm ci --production

# Switch to non-root user
USER nodejs

EXPOSE 3000
CMD ["node", "server.js"]

Docker Networking

Bridge Network (Default)

Containers di network yang sama bisa communicate by name.

# Create custom network
docker network create mynetwork

# Run containers di network yang sama
docker run -d --name db --network mynetwork postgres
docker run -d --name app --network mynetwork myapp

# App bisa connect ke db dengan: postgres://db:5432

Port Mapping

# Map container port ke host port
docker run -p 8080:3000 myapp  # host:container

# Multiple ports
docker run -p 8080:3000 -p 8081:3001 myapp

# All ports
docker run -P myapp

Docker Volumes

Untuk persistent data storage:

Named Volumes

# Create volume
docker volume create mydata

# Use volume
docker run -v mydata:/app/data myapp

# List volumes
docker volume ls

# Inspect volume
docker volume inspect mydata

Bind Mounts

Mount host directory ke container:

# Development: Live reload
docker run -v $(pwd):/app myapp

# Windows
docker run -v %cd%:/app myapp

Real-World Use Cases

1. Development Environment

# docker-compose.dev.yml
version: '3.8'
services:
  app:
    build: .
    volumes:
      - .:/app
      - /app/node_modules
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
    command: npm run dev

2. Microservices Architecture

version: '3.8'
services:
  frontend:
    image: myapp/frontend
    ports:
      - "80:80"
  
  api-gateway:
    image: myapp/api-gateway
    ports:
      - "8080:8080"
  
  user-service:
    image: myapp/user-service
  
  product-service:
    image: myapp/product-service
  
  order-service:
    image: myapp/order-service

3. CI/CD Integration

# .github/workflows/docker.yml
name: Docker Build and Push
on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      
      - name: Build Docker image
        run: docker build -t myapp:${{ github.sha }} .
      
      - name: Push to registry
        run: |
          echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
          docker push myapp:${{ github.sha }}

Docker di Production

Orchestration Tools

Untuk manage containers di scale:

  1. Docker Swarm - Built-in Docker orchestration
  2. Kubernetes - Pilihan yang paling sering dipakai untuk container orchestration
  3. AWS ECS - Amazon's container service
  4. Google Cloud Run - Serverless containers

Health Checks

HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:3000/health || exit 1

Resource Limits

# Limit memory dan CPU
docker run -m 512m --cpus=1 myapp

Docker untuk Developer Indonesia

Keuntungan

  1. Environment lebih konsisten - Dev, staging, dan production tidak terlalu jauh bedanya
  2. Project lebih terisolasi - Dependency antarproject tidak mudah saling bentrok
  3. Setup lebih cepat - Project baru bisa dijalankan tanpa instalasi manual yang panjang
  4. Kolaborasi lebih rapi - Tim memakai environment yang kurang lebih sama
  5. Eksperimen lebih aman - Mencoba database, message broker, atau service lain jadi lebih mudah

Tantangan

  1. Perlu adaptasi di awal - Konsep image, container, volume, dan network butuh waktu untuk dipahami
  2. Butuh ruang penyimpanan - Image dan volume bisa cepat membesar
  3. Ada overhead di Windows atau macOS - Biasanya lewat Docker Desktop
  4. Debugging networking kadang membingungkan - Terutama saat baru mulai

Tips Mulai dengan Docker

  1. Mulai dari satu service - Jangan langsung memindahkan seluruh sistem sekaligus
  2. Pakai official image - Lebih aman untuk belajar dan biasanya dokumentasinya lebih rapi
  3. Pelajari Docker Compose - Sangat membantu saat aplikasi punya beberapa service
  4. Coba di project yang sudah Anda kenal - Lebih mudah memahami perubahan perilakunya
  5. Ikuti komunitas - Banyak kasus sehari-hari justru lebih cepat dipahami dari diskusi developer lain

Alternatif Docker

  • Podman - Daemonless, rootless containers
  • LXC/LXD - System containers
  • rkt - Alternative container runtime (deprecated)
  • containerd - Core container runtime (Docker menggunakan ini)

Docker dengan smbCloud

smbCloud mendukung deployment berbasis Docker tanpa alur setup yang panjang.

# smbCloud auto-detect Dockerfile
$ cat Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install
CMD ["npm", "start"]

$ git push smb main
# smbCloud build image dan deploy otomatis

Keunggulan:

  • Tidak perlu menyiapkan Docker registry sendiri untuk alur dasar
  • Image bisa dibangun langsung dari Dockerfile
  • Container dapat diskalakan lewat fitur platform
  • Monitoring dasar sudah tersedia

Troubleshooting Common Issues

Container Exits Immediately

# Check logs
docker logs <container_id>

# Run interactively untuk debug
docker run -it myapp /bin/sh

Port Already in Use

# Find process using port
lsof -i :8080  # Mac/Linux
netstat -ano | findstr :8080  # Windows

# Kill process atau use different port
docker run -p 8081:3000 myapp

Out of Disk Space

# Remove unused images
docker image prune -a

# Remove unused volumes
docker volume prune

# Clean everything
docker system prune -a --volumes

Kesimpulan

Docker membantu developer menjalankan aplikasi dengan lingkungan yang lebih konsisten. Itu sebabnya Docker sering dipakai untuk development, testing, CI/CD, sampai deployment.

Kalau Anda baru belajar, tidak perlu langsung memikirkan cluster besar atau arsitektur rumit. Cukup mulai dari satu aplikasi, pahami Dockerfile, bedakan image dan container, lalu coba jalankan beberapa service dengan Compose. Setelah itu, konsep yang lebih lanjut biasanya terasa jauh lebih masuk akal.

Istilah Terkait

Lainnya dalam Cloud & Infrastructure

Siap membangun dengan smbCloud?

Deploy NodeJS, Swift, dan Ruby dengan satu perintah.

Mulai dengan smbCloud →

Terakhir diperbarui: 15 Januari 2024