## 📘 Pengenalan Ringkas: Apa Itu Docker?

**Docker** ialah platform sumber terbuka yang membolehkan pembangun membungkus aplikasi bersama semua kebergantungan (dependencies) ke dalam satu unit yang dipanggil **container**.

### 🌟 Kelebihan Docker:

- 🚀 **Cepat & Ringan** – Lebih pantas berbanding VM (Virtual Machine) dan guna sumber lebih sedikit.
- 🔄 **Konsisten** – "It works on my machine" tidak lagi jadi masalah.
- 🧪 **Mudah untuk Ujian** – Boleh bina & uji aplikasi dalam persekitaran yang terpencil.

---

## 📦 Konsep Asas Docker

### 1. 🧊 Image
- Imej ialah **template read-only** yang mengandungi segala yang diperlukan untuk menjalankan aplikasi: kod, runtime, pustaka, dan dependencies.
- Contoh: `node:16-alpine`, `mysql:latest`

### 2. 📦 Container
- Container ialah **instance** aktif daripada image.
- Ia adalah persekitaran yang terpencil dan ringan untuk menjalankan aplikasi.

### 3. 💾 Volume
- Volume digunakan untuk **menyimpan data** secara berterusan di luar container.
- Ini penting untuk data seperti pangkalan data yang anda tidak mahu hilang apabila container dimusnahkan.

### 4. 📝 Dockerfile
- Fail konfigurasi yang digunakan untuk **bina image**.
- Mengandungi arahan seperti `FROM`, `COPY`, `RUN`, `EXPOSE`, dan `CMD`.

### 5. 🔗 Docker Compose
- Alat untuk **urus berbilang container** dalam satu fail YAML (`docker-compose.yml`).
- Memudahkan deploy aplikasi yang ada frontend, backend, dan pangkalan data sekaligus.
- Contoh perintah:
  ```bash
  docker-compose up -d --build
  ```

---


# 🚀 LATIHAN AMALI: Docker untuk Aplikasi React + Spring Boot



## 1. ✅ PROSEDUR PEMASANGAN DOCKER DESKTOP (WINDOWS)

1. **Akses laman rasmi Docker**  
   👉 [https://www.docker.com/products/docker-desktop](https://www.docker.com/products/docker-desktop)

2. **Muat turun pemasang** (.exe)

3. **Jalankan pemasang**  
   Klik dua kali pada fail `.exe`

4. **Ikuti arahan pemasangan**  
   ✔ Aktifkan WSL 2 (jika Windows Home)  
   ✔ Teruskan pemasangan

5. **Selesaikan pemasangan**  
   🔄 Restart jika diminta

6. **Buka Docker Desktop** dari menu Start

7. **Sahkan pemasangan Docker**  
   ```bash
   docker --version
   ```

---

## 2. 🐳 DEPLOY APLIKASI MENGGUNAKAN DOCKER

### 2.1 🎯 Objektif

- Fahami containerization React + Spring Boot
- Gunakan `docker-compose` untuk deploy sistem penuh

### 2.2 📦 Keperluan

- Docker Desktop
- Git & VS Code (atau mana-mana teks editor)

### 2.3 📁 Struktur Folder Projek
```
your-project/
├── productApp/         # React frontend
│   ├── Dockerfile
│   ├── .env
│   └── nginx.conf
├── productSvc/         # Spring Boot backend
│   └── Dockerfile
├── nginx.conf          # NGINX config for serving React app (optional global config)
└── docker-compose.yml  # Compose file to run both services

```
📥 Muat turun:  
[Download Projek ZIP](http://gitlab.cybersolution.com.my/mbdk-tot/product-management-docker/repository/master/archive.zip)

🗂 Extract ke direktori:  
`C:\Users\<nama-anda>\Documents\DockerProductApp\`

---

## 2.4 🌐 Deploy React App

### 2.4.1 🔧 Dockerfile (React)

Letak dalam `productApp/Dockerfile`

```
FROM node:16-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```

### 2.4.2 ⚙️ Fail nginx.conf

Letak dalam `productApp/nginx.conf`

```
server {
    listen 80;
    location / {
        root /usr/share/nginx/html;
        index index.html;
        try_files $uri $uri/ /index.html;
    }
}
```

📌 **Nota:** Membolehkan React Router handle routing.

### 2.4.3 ▶️ Jalankan React App dalam Docker

```bash
cd productApp
docker build -t product-ui .
docker run -d -p 3000:80 --name product-ui product-ui
docker ps
```

🌍 Akses: [http://localhost:3000](http://localhost:3000)

---

## 2.5 ⚙️ Deploy Java Spring Boot

### 2.5.1 🔧 Dockerfile (Spring Boot)

Letak dalam `productSvc/Dockerfile`

```
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /app
COPY . .
RUN ./gradlew clean build -x test

FROM eclipse-temurin:21-jdk-alpine
WORKDIR /app
COPY --from=builder /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
```

### 2.5.2 ▶️ Jalankan Spring Boot App

```bash
cd productSvc
docker network create my-network

docker run -d --network my-network --name mysql-db \
  -e MYSQL_ROOT_PASSWORD=S3cret \
  -e MYSQL_DATABASE=productmngm \
  -p 3306:3306 mysql:latest

docker build -t product-svc .

docker run -d --network my-network -p 8025:8025 --name product-service \
  -e APP_INTERNAL_PORT=8025 \
  -e DB_ADDRESS=mysql-db \
  -e DB_PORT=3306 \
  -e DB_NAME=productmngm \
  -e DB_USERNAME=root \
  -e DB_PASSWORD=S3cret \
  product-svc

docker ps
```

🌍 Akses Swagger:  
[http://localhost:8025/product-service/swagger-ui/index.html](http://localhost:8025/product-service/swagger-ui/index.html)

---

## 3. 🧩 Deploy Multi-container dengan Docker Compose + NGINX

### 3.1 📜 Fail docker-compose.yml

Letakkan di root projek:

```yaml
version: '3.8'

services:
  product-svc:
    container_name: productservice
    build: ./productSvc
    ports:
      - "8020:8020"
    environment:
      APP_INTERNAL_PORT: 8020
      DB_ADDRESS: mysql
      DB_PORT: 3306
      DB_NAME: productmngm
      DB_USERNAME: root
      DB_PASSWORD: S3cret
    depends_on:
      - mysql
    networks:
      - my-network

  mysql:
    container_name: mysql
    image: mysql:latest
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: S3cret
      MYSQL_DATABASE: productmngm
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - my-network

  product-ui:
    container_name: product-ui
    build: ./productApp
    ports:
      - "8030:80"
    networks:
      - my-network

  nginx:
    container_name: nginx
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - product-svc
    networks:
      - my-network

volumes:
  mysql-data:

networks:
  my-network:
    driver: bridge
```

### 3.2 🔄 NGINX sebagai Reverse Proxy

**Reverse Proxy** = Pengantara antara pengguna dan backend

🗂 Contoh `nginx.conf`:

```
events {}

http {
    server {
        listen 80;

        location /product-service/ {
            proxy_pass http://productservice:8020/product-service/;
        }

        location /product-ui/ {
            proxy_pass http://product-ui:80/;
        }
    }
}
```

### 3.3 🚀 Jalankan Semua Sekali Guna Docker Compose

```bash
docker-compose up -d --build
```

### 3.4 ✅ Semak Semua Container Aktif

```bash
docker ps
```

### 3.5 🌍 Akses Aplikasi

- Frontend: [http://localhost/product-ui](http://localhost/product-ui)
- Backend API: [http://localhost/product-service/swagger-ui/index.html](http://localhost/product-service/swagger-ui/index.html)