spinny:~/writing $ vim docker-containers-complete-guide.md
1~2Docker mengubah cara kita membangun, mengirim, dan menjalankan perangkat lunak. Alih-alih "berjalan di mesin saya", Docker menjamin bahwa aplikasi Anda berjalan dengan cara yang sama di mana saja - di laptop Anda, di mesin rekan kerja, di CI/CD, dan di produksi. Dalam panduan ini, kita akan mulai dari nol hingga men-deploy aplikasi nyata.3~4## Apa itu Docker?5~6Docker adalah platform yang mengemas aplikasi Anda dan semua dependensinya ke dalam unit standar yang disebut **container**. Container adalah proses yang terisolasi dan ringan yang berbagi kernel OS host tetapi memiliki filesystem, jaringan, dan ruang proses sendiri.7~8```mermaid9graph TD10 subgraph "Traditional Deployment"11 A1[App 1] --> OS1[Guest OS]12 A2[App 2] --> OS2[Guest OS]13 OS1 --> HV[Hypervisor]14 OS2 --> HV15 HV --> HW1[Hardware]16 end17~18 subgraph "Docker Deployment"19 B1[App 1] --> D1[Container]20 B2[App 2] --> D2[Container]21 D1 --> DE[Docker Engine]22 D2 --> DE23 DE --> HW2[Hardware]24 end25```26~27### Container vs Mesin Virtual28~29| Aspek | Container | Mesin Virtual |30|-------|-----------|---------------|31| **Startup** | Detik | Menit |32| **Ukuran** | MB | GB |33| **OS** | Berbagi kernel host | OS tamu penuh |34| **Isolasi** | Level proses | Level hardware |35| **Performa** | Hampir native | Overhead dari hypervisor |36| **Kepadatan** | Ratusan per host | Puluhan per host |37~38## Menginstal Docker39~40```bash41# macOS42brew install --cask docker43~44# Ubuntu/Debian45curl -fsSL https://get.docker.com | sh46sudo usermod -aG docker $USER47~48# Verify installation49docker --version50docker run hello-world51```52~53## Konsep Inti54~55### Image56~57Image adalah template read-only dengan instruksi untuk membuat container. Anggap saja sebagai snapshot dari aplikasi dan lingkungannya.58~59```bash60# Pull an image from Docker Hub61docker pull node:20-alpine62~63# List local images64docker images65~66# Remove an image67docker rmi node:20-alpine68```69~70### Container71~72Container adalah instance yang sedang berjalan dari sebuah image. Anda dapat membuat, memulai, menghentikan, dan menghapus container.73~74```bash75# Run a container76docker run -d --name my-app -p 3000:3000 node:20-alpine77~78# List running containers79docker ps80~81# List all containers (including stopped)82docker ps -a83~84# Stop a container85docker stop my-app86~87# Remove a container88docker rm my-app89~90# View logs91docker logs my-app92~93# Execute a command inside a running container94docker exec -it my-app sh95```96~97## Menulis Dockerfile98~99Dockerfile adalah file teks dengan instruksi untuk membangun image. Setiap instruksi membuat sebuah layer.100~101### Dockerfile Dasar untuk Aplikasi Node.js102~103```dockerfile104# Use an official Node.js runtime as base image105FROM node:20-alpine106~107# Set working directory108WORKDIR /app109~110# Copy package files first (better caching)111COPY package.json package-lock.json ./112~113# Install dependencies114RUN npm ci --only=production115~116# Copy application code117COPY . .118~119# Expose the port the app runs on120EXPOSE 3000121~122# Command to run the application123CMD ["node", "server.js"]124```125~126### Build dan Jalankan127~128```bash129# Build the image130docker build -t my-node-app .131~132# Run the container133docker run -d -p 3000:3000 my-node-app134~135# Visit http://localhost:3000136```137~138## Multi-Stage Build139~140Multi-stage build menjaga image produksi Anda tetap kecil dengan memisahkan lingkungan build dari runtime.141~142```dockerfile143# Stage 1: Build144FROM node:20-alpine AS builder145WORKDIR /app146COPY package.json package-lock.json ./147RUN npm ci148COPY . .149RUN npm run build150~151# Stage 2: Production152FROM node:20-alpine AS runner153WORKDIR /app154COPY --from=builder /app/dist ./dist155COPY --from=builder /app/node_modules ./node_modules156COPY --from=builder /app/package.json ./157EXPOSE 3000158CMD ["node", "dist/server.js"]159```160~161Ini menghasilkan image yang hanya berisi output terkompilasi dan dependensi produksi - tanpa kode sumber, tanpa dependensi pengembangan, tanpa alat build.162~163### Contoh Multi-Stage untuk Next.js164~165```dockerfile166FROM node:20-alpine AS deps167WORKDIR /app168COPY package.json package-lock.json ./169RUN npm ci170~171FROM node:20-alpine AS builder172WORKDIR /app173COPY --from=deps /app/node_modules ./node_modules174COPY . .175RUN npm run build176~177FROM node:20-alpine AS runner178WORKDIR /app179ENV NODE_ENV=production180COPY --from=builder /app/public ./public181COPY --from=builder /app/.next/standalone ./182COPY --from=builder /app/.next/static ./.next/static183EXPOSE 3000184CMD ["node", "server.js"]185```186~187## Volume: Data Persisten188~189Secara default, data di dalam container hilang ketika container dihapus. Volume menyelesaikan masalah ini.190~191```bash192# Create a named volume193docker volume create my-data194~195# Run with a volume196docker run -d -v my-data:/app/data my-app197~198# Bind mount (map host directory to container)199docker run -d -v $(pwd)/data:/app/data my-app200~201# List volumes202docker volume ls203```204~205## Jaringan206~207Docker membuat jaringan terisolasi agar container dapat berkomunikasi.208~209```bash210# Create a custom network211docker network create my-network212~213# Run containers on the same network214docker run -d --name api --network my-network my-api215docker run -d --name db --network my-network postgres:16216~217# Containers can reach each other by name218# From "api" container: postgres://db:5432219```220~221```mermaid222graph LR223 subgraph "my-network"224 API[api container\nport 3000] -- "db:5432" --> DB[db container\nport 5432]225 end226 User -- "localhost:3000" --> API227```228~229## Docker Compose230~231Docker Compose memungkinkan Anda mendefinisikan dan menjalankan aplikasi multi-container dengan satu file YAML.232~233### docker-compose.yml234~235```yaml236services:237 api:238 build: ./api239 ports:240 - "3000:3000"241 environment:242 - DATABASE_URL=postgres://user:pass@db:5432/mydb243 depends_on:244 - db245~246 db:247 image: postgres:16-alpine248 environment:249 - POSTGRES_USER=user250 - POSTGRES_PASSWORD=pass251 - POSTGRES_DB=mydb252 volumes:253 - pgdata:/var/lib/postgresql/data254 ports:255 - "5432:5432"256~257 redis:258 image: redis:7-alpine259 ports:260 - "6379:6379"261~262volumes:263 pgdata:264```265~266### Perintah267~268```bash269# Start all services270docker compose up -d271~272# View logs273docker compose logs -f274~275# Stop all services276docker compose down277~278# Rebuild and restart279docker compose up -d --build280~281# Scale a service282docker compose up -d --scale api=3283```284~285## .dockerignore286~287Seperti `.gitignore`, file ini mencegah file yang tidak diperlukan disalin ke dalam image.288~289```plaintext290node_modules291.git292.env293*.md294.next295dist296coverage297```298~299## Praktik Terbaik untuk Produksi300~301### 1. Gunakan Image Dasar yang Kecil302~303```dockerfile304# Bad: 1GB+305FROM node:20306~307# Good: ~180MB308FROM node:20-alpine309```310~311### 2. Jangan Jalankan sebagai Root312~313```dockerfile314FROM node:20-alpine315RUN addgroup -S app && adduser -S app -G app316USER app317WORKDIR /home/app318COPY --chown=app:app . .319```320~321### 3. Gunakan Tag Image yang Spesifik322~323```dockerfile324# Bad: can change unexpectedly325FROM node:latest326~327# Good: pinned version328FROM node:20.11-alpine3.19329```330~331### 4. Manfaatkan Cache Build332~333Urutkan instruksi Dockerfile dari yang paling jarang berubah ke yang paling sering berubah:334~335```dockerfile336FROM node:20-alpine337WORKDIR /app338~339# These change rarely - cached340COPY package.json package-lock.json ./341RUN npm ci --only=production342~343# This changes often - not cached344COPY . .345```346~347### 5. Health Check348~349```dockerfile350HEALTHCHECK --interval=30s --timeout=3s --retries=3 \351 CMD wget -qO- http://localhost:3000/health || exit 1352```353~354### 6. Gunakan Variabel Lingkungan355~356```dockerfile357ENV NODE_ENV=production358ENV PORT=3000359```360~361## Lembar Contekan Perintah Docker Umum362~363```bash364# Images365docker build -t name:tag . # Build image366docker images # List images367docker rmi image_name # Remove image368docker image prune # Remove unused images369~370# Containers371docker run -d -p 3000:3000 image # Run detached372docker ps # List running373docker stop container_name # Stop374docker rm container_name # Remove375docker logs -f container_name # Follow logs376docker exec -it container sh # Shell into container377~378# Compose379docker compose up -d # Start services380docker compose down # Stop services381docker compose logs -f # Follow all logs382docker compose ps # List services383~384# Cleanup385docker system prune -a # Remove everything unused386```387~388## Dari Docker ke Kubernetes389~390Docker menangani container individual. Ketika Anda perlu mengorkestrasi ratusan container di beberapa server, Anda memerlukan Kubernetes. Docker dan Kubernetes saling melengkapi:391~3921. **Docker**: membangun dan menjalankan container3932. **Kubernetes**: mengorkestrasi container dalam skala besar (penjadwalan, penskalaan, penyembuhan)394~395Jika Anda tertarik dengan langkah selanjutnya, lihat artikel saya tentang Pengantar Kubernetes.396~397## Kesimpulan398~399Docker adalah keterampilan fundamental bagi pengembang modern. Ini menghilangkan inkonsistensi lingkungan, menyederhanakan deployment, dan merupakan fondasi untuk orkestrasi container dengan Kubernetes. Mulai dengan Dockerfile sederhana, beralih ke Docker Compose untuk aplikasi multi-layanan, dan adopsi multi-stage build serta praktik terbaik keamanan seiring Anda berkembang.400~401Cara terbaik untuk belajar Docker adalah meng-containerize proyek yang sudah Anda kerjakan. Mulai hari ini.402~
NORMAL · docker-containers-complete-guide.md [readonly]402 lines · :q to close