Belajar Docker dari Nol sampai Aplikasi Berjalan
Halaman ini adalah modul bacaan lengkap (textbook) untuk menguasai Docker — alat yang mengemas aplikasi beserta lingkungannya ke dalam container yang sama di mana pun ia dijalankan. Kita belajar lewat studi kasus: menjalankan aplikasi web lengkap dengan database memakai Docker Compose.
1. Container & DockerKonsep sebelum perintah
Sebelum mengetik perintah, pahami dulu mengapa container ada dan apa bedanya image dengan container. Modul ini memberi peta mental yang membuat semua perintah Docker terasa logis.
1.1 Mengapa Perlu Container?
- Masalah klasik: "di laptop saya jalan, di server tidak." Aplikasi bergantung pada versi library, bahasa, dan sistem operasi tertentu.
- Solusi container: bungkus aplikasi + semua dependensinya + konfigurasi ke dalam satu paket yang sama persis di mana pun dijalankan.
- Ringan: container berbagi kernel dengan host — tidak perlu sistem operasi utuh seperti mesin virtual (VM).
- Isolasi: setiap container punya filesystem, proses, dan network sendiri — aplikasi tidak saling merusak.
- Reproduksibel: definisi container ditulis sebagai teks (Dockerfile), bisa di-versioning di git.
1.2 Image vs Container
| Image | Container |
|---|---|
| Biru/cetak biru — template yang tidak berubah | Contoh berjalan dari image |
| Tersusun dari layer (lapisan) yang efisien | Bisa dibuat, dijalankan, dihentikan, dihapus |
docker build / docker pull | docker run / docker start / docker stop |
| Berbagi layer antar image lain | Data di dalam container hilang saat dihapus (pakai volume) |
1.3 Instalasi & Perintah Dasar
Instal Docker Engine (atau Docker Desktop di Windows/macOS). Verifikasi:
docker version
docker info
Perintah dasar yang wajib dikuasai pertama:
docker run -it ubuntu bash— jalankan container dari imageubuntulalu masuk ke shell.docker ps— daftar container yang berjalan;docker ps -atermasuk yang berhenti.docker images— daftar image yang tersimpan di mesin.docker stop <nama>dandocker rm <nama>— hentikan dan hapus container.docker pull <image>— unduh image dari registry (default: Docker Hub).
docker rm -f $(docker ps -aq) menghapus semua container — sangat berguna di mesin lab, sangat berbahaya di server produksi.Lab 1 — Jalankan container pertama
docker run --rm -it hello-world— image uji kecil yang mencetak pesan.docker run --rm -it ubuntu bash— masuk ke Ubuntu; cobacat /etc/os-release; keluar denganexit.docker ps -a— lihat riwayat container.--rmotomatis membersihkan setelah berhenti.
2. Image & DockerfileMembangun image sendiri
Memakai image siap pakai itu mudah; membuat image sendiri adalah keterampilan inti. Modul ini mengajarkan cara menulis Dockerfile yang benar dan membangun image aplikasi sendiri.
2.1 Menarik & Mengelola Image
docker pull nginx:alpine— tarik image dengan tag tertentu. Tag = versi;alpine= varian kecil/ringan.docker images— lihat ukuran; image yang tidak dipakai menghabiskan disk.docker rmi <image>— hapus image.- Lapisan (layer): image tersusun dari layer yang dibagi antar image — ini yang membuat pengunduhan efisien.
node:20-alpine) di produksi, bukan latest — latest bisa berubah diam-diam dan merusak aplikasi.2.2 Menulis Dockerfile
Dockerfile adalah resep langkah-demi-langkah membangun image. Contoh aplikasi Node.js sederhana:
# 1. Dasar: image node versi 20 varian alpine
FROM node:20-alpine
# 2. Direktori kerja di dalam container
WORKDIR /app
# 3. Salin file dependensi dulu (manfaatkan cache layer)
COPY package*.json ./
RUN npm install
# 4. Salin kode aplikasi
COPY . .
# 5. Ekspos port
EXPOSE 3000
# 6. Perintah saat container berjalan
CMD ["node", "index.js"]
- FROM — image dasar (selalu wajib, baris pertama).
- WORKDIR — direktori kerja; perintah berikut dijalankan dari sana.
- COPY — menyalin file dari host ke image.
- RUN — menjalankan perintah saat membangun image (mis. instalasi).
- EXPOSE — dokumentasi port; bukan membuka port (itu urusan
-psaatrun). - CMD — perintah default saat container dijalankan.
package.json tidak berubah, Docker tidak perlu mengulang npm install — mempercepat pembangunan ulang drastis.2.3 Membangun & Menjalankan
# Bangun image dengan nama 'myapp' dan tag 'v1'
docker build -t myapp:v1 .
# Jalankan container dari image tersebut
# -p 3000:3000 = petakan port host 3000 ke port 3000 container
docker run -d --name app1 -p 3000:3000 myapp:v1
# Lihat log container
docker logs app1
-d— detach (berjalan di latar belakang).--name— beri nama agar mudah dirujuk.docker exec -it app1 sh— masuk ke dalam container yang sedang berjalan.docker logs -f app1— ikuti log secara real-time.
Lab 2 — Image sendiri
- Buat folder
lab-docker, isiindex.js(server HTTP kecil) danpackage.json. - Tulis Dockerfile seperti contoh di atas.
- Bangun dengan
docker build -t lab:v1 .. - Jalankan
docker run -d --name lab -p 3000:3000 lab:v1, lalu bukahttp://localhost:3000. - Ubah kode, bangun ulang, perhatikan kecepatan build berkat cache layer.
3. Volume & NetworkAgar data tahan lama dan container saling bicara
Container itu sementara — data di dalamnya hilang saat dihapus. Volume dan network adalah dua mekanisme yang membuat container berguna dalam dunia nyata: data tahan lama, dan aplikasi terhubung satu sama lain.
3.1 Volume & Bind Mount
| Jenis | Dikelola oleh | Kegunaan |
|---|---|---|
| Named volume | Docker (di bawah /var/lib/docker/volumes) | Data database, file upload — yang paling disarankan |
| Bind mount | Anda (folder host langsung) | Development (kode di host langsung terlihat di container) |
# Named volume
docker volume create data-db
docker run -d --name db -v data-db:/var/lib/postgresql/data postgres:16-alpine
# Bind mount untuk development
docker run -d --name app -v "$PWD":/app myapp:v1
3.2 Network Container
- Setiap container bisa punya IP sendiri; tapi IP berubah tiap container dibuat ulang.
- Solusinya: network Docker dengan DNS internal — container dipanggil lewat nama, bukan IP.
# Buat network
docker network create mynet
# Jalankan dua container di network yang sama
docker run -d --name db --network mynet postgres:16-alpine
docker run -d --name app --network mynet -p 3000:3000 myapp:v1
# Dari dalam app, database dapat diakses sebagai 'db' (bukan IP)
db, bukan IP — ini membuat konfigurasi stabil meski container dibuat ulang.3.3 Variabel Lingkungan
- Konfigurasi (kredensial DB, mode aplikasi) dilewatkan lewat environment variable, bukan di-hardcode di kode.
- Pakai
-esaat run, atauenv_filedi Compose.
docker run -d --name app --network mynet \
-e DB_HOST=db -e DB_USER=app -e DB_PASS=rahasia \
myapp:v1
Lab 3 — Volume & network
- Buat network
labnetdan volumelabdb. - Jalankan Postgres dengan volume dan di network itu.
- Jalankan aplikasi dari Lab 2 di network yang sama dengan
-e DB_HOST=.... - Hapus container database (
docker rm -f db), buat ulang, dan buktikan data tetap ada karena volume.
4. Docker Compose & PraktikBanyak layanan, satu perintah
Aplikasi nyata terdiri dari banyak layanan: web, database, cache, worker. Docker Compose mendefinisikan semuanya dalam satu file YAML dan menjalankannya dengan satu perintah.
4.1 Docker Compose
Compose menggantikan rangkaian panjang docker run dengan satu file compose.yaml:
services:
app:
build: .
ports:
- "3000:3000"
environment:
- DB_HOST=db
depends_on:
- db
db:
image: postgres:16-alpine
environment:
- POSTGRES_USER=app
- POSTGRES_PASSWORD=rahasia
volumes:
- dbdata:/var/lib/postgresql/data
volumes:
dbdata:
services— daftar layanan (masing-masing seperti satudocker run).build— bangun dari Dockerfile;image— pakai image siap pakai.depends_on— urutan mulai;volumes— deklarasi named volume.- Perintah:
docker compose up -d,docker compose logs -f,docker compose down.
db sebagai host. Satu file, satu perintah, lingkungan pengembangan dan produksi yang konsisten.4.2 Studi Kasus: App + DB
- Buat
compose.yamldengan dua layanan: aplikasi Node dan Postgres. - Aplikasi membaca
DB_HOST=db— tanpa IP, hanya nama layanan. - Jalankan
docker compose up -d— kedua layanan mulai bersamaan. - Periksa dengan
docker compose psdandocker compose logs -f app.
git pull, lalu docker compose up -d --build. Rollback semudah men-downgrade tag image dan up -d lagi.4.3 Tips Deploy & Keamanan
- Jangan jalankan container sebagai root — gunakan
USERnon-root di Dockerfile (mis.nodeyang sudah tersedia di image Node). - Image kecil = serangan lebih sempit dan transfer lebih cepat — pakai varian
alpinebila memungkinkan. - Pin tag, jangan
latest; audit image dengandocker scanatau tool sejenis. - Backup volume database secara rutin — volume tidak otomatis dibackup.
- Batasi paparan port: hanya expose port yang benar-benar perlu (mis. 3000, jangan 5432 ke publik).
Lab 4 — Compose penuh
- Susun proyek: kode aplikasi + Dockerfile +
compose.yaml(app + db). - Jalankan
docker compose up -d, buka aplikasi, pastikan terhubung ke database. - Simulasikan down:
docker compose down, laluup -d— data harus tetap ada. - Tulis satu Dockerfile dengan
USER nodeuntuk aplikasi.
Cek Pemahaman — Docker
- Apa beda image dan container?
Lihat jawaban
Image adalah template/cetak biru yang tidak berubah; container adalah instance berjalan dari image yang bisa dibuat, dihentikan, dan dihapus.
- Mengapa data database harus disimpan di volume?
Lihat jawaban
Karena data di dalam filesystem container hilang saat container dihapus; volume menyimpan data di luar siklus hidup container.
- Bagaimana container saling memanggil tanpa bergantung IP?
Lihat jawaban
Lewat network Docker dan DNS internal: nama container dipakai sebagai nama host (mis. aplikasi memanggil
db). - Mengapa urutan COPY/instalasi di Dockerfile penting?
Lihat jawaban
Memanfaatkan cache layer: jika dependensi tidak berubah, Docker mengulang instalasi — build menjadi jauh lebih cepat.
- Apa fungsi Docker Compose?
Lihat jawaban
Mendefinisikan beberapa layanan (app, db, dsb.) dalam satu file YAML dan menjalankannya dengan satu perintah
docker compose up. - Mengapa tidak menaruh kredensial di Dockerfile?
Lihat jawaban
Karena Dockerfile (dan image) bisa dilihat siapa saja yang memegangnya — gunakan environment variable dan pengelolaan rahasia.
Drill DockerLatihan cepat ingatan
| Perintah | Fungsi |
|---|---|
docker build -t nama . | Bangun image dari Dockerfile di folder saat ini |
docker run -d -p 3000:3000 nama | Jalankan container di latar belakang, petakan port |
docker ps -a | Daftar semua container (termasuk yang berhenti) |
docker exec -it nama sh | Masuk ke shell container yang berjalan |
docker logs -f nama | Ikuti log container |
docker compose up -d | Jalankan semua layanan dari compose.yaml |
docker compose down | Hentikan dan hapus layanan (volume tetap) |
docker system prune | Bersihkan image/container yang tidak dipakai |
Cheat Sheet DockerReferensi cepat
| Kebutuhan | Perintah |
|---|---|
| Image dasar | FROM node:20-alpine |
| Direktori kerja | WORKDIR /app |
| Salin file | COPY . . |
| Instalasi | RUN npm install |
| Perintah start | CMD ["node", "index.js"] |
| Volume | -v nama:/path |
| Network | --network nama |
| Variabel lingkungan | -e KEY=value |