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:
- Docker Swarm - Built-in Docker orchestration
- Kubernetes - Pilihan yang paling sering dipakai untuk container orchestration
- AWS ECS - Amazon's container service
- 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
- Environment lebih konsisten - Dev, staging, dan production tidak terlalu jauh bedanya
- Project lebih terisolasi - Dependency antarproject tidak mudah saling bentrok
- Setup lebih cepat - Project baru bisa dijalankan tanpa instalasi manual yang panjang
- Kolaborasi lebih rapi - Tim memakai environment yang kurang lebih sama
- Eksperimen lebih aman - Mencoba database, message broker, atau service lain jadi lebih mudah
Tantangan
- Perlu adaptasi di awal - Konsep image, container, volume, dan network butuh waktu untuk dipahami
- Butuh ruang penyimpanan - Image dan volume bisa cepat membesar
- Ada overhead di Windows atau macOS - Biasanya lewat Docker Desktop
- Debugging networking kadang membingungkan - Terutama saat baru mulai
Tips Mulai dengan Docker
- Mulai dari satu service - Jangan langsung memindahkan seluruh sistem sekaligus
- Pakai official image - Lebih aman untuk belajar dan biasanya dokumentasinya lebih rapi
- Pelajari Docker Compose - Sangat membantu saat aplikasi punya beberapa service
- Coba di project yang sudah Anda kenal - Lebih mudah memahami perubahan perilakunya
- 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.