Skip to content

Final Project ​

Sampai sini kamu sudah mengenal seluruh materi inti Docker Essentials: menjalankan container, membuat image, menyimpan data, mengatur network dan environment variable, sampai Docker Compose. Sekarang saatnya membuktikan bahwa ilmu itu benar-benar nempel dengan mengerjakan project di bawah.

Cara mengerjakan:

  • Tidak ada langkah langkah. Kamu yang merancang dan mengetik command-nya sendiri, mulai dari membaca study case dan target akhir.
  • Setiap project punya checklist verifikasi. Kamu berhasil kalau semua item checklist terpenuhi, bukan kalau command-mu sama dengan punya orang lain.
  • Kalau macet, buka clue yang tersedia. Clue sengaja dibertahap, coba yang paling atas dulu.
  • Semua project hanya memakai materi dari lesson 1 sampai 9. Link lesson terkait selalu dicantumkan.

Kerjakan berurutan, karena project berikutnya memakai hasil project sebelumnya.

Project 1: Database lokal untuk development ​

Level: dasar · Materi: Bekerja dengan container, Bekerja dengan image, Docker Volume, Environment Variable

Study case: tim frontend membutuhkan PostgreSQL untuk local development. Tidak ada yang mau install PostgreSQL langsung di laptop karena versinya suka bentrok dengan project lain. Kamu diminta menyiapkan container database yang bisa dipakai seluruh tim, dengan dua syarat dari tech lead: password database tidak boleh ditulis hardcoded di script, dan data harus tetap aman walaupun container-nya dihapus.

Target akhir:

  • Container PostgreSQL berjalan di background dengan nama dev-db.
  • Password dan nama database diberikan lewat environment variable.
  • Port 5432 di container di-map ke port 5433 di laptop, supaya tidak bentrok kalau nanti ada database lain.
  • Data tersimpan di named volume, bukan di dalam container.

Checklist verifikasi:

Clue 1

Image postgres:16 membaca environment variable POSTGRES_PASSWORD dan POSTGRES_DB saat first start. Cara memberikannya ada di lesson Environment Variable.

Clue 2

Untuk syarat data aman, jalankan container dengan option -v <nama-volume>:/var/lib/postgresql/data. Ini pola named volume yang dibahas di lesson Docker Volume. Cek juga daftar volume milikmu dengan perintah yang ada di lesson itu.

Clue 3

Untuk mengisi dan memeriksa data, jalankan psql di dalam container dengan docker exec, formatnya docker exec -it dev-db psql -U postgres -d <nama-database>. Option -it dan cara kerja docker exec dibahas di lesson Bekerja dengan container.

Project 2: Dockerize sebuah aplikasi ​

Level: menengah · Materi: Bekerja dengan image, Membuat Docker Image sendiri, Environment Variable

Study case: tim kamu punya service kecil bernama status-api, ditulis dengan Node.js. Masalahnya, setiap anggota tim baru harus install Node versi yang tepat sebelum bisa menjalankannya. Kamu diminta mengemas app ini menjadi image, sehingga siapa pun cukup menjalankan satu command tanpa install apa pun.

Source code-nya hanya dua file. Buat folder baru, lalu simpan kedua file ini di dalamnya.

server.js:

js
const http = require("http");

const port = process.env.PORT || 3000;
const message = process.env.MESSAGE || "Hello dari container";

const server = http.createServer((req, res) => {
  res.end(`${message} (port ${port})`);
});

server.listen(port, () => {
  console.log(`status-api berjalan di port ${port}`);
});

package.json:

json
{
  "name": "status-api",
  "scripts": {
    "start": "node server.js"
  }
}

App ini membaca dua environment variable: PORT (port tempat app mendengarkan, default 3000) dan MESSAGE (teks yang dikembalikan, default Hello dari container). Ini disengaja, supaya konfigurasi container-nya bisa kamu buktikan sendiri.

Target akhir:

  • Sebuah Dockerfile yang menyalin kedua file itu ke dalam image dan menjalankan app dengan npm start.
  • Image berhasil di-build dengan nama status-api dan tag 1.0.
  • Container berjalan di background, port di-map ke laptop, dan pesan yang tampil di browser berasal dari environment variable yang kamu berikan saat docker run, bukan dari default.

Checklist verifikasi:

Clue 1

Base image node:22-alpine dipakai di contoh lesson Membuat Docker Image sendiri, lengkap dengan pola WORKDIR, COPY, dan CMD. Kamu tinggal menyesuaikannya untuk dua file ini.

Clue 2

Port di dalam container tetap 3000 pada kedua container. Yang berbeda hanya port di laptop. Ingat pola -p <port-laptop>:<port-container> dan ingat bahwa app membaca PORT kalau kamu ingin mengubah port di dalam container juga.

Clue 3

Jangan lupa .dockerignore. Tidak ada node_modules di project ini, tetapi file .env atau folder Git bisa ikut tersalin ke image lewat COPY . . kalau ada. Baca lagi bagian .dockerignore di lesson Membuat Docker Image sendiri.

Project 3: Stack app + database dengan Compose ​

Level: mahir · Materi: Docker Volume, Docker Network, Environment Variable, Docker Compose

Study case: status-api dari Project 2 naik kelas. Product manager ingin setiap kunjungan ke halaman utama tercatat ke database, sehingga jumlah visit bisa dilihat kapan saja. Sekarang stack-nya jadi dua service: api (image buatan sendiri) dan db (PostgreSQL). Kamu diminta menjalankan keduanya sebagai satu stack dengan Docker Compose, dengan konfigurasi yang tersimpan di repo, bukan sekadar rangkaian command di terminal.

Simpan dua file berikut di folder yang sama dengan Dockerfile dari Project 2, lalu update keduanya.

server.js (app sekarang mencatat setiap kunjungan ke PostgreSQL):

js
const http = require("http");
const { Pool } = require("pg");

const pool = new Pool({ connectionString: process.env.DATABASE_URL });

const server = http.createServer(async (req, res) => {
  await pool.query(
    "CREATE TABLE IF NOT EXISTS visits (id SERIAL PRIMARY KEY, at TIMESTAMPTZ DEFAULT now())"
  );
  await pool.query("INSERT INTO visits (at) VALUES (now())");
  const result = await pool.query("SELECT count(*) AS total FROM visits");
  res.end(`Total visit: ${result.rows[0].total}`);
});

server.listen(process.env.PORT || 3000, () => {
  console.log(`status-api berjalan di port ${process.env.PORT || 3000}`);
});

package.json (sekarang butuh dependency pg, driver PostgreSQL untuk Node.js):

json
{
  "name": "status-api",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "pg": "8.12.0"
  }
}

App ini membaca environment variable DATABASE_URL, yaitu connection string menuju PostgreSQL. Formatnya: postgres://<user>:<password>@<host>:<port>/<nama-database>.

Target akhir:

  • Sebuah compose.yaml dengan dua service: api yang di-build dari Dockerfile milikmu, dan db yang memakai image postgres:16.
  • Service api connect ke PostgreSQL lewat hostname nama service, bukan localhost.
  • Password PostgreSQL dibaca dari file .env, tidak ditulis langsung di compose.yaml.
  • Data visit tersimpan di named volume, sehingga tetap ada setelah stack di-down dan di-up lagi.

Checklist verifikasi:

Clue 1

Field build di compose.yaml membuat Compose memakai Dockerfile milikmu, dan depends_on mengatur service db dijalankan lebih dulu. Keduanya ada di lesson Docker Compose. Ingat catatan lesson itu: depends_on hanya mengatur urutan start. Kalau halaman pertama langsung error, itu app mencoba connect sebelum PostgreSQL siap. Tunggu sebentar lalu refresh.

Clue 2

Untuk DATABASE_URL, ganti bagian host dengan nama service db, contohnya postgres://postgres:${POSTGRES_PASSWORD}@db:5432/app. Mekanisme ${...} dari file .env juga dibahas di lesson Docker Compose.

Clue 3

Untuk volume database, lihat lagi service db pada contoh Compose di lesson Docker Compose: named volume dipasang ke /var/lib/postgresql/data, dan daftar volume-nya didaftarkan di key volumes paling bawah file. Setelah itu, down tanpa option -v tidak akan menghapus data kamu.


Selesai semua checklist? Kamu sudah membuktikan bisa memakai Docker untuk pekerjaan nyata: menjalankan service dengan konfigurasi yang benar, mengemas app menjadi image, dan merangkai beberapa service dengan Compose. Selamat 🥳

Kalau masih ada item checklist yang gagal, jangan langsung lihat jawaban orang lain. Justru dari situ yang paling banyak belajarnya: baca docker logs, cek docker compose ps, dan bandingkan dengan lesson terkait.