Docker

1. Pengenalan Docker

image.png

1. Apa Itu Docker?

Docker adalah alat untuk membuat dan menjalankan "container", yaitu kotak kecil yang berisi aplikasi lengkap dan bisa berjalan di komputer mana pun.

Bayangkan kamu membuat mie instan:

Istilah Penting

2. Kenapa Harus Pakai Docker?


3. Perbedaan Docker dan Virtual Machine

Sebelum ada Docker, biasanya aplikasi diinstal langsung di sistem operasi (OS). Cara ini punya banyak kekurangan, seperti:

Dengan Docker, semua konfigurasi, library, dan environment dikemas ke dalam 1 box/container yang bisa langsung dijalankan di mana saja.

Perbandingan :

image.png

Fitur Instal Langsung di OS Virtual Machine (VM) Docker Container
Kebutuhan OS Langsung pakai OS utama Perlu OS lengkap di atas host Share OS kernel dengan host
Isolasi Aplikasi Minim Sangat terisolasi Cukup terisolasi
Setup Ribet (manual install) Lewat template atau ISO Lewat Dockerfile + image
Konflik antar aplikasi Bisa terjadi Tidak (karena OS terpisah) Tidak (pakai container)
Ukuran Ringan Berat (GB-an) Ringan (puluhan MB – ratusan MB)
Kecepatan boot/start Instan Lambat (menit) Cepat (detik)
Portabilitas Sulit pindah Bisa, tapi besar & lambat Sangat portabel & cepat
Cocok untuk DevOps & CI/CD Tidak cocok Kurang fleksibel Sangat cocok

Bayangkan kamu ingin install aplikasi Laravel + MySQL:

Semua jalan di container masing-masing.


4. Cara Kerja Docker

  1. Kita ambil image dari Docker Hub (misalnya nginx)
  2. Docker menjalankan image jadi container
  3. Kita bisa akses aplikasi dari browser atau terminal
[ Docker Image ] --> [ Docker Container ] --> [ Aplikasi Jalan ]

5. Instalasi Docker (Ubuntu/Linux)

sudo apt update
sudo apt install docker.io -y
sudo systemctl enable docker
sudo systemctl start docker

6. Perintah Dasar Docker

Perintah Fungsi
docker --version Cek versi Docker
docker run hello-world Jalankan contoh pertama
docker ps Lihat container yang aktif
docker images Lihat daftar image
docker pull nginx Download image dari Docker Hub
docker run -d -p 8080:80 nginx Jalankan nginx di port 8080
docker stop <id> Hentikan container
docker rm <id> Hapus container
docker rmi <id> Hapus image

7. Contoh Praktik: Web + Database dengan Docker Compose

Buat file docker-compose.yml:

version: '3'
services:
  web:
    image: nginx
    ports:
      - "8080:80"
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: rahasia

Jalankan:

docker-compose up -d

Akses localhost:8080 di browser.


8. Kesimpulan

Docker adalah alat keren yang membantu kita menjalankan aplikasi dengan cara cepat, ringan, dan konsisten. Cocok untuk yang ingin masuk ke dunia DevOps, sistem administrator, dan cloud.

Docker tidak hanya soal performa, tapi soal cara kerja modern yang membuat aplikasi lebih fleksibel, konsisten, dan mudah dipindah.
Dengan Docker, kamu tidak lagi "install aplikasi" — kamu menjalankan aplikasi siap pakai, lengkap dengan semua konfigurasinya.


Sumber Belajar Lanjut


2. Instal Docker

image.png

Instal Docker dengan manual command Ubuntu 22.04 LTS

1. Remove docker package untuk memastikan tidak ada bekas instalasi lama supaya clean instal.
sudo apt-get remove docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc -y
2. Update repository agar mendapatkan package terbaru
sudo apt-get update -y
3. Tambahkan repository untuk docker
4. Menginstal Docker
5. Cek status instalasi docker
sudo systemctl status docker
sudo docker --version
sudo docker ps
6. Kalau ingin Docker bisa dijalankan tanpa sudo, tambahkan user ke grup docker:

Instal Docker dengan bash script di Ubuntu 22.04 LTS

1. Buat file instal-docker.sh
vim instal-docker.sh

Setelah masuk vim, tekan i untuk edit.

Isi script berikut :

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do apt-get remove $pkg; done
apt-get update
apt-get install ca-certificates curl
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update -y
apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
2. Save dengan klik esc, tekan titik dua : , kemudian wq!, enter.
:wq!
3. Set permissions file instal-docker.sh supaya executable
chmod +x instal-docker.sh
4. Jalankan bash script instal-docker.sh
sudo bash instal-docker.sh

Tunggu sampai proses instalasi selesai

5. Cek status instalasi docker
sudo systemctl status docker
sudo docker --version
sudo docker ps
6. Kalau ingin Docker bisa dijalankan tanpa sudo, tambahkan user ke grup docker:

3. Docker Command

image.png

Perintah Docker Dasar + Use Case

Perintah Fungsi Utama Penjelasan Mudah Contoh Use Case
docker run Menjalankan container Seperti menyalakan mesin dari cetakan (image) Menjalankan web server seperti Nginx, Node.js
docker ps -a Melihat semua container Menampilkan semua container, baik aktif maupun mati Cek container yang gagal jalan atau sudah stop
docker exec Masuk ke dalam container Seperti masuk ke terminal dari komputer virtual (container) Debug aplikasi yang error dari dalam
docker logs Melihat log container Melihat output/error yang terjadi dalam aplikasi Melihat kenapa web app gagal jalan
docker build Membuat image dari Dockerfile Compile semua konfigurasi dan source code jadi image Build web app dari source code lokal
docker images / docker rmi Melihat & hapus image Lihat semua image lokal dan hapus yang tidak dipakai Bersih-bersih image lama
docker stop / docker rm Hentikan dan hapus container Stop container yang sedang berjalan, lalu hapus Bersih-bersih container yang tidak aktif
docker volume Kelola volume (penyimpanan) Simpan data yang tetap ada walau container dihapus Menyimpan data MySQL agar tidak hilang
docker network Kelola jaringan antar container Hubungkan container seperti jaringan LAN Web app bisa akses database di container lain
docker compose Jalankan beberapa container sekaligus Jalankan 1 set aplikasi (web + db + cache) dalam 1 perintah Deploy project: React + Node.js + MongoDB
1. Jalankan Nginx (web server)

docker run -d --name web-nginx -p 8080:80 nginx

Menjalankan Nginx dan membuka port 8080 di komputer lokal.


2. Lihat semua container (aktif dan tidak aktif)
docker ps -a

Untuk mengecek container mana yang berjalan atau sudah berhenti.


3. Masuk ke dalam container
docker exec -it web-nginx bash

Seperti buka terminal di dalam container Nginx.


4. Lihat log container (misalnya container Node.js)
docker logs web-node

Lihat error atau output dari aplikasi kita.


5. Build image dari Dockerfile
docker build -t myapp:v1 .

Bangun image bernama myapp:v1 dari Dockerfile di folder saat ini.


6. Lihat dan hapus image
docker images docker rmi myapp:v1

Cek semua image yang ada lalu hapus image yang tidak dipakai.


7. Stop dan hapus container
docker stop web-nginx docker rm web-nginx

Matikan dan hapus container Nginx.


8. Gunakan volume untuk database
docker volume create dbdata docker run -d --name mysql-db -e MYSQL_ROOT_PASSWORD=admin -v dbdata:/var/lib/mysql mysql

Volume dbdata menyimpan data MySQL agar tidak hilang walau container dihapus.


9. Buat jaringan khusus
docker network create webnet

Container yang dibuat di jaringan ini bisa saling komunikasi seperti dalam LAN.


10. Jalankan semua service dengan docker-compose

Isi file docker-compose.yml:

version: '3'
services:
  web:
    image: nginx
    ports:
      - "8080:80"
  db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: admin

Jalankan:

docker-compose up -d 

Menjalankan Nginx dan MySQL sekaligus dengan satu perintah.

Perintah Maintenance Docker

Perintah Fungsi Penjelasan Mudah
docker system df Lihat pemakaian storage Seperti df di Linux, tapi khusus Docker
docker system prune -a Hapus semua yang tidak dipakai (container/image/volume) Bersih-bersih total
docker image prune / docker container prune Hapus image/container tidak terpakai Pilih bersih-bersih bagian tertentu
docker inspect Lihat detail konfigurasi container/image Untuk troubleshooting atau melihat pengaturan dalamnya
docker stats Lihat penggunaan CPU/RAM per container Pantau resource tiap container
docker cp Copy file ke/dari container Untuk backup log, atau copy konfigurasi
docker login/push/pull Akses Docker registry Upload/download image ke registry (Docker Hub, GitLab, dsb)

Contoh Maintenance

1. Lihat disk usage Docker
docker system df
2. Hapus semua yang tidak digunakan
docker system prune -a
3. Copy file dari container ke host
docker cp web-nginx:/etc/nginx/nginx.conf ./nginx.conf
4. Lihat penggunaan CPU/RAM container
docker stats


🐳 Docker Cheatsheet

Perintah Dasar Docker
Perintah Fungsi Contoh
docker run Jalankan container docker run -d -p 8080:80 nginx
docker ps Lihat container aktif docker ps
docker ps -a Lihat semua container docker ps -a
docker exec Masuk ke dalam container docker exec -it nama_container bash
docker logs Lihat log container docker logs nama_container
docker stop Hentikan container docker stop nama_container
docker rm Hapus container docker rm nama_container
docker images Lihat semua image docker images
docker rmi Hapus image docker rmi nama_image
docker build Build image dari Dockerfile docker build -t nama_image:v1 .

Volume & Data Persistence
Perintah Fungsi Contoh
docker volume create Buat volume baru docker volume create dataweb
-v volume:/path Mount volume ke container -v dataweb:/usr/share/nginx/html
docker volume ls Lihat semua volume docker volume ls
docker volume rm Hapus volume docker volume rm nama_volume

Network antar Container
Perintah Fungsi Contoh
docker network create Buat network baru docker network create mynet
--network mynet Hubungkan container ke network docker run --network mynet ...
docker network ls Lihat daftar network docker network ls
docker network inspect Lihat detail network docker network inspect mynet

Docker Compose

File docker-compose.yml:



version: '3'
services:
  web:
    image: nginx
    ports:
      - "8080:80"
  db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: admin

Perintah Fungsi
docker-compose up -d Jalankan semua service
docker-compose down Hentikan dan hapus semua container
docker-compose ps Lihat status container

Maintenance & Cleanup
Perintah Fungsi
docker system df Cek penggunaan storage
docker system prune -a Bersihkan semua yang tidak dipakai
docker image prune Bersihkan image tak terpakai
docker container prune Bersihkan container mati
docker volume prune Bersihkan volume tak terpakai
docker stats Lihat pemakaian CPU & RAM
docker inspect Lihat metadata container/image
docker cp Copy file ke/dari container

Interaksi dengan Docker Registry
Perintah Fungsi Contoh
docker login Login ke Docker Hub docker login
docker pull Download image docker pull nginx
docker push Upload image docker push user/nama_image

Shortcut Paling Penting
Tujuan Perintah
Jalankan web server docker run -d -p 8080:80 nginx
Masuk ke terminal container docker exec -it nama_container bash
Lihat semua container docker ps -a
Hapus semua container & image tak terpakai docker system prune -a

4. Membuat Aplikasi CRUD Sederhana dengan Docker

CRUD Web + Database Full Docker

image.png

Docker adalah platform containerization yang memungkinkan kamu membungkus aplikasi beserta dependensinya dalam satu wadah (container). Hal ini mempermudah proses deployment, testing, dan distribusi aplikasi tanpa khawatir perbedaan sistem operasi, package, atau versi runtime.

Tutorial ini cocok untuk:


Persiapan Awal

Syarat:

Untuk memastikan Docker sudah terinstall:

docker -v
docker compose version

Jika belum, kunjungi: https://www.32inside.com/books/docker/page/instal-docker 

Selanjutnya, kita akan membuat aplikasi web CRUD yang terdiri dari:

Struktur Folder
crud-app/
├── backend
│   ├── Dockerfile
│   ├── index.js
│   ├── package.json
│   └── public
│       └── index.html
└── docker-compose.yml
1. Buat Struktur Direktori Proyek
mkdir -p crud-app/backend/public
cd crud-app
2. Buat File docker-compose.yml
version: "3.9"

services:
  web:
    build: ./backend
    ports:
      - "3000:3000"
    depends_on:
      - db
    volumes:
      - web-data:/app
    restart: unless-stopped

  db:
    image: postgres:15
    environment:
      POSTGRES_DB: cruddb
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    volumes:
      - pgdata:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  pgdata:
  web-data:
3. File package.json untuk Backend
cd backend
vim package.json
{
  "name": "crud-app",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "express": "^4.18.2",
    "pg": "^8.11.0",
    "body-parser": "^1.20.2"
  }
}
4. File index.js (Backend Logic)
vim index.js
const express = require('express');
const bodyParser = require('body-parser');
const { Pool } = require('pg');
const path = require('path');

const app = express();
const port = 3000;

const pool = new Pool({
  user: 'postgres',
  host: 'db',
  database: 'cruddb',
  password: 'postgres',
  port: 5432,
});

app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));

pool.query(`
  CREATE TABLE IF NOT EXISTS items (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL
  )
`);

app.get('/items', async (req, res) => {
  const result = await pool.query('SELECT * FROM items');
  res.json(result.rows);
});

app.post('/items', async (req, res) => {
  const { name } = req.body;
  const result = await pool.query('INSERT INTO items(name) VALUES($1) RETURNING *', [name]);
  res.json(result.rows[0]);
});

app.put('/items/:id', async (req, res) => {
  const { id } = req.params;
  const { name } = req.body;
  await pool.query('UPDATE items SET name = $1 WHERE id = $2', [name, id]);
  res.sendStatus(200);
});

app.delete('/items/:id', async (req, res) => {
  const { id } = req.params;
  await pool.query('DELETE FROM items WHERE id = $1', [id]);
  res.sendStatus(200);
});

app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
});
5. File Dockerfile (Build Backend)
vim Dockerfile
FROM node:18

WORKDIR /app
COPY package.json .
RUN npm install
COPY . .

EXPOSE 3000
CMD ["node", "index.js"]
6. File index.html (Frontend GUI)
cd public
vim index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>CRUD Docker App</title>
  <style>
    body { font-family: sans-serif; margin: 2rem; }
    input, button { margin: 0.5rem; padding: 0.5rem; }
    table { border-collapse: collapse; margin-top: 1rem; width: 100%; }
    td, th { border: 1px solid #ccc; padding: 0.5rem; text-align: left; }
    tr:nth-child(even) { background-color: #f9f9f9; }
  </style>
</head>
<body>

<h1>CRUD Docker App (Express + PostgreSQL)</h1>

<input type="text" id="newItemName" placeholder="Item Name">
<button onclick="addItem()">Add Item</button>

<table>
  <thead>
    <tr>
      <th>ID</th><th>Name</th><th>Action</th>
    </tr>
  </thead>
  <tbody id="itemsTable"></tbody>
</table>

<script>
const apiBase = "/items";

async function fetchItems() {
  const res = await fetch(apiBase);
  const items = await res.json();
  const table = document.getElementById("itemsTable");
  table.innerHTML = "";
  items.forEach(item => {
    const row = document.createElement("tr");
    row.innerHTML = `
      <td>${item.id}</td>
      <td contenteditable onblur="updateItem(${item.id}, this.innerText)">${item.name}</td>
      <td><button onclick="deleteItem(${item.id})">Delete</button></td>
    `;
    table.appendChild(row);
  });
}

async function addItem() {
  const name = document.getElementById("newItemName").value;
  if (!name) return alert("Please enter a name.");
  await fetch(apiBase, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ name })
  });
  document.getElementById("newItemName").value = "";
  fetchItems();
}

async function updateItem(id, name) {
  await fetch(`${apiBase}/${id}`, {
    method: "PUT",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ name })
  });
}

async function deleteItem(id) {
  await fetch(`${apiBase}/${id}`, { method: "DELETE" });
  fetchItems();
}

fetchItems();
</script>

</body>
</html>
7. Menjalankan Aplikasi

Setelah semua file selesai dibuat dan diisi, kembali ke root folder:

cd ../../
8. Build dan jalankan seluruh stack:
docker compose up --build -d

Buka di browser:

http://<IPADDRESS>:3000

image.png