Memuat halaman…
Memuat halaman…
Pelajari Docker dari dasar dengan contoh aplikasi Node.js: image, container, Dockerfile, volume, network, Docker Compose, environment variable, dan workflow development.
Feedback kamu membantu kami memperbaiki materi berikutnya.
Silakan masuk terlebih dahulu untuk ikut berdiskusi
Login SekarangDocker membantu developer menjalankan aplikasi dalam container. Container berisi runtime, dependency, konfigurasi dasar, dan proses aplikasi sehingga lingkungan development, testing, dan deployment dapat dibuat lebih konsisten.
Masalah klasik dalam pengembangan aplikasi adalah "jalan di laptop saya, tetapi error di laptop orang lain". Docker tidak menghapus semua masalah, tetapi membantu membuat lingkungan lebih eksplisit dan dapat direplikasi.
Setelah membaca tutorial ini, kamu diharapkan mampu:
Dockerfile untuk aplikasi Node.js sederhana.Image adalah blueprint. Container adalah proses yang berjalan dari image. Analogi sederhananya: image seperti resep, container seperti masakan yang dibuat dari resep tersebut.
| Istilah | Makna |
|---|---|
| Image | Paket berisi filesystem, runtime, dependency, dan instruksi menjalankan aplikasi. |
| Container | Instance berjalan dari image. |
| Dockerfile | File instruksi untuk membangun image. |
| Registry | Tempat menyimpan dan mengambil image, misalnya Docker Hub atau registry privat. |
Satu image dapat dipakai untuk membuat banyak container.
Misalkan kita punya aplikasi Express kecil.
{
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.18.0"
}
}File server.js:
const express = require("express");
const app = express();
const port = process.env.PORT || 3000;
app.get("/", (_req, res) => {
res.json({
message: "Aplikasi berjalan di Docker",
time: new Date().toISOString(),
});
});
app.listen(port, () => {
console.log(`Server berjalan di port ${port}`);
});Aplikasi ini membaca PORT dari environment variable. Pola ini penting karena port dan konfigurasi sering berbeda antara development dan production.
Dockerfile berikut membangun image untuk aplikasi Node.js.
Penjelasan singkat:
FROM menentukan base image.WORKDIR menentukan folder kerja di dalam container.COPY package*.json ./ menyalin manifest dependency lebih dulu agar cache build lebih efektif.RUN npm ci --omit=dev menginstal dependency production.COPY . . menyalin source code aplikasi.EXPOSE mendokumentasikan port yang dipakai aplikasi.CMD menentukan command default saat container berjalan.Jangan menyalin semua file lokal ke image. Buat .dockerignore.
File .env sebaiknya tidak masuk image. Secret diberikan saat runtime melalui environment variable atau secret manager.
Bangun image:
Jalankan container:
Format -p 3000:3000 berarti port 3000 di host diarahkan ke port 3000 di container.
Menjalankan dengan environment variable:
Melihat container berjalan:
Melihat log:
Masuk ke shell container:
Pada image Alpine, shell yang tersedia biasanya sh, bukan bash.
Container bersifat disposable. Jika container dihapus, perubahan file di dalam container bisa ikut hilang. Volume dipakai untuk data yang perlu bertahan, misalnya data database.
Contoh menjalankan PostgreSQL dengan volume:
Pada Windows PowerShell, multiline command bisa berbeda. Jika bingung, tulis command dalam satu baris terlebih dahulu.
Jika aplikasi dan database berjalan sebagai container terpisah, keduanya perlu berada di network yang sama.
Database:
Aplikasi:
Perhatikan host database memakai db, yaitu nama container database dalam network yang sama.
Docker Compose membuat definisi multi-container lebih rapi.
Jalankan:
Hentikan:
Jika ingin menghapus volume juga, gunakan opsi -v dengan hati-hati karena data database akan ikut terhapus.
Dockerfile production biasanya menginstal dependency production dan menjalankan build final. Untuk development, kita sering butuh hot reload dan bind mount.
Contoh Compose development:
Pola development perlu disesuaikan dengan framework yang digunakan. Tujuannya adalah feedback cepat, bukan image sekecil mungkin.
| Kesalahan | Dampak | Perbaikan |
|---|---|---|
Menyalin .env ke image | Secret bisa bocor | Masukkan .env ke .dockerignore. |
| Tidak memakai volume untuk database | Data hilang saat container dihapus | Gunakan named volume. |
Menganggap localhost selalu menunjuk host | Di container, localhost adalah container itu sendiri | Gunakan nama service/container di network. |
| Image terlalu besar | Build dan pull lambat | Gunakan base image sesuai kebutuhan dan .dockerignore. |
| Menghapus volume tanpa sadar | Data hilang | Baca command sebelum memakai docker compose down -v. |
Buat aplikasi Node.js kecil dengan endpoint berikut:
GET / mengembalikan pesan aplikasi berjalan.GET /health mengembalikan { "status": "ok" }.PORT.Kemudian:
Dockerfile..dockerignore.app dan db.Catat command yang kamu jalankan dan error yang muncul jika ada. Dokumentasi kecil seperti ini akan sangat membantu saat deployment.
Kuis
Apa perbedaan paling tepat antara image dan container?
Kuis
Mengapa database dalam container biasanya memakai volume?
Docker membantu membuat lingkungan aplikasi lebih konsisten. Pahami image, container, Dockerfile, .dockerignore, port, environment variable, volume, network, dan Compose. Untuk aplikasi produksi, jaga image tetap bersih dan jangan memasukkan secret. Untuk development, susun workflow yang memberi feedback cepat tanpa mengorbankan pemahaman terhadap container.
node_modules
npm-debug.log
.git
.env
.next
coverageFROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
ENV NODE_ENV=production
ENV PORT=3000
EXPOSE 3000
CMD ["npm", "start"]docker build -t node-docker-demo .docker run --rm -p 3000:3000 node-docker-demodocker run --rm -p 8080:8080 -e PORT=8080 node-docker-demodocker psdocker logs <container-id>docker exec -it <container-id> shdocker volume create pgdatadocker run --rm \
--name demo-postgres \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=app_db \
-v pgdata:/var/lib/postgresql/data \
-p 5432:5432 \
postgres:16docker network create app-networkdocker run -d \
--name db \
--network app-network \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=app_db \
postgres:16docker run -d \
--name app \
--network app-network \
-p 3000:3000 \
-e DATABASE_URL=postgresql://postgres:secret@db:5432/app_db \
node-docker-demoservices:
app:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://postgres:secret@db:5432/app_db
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
POSTGRES_DB: app_db
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:docker compose up --builddocker compose downservices:
app:
image: node:20-alpine
working_dir: /app
command: sh -c "npm install && npm run dev"
ports:
- "3000:3000"
volumes:
- .:/app
- node_modules:/app/node_modules
environment:
NODE_ENV: development
volumes:
node_modules: