← Semua pembelajaran / Python untuk AI Engineer
Fase 6 · Data, Testing, Deploy

Docker — Python language guide

Konsep Docker yang perlu kamu pahami: image, layer, container, volume, network, dan compose.

Sumber asli docs.docker.com Resmi Rangkuman ~5 menit baca

Intisari

  • Image = cetakan (statis). Container = instance yang berjalan.
  • Tiap instruksi Dockerfile membuat layer; layer di-cache dan digunakan ulang selama input-nya tidak berubah.
  • Data di dalam container hilang saat container dihapus. Yang harus bertahan disimpan di volume.
  • Compose menjalankan beberapa layanan sekaligus; layanan saling memanggil lewat namanya.
  • Kesalahan paling umum: bind ke 127.0.0.1, dan PYTHONUNBUFFERED yang belum diatur.

Kosakata

IstilahArtinya
ImagePaket read-only berisi kode + dependency + OS minimal
ContainerImage yang sedang berjalan sebagai proses terisolasi
LayerSatu instruksi Dockerfile = satu layer; di-cache dan dipakai bersama antar image
VolumePenyimpanan yang bertahan setelah container dihapus
NetworkJaringan virtual tempat container saling menemukan lewat nama
RegistryTempat menyimpan dan berbagi image (Docker Hub, ECR, GHCR)

Layer dan cache

FROM python:3.13-slim        ← layer 1
WORKDIR /app                  ← layer 2
COPY pyproject.toml ./        ← layer 3
RUN uv sync --frozen          ← layer 4  (mahal)
COPY src/ ./src/              ← layer 5
CMD ["uvicorn", "..."]        ← layer 6

Aturannya: begitu satu layer berubah, semua layer sesudahnya dibangun ulang. Karena itu urutkan dari yang paling jarang berubah ke yang paling sering. Kode aplikasi selalu di bawah; dependency selalu di atas.

Instruksi Dockerfile

InstruksiFungsinya
FROMImage dasar
WORKDIRDirektori kerja (dibuat kalau belum ada)
COPYSalin dari konteks build ke image
RUNJalankan perintah saat build
ENVEnvironment variable (build dan runtime)
ARGVariabel hanya saat build
EXPOSEDokumentasi port (tidak benar-benar membuka)
USERGanti user
HEALTHCHECKCara Docker menentukan container sehat
CMDPerintah default (bisa ditimpa)
ENTRYPOINTPerintah yang selalu jalan

Memilih image dasar

TagUkuranCatatan
python:3.13~1 GBLengkap; terlalu besar untuk production
python:3.13-slim~150 MBPilihan default yang tepat
python:3.13-alpine~50 MBmusl libc — banyak wheel tidak jalan, harus compile

Hindari Alpine untuk aplikasi Python. Ukurannya memang menggoda, tapi Alpine memakai musl libc alih-alih glibc — sehingga wheel biner (numpy, pandas, cryptography) tidak cocok dan harus dikompilasi dari sumber. Build-nya jadi berkali-kali lipat lebih lama, dan kadang hasilnya justru lebih besar.

Perintah sehari-hari

docker build -t myapp:latest .
docker run --rm -p 8000:8000 --env-file .env myapp:latest
docker run --rm -it myapp:latest bash        # masuk ke shell untuk debug

docker ps                                     # container yang jalan
docker logs -f <id>                           # ikuti log
docker exec -it <id> bash                     # masuk ke container yang jalan
docker stop <id>

docker images
docker system prune -a                        # bersihkan yang tidak terpakai

Volume

# Named volume — dikelola Docker, untuk data persisten
docker run -v chroma-data:/chroma/chroma chromadb/chroma

# Bind mount — folder host, untuk development
docker run -v $(pwd)/src:/app/src myapp

Tanpa volume, semua data hilang saat container dihapus. Vector store, database, dan file yang diunggah harus disimpan di named volume. Bind mount cocok untuk development (kode di host langsung terlihat di container), tapi jangan dipakai di production.

Compose

services:
  api:
    build: .
    ports:
      - "8000:8000"
    env_file: [.env]
    depends_on:
      chroma:
        condition: service_healthy
    restart: unless-stopped

  chroma:
    image: chromadb/chroma:latest
    volumes:
      - chroma-data:/chroma/chroma
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/api/v2/heartbeat"]
      interval: 10s
      retries: 5

volumes:
  chroma-data:
docker compose up -d
docker compose logs -f api
docker compose down            # hentikan
docker compose down -v         # hentikan DAN hapus volume (hati-hati)

Layanan saling memanggil lewat nama

CHROMA_URL = "http://chroma:8000"     # 'chroma' = nama layanan di compose

Docker menyediakan DNS internal. Dari dalam container api, hostname chroma otomatis menunjuk ke container Chroma. Jangan pakai localhost — di dalam container, itu menunjuk ke container itu sendiri.

Kesalahan yang paling sering

GejalaPenyebabPerbaikan
Tidak bisa diakses dari hostBind ke 127.0.0.1--host 0.0.0.0
Log tidak munculOutput di-bufferENV PYTHONUNBUFFERED=1
Image sangat besar.venv ikut tersalin, atau tidak multi-stage.dockerignore + multi-stage
Build selalu lambatCOPY . . sebelum installSalin lockfile dulu
Data hilang setelah restartTidak ada volumeTambahkan named volume
Connection refused antar layananPakai localhostPakai nama layanan
Layanan start sebelum dependensinya siapHanya depends_onTambahkan condition: service_healthy

Debugging

docker run --rm -it myapp bash                  # jelajahi image
docker exec -it <id> bash                       # masuk ke container hidup
docker inspect <id>                             # konfigurasi lengkap
docker stats                                    # pemakaian CPU/memori
docker compose logs --tail=100 -f api

# Kalau container langsung mati
docker run --rm myapp                            # lihat pesan errornya
docker logs <id>

Checkpoint Fase 6

Target: siapa pun bisa menjalankan proyekmu dengan satu perintah.

git clone https://github.com/kamu/proyek
cd proyek
cp .env.example .env      # isi ANTHROPIC_API_KEY
docker compose up

Kalau itu berhasil di mesin orang lain tanpa penjelasan tambahan, checkpoint-nya tercapai.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.