Yêu cầu
– Triển khai docker trên nền tảng Windows 11 và ubuntu22.04
– Dùng portainer enterprise để kết nối các host docker lại để triển khai.
– Tạo một Registry local và lưu trữ image lên đó.
– Viết Dockerfile và triển khai dự án Shopping-Cart dùng Java sprint boot trên:
+ Viết Dockerfile
+ Đóng gói image
+ Public image lên docker hub
+ Docker Windows
+ Docker Linux
– Triển khai một cụm docker-compose đầy đủ:
+ Backup end
+ Frond end
+ Health check
Để triển khai dự án Java Spring boot trên docker với các yêu cầu trên tôi sẽ chia làm 2 phần
Phần 1: Cài đặt docker và thành phần liên quan
Phần 2: Triển khai dự án Shopping Cart dùng Java Spring Boot.
PHẦN 1: CÀI ĐẶT DOCKER VÀ THÀNH PHẦN LIÊN QUAN
1. Cài đặt và cấu hình Docker trên windows và Linux
1.1 Cài đặt docker trên windows
Yêu cầu hệ thống
| Yêu cầu | Hệ thống |
| Hệ điều hành | Windows 10 hoặc Windows 11 (bản 64 bit) |
| CPU | Hỗ trợ ảo hóa (VTx – AMD -v) |
| RAM | >=4G |
| Tính năng bổ sung | WSL 2 (Windows Subsystem for Linux 2) |
Cài đặt
Bước 1: Truy cập vào trang https://docker.com chọn phên bản phù hợp với hệ điều hành của máy tính

Bước 2: Chạy file .exe vừa download và làm theo các chỉ dẫn




Bước 3: Sau khi khởi động lại vào windows và chạy Docker Desktop

Bấm Accept

Bấm Skip hoặc Create an account để tạo tài khoản, hoặc nhập email để đăng nhập
Bước 4: Nếu gặp lỗi

Thì thực hiện các như sau
Mở powershell, Run As Administrator

Run lệnh wsl --update

Đợi cho update xong bấm Restart
Đợi Docker Engine Start


Đến đây là Docker Desktop đã được cài đặt thành công trên windows
1.2 Cài đặt docker trên linux
Yêu cầu hệ thống
| Yêu cầu | Hệ thống |
| Hệ điều hành | Ubuntu 22.04 hoặc Ubuntu 24.04 |
| CPU | Hỗ trợ ảo hóa (VTx – AMD -v) |
| RAM | >=4G |
Bước 1: Cập nhật hệ thốngsudo apt update
sudo apt upgrade -y
Bước 2: Cài các gói hỗ trợsudo apt install apt-transport-https ca-certificates curl software-properties-common -y
Bước 3: Thêm khóa GPG chính thức của dockercurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Bước 4: Thêm Docker repository vào danh sách nguồn APTecho "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list> /dev/null
Điều này giúp bạn cài Docker từ nguồn chính thức
Bước 5: Cài Docker Enginesudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose -y
Sau khi cài xong, Docker Engine (bao gồm docker‑ce, cli, và containerd) sẽ sẵn sàng
Bước 6: Kiểm tra trạng thái Dockersudo systemctl status docker
Nếu Docker đang chạy bình thường, bạn sẽ thấy trạng thái active (running)

Bước 7: Cho phép chạy Docker không cần dùng sudosudo usermod -aG docker ${USER}
newgrp docker
Sau khi thêm vào group docker, bạn có thể thao tác Docker mà không cần sudo
2. Cài đặt Portainer để quản lý các node docker
2.1 Portainer là gì?
Portainer là công cụ quản lý Docker Containter miễn phí với kích thước gọn nhẹ và giao diện quản lý trực quan, đơn giản để triển khai cũng như sử dụng, cho phép người dùng dễ dàng quản lý Docker host hoặc Swarm cluster.
Portainer được chia làm 2 phiên bản là Community Edition (CE) và Business Edition (BE). Bảng CE là phiên bản miễn phí nhưng những tính năng nó cung cấp hoàn toàn đủ để chúng ta có thể sử dụng
2.2 Cài đặt Portainer
Bước 1: Kiểm tra docker đã được cài đặt chưa
docker version

docker compose --version

Bước 2: Tạo volume để lưu dữ liệu của portainer
docker volume create portainer_data
Bước 3: Download và cài đặt Portainer
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:lts
Bước 4: Cấu hình và sử dụng Portainer
Truy cập vào địa chỉ https://IP_SERVER:9443

Chọn Advanced, sau đó bấm Procceed to...
Sau khi truy cập portainer sẽ yêu cầu tạo mật khẩu cho tài khoản admin.

Sau khi tạo user thành công

Bấm vào Get Started để tiến hành kết nối Portainer
Giao diện Dashboard của Portainer

Thêm host để quản lý: Enviroment-related -> Enviroments -> Add enviroment

Chọn môi trường phù hợp (ở đây tôi chọn Docker Standalone)

Copy và paste command vào host

Sau khi add host dashboard như sau

3. Cài đặt harbor làm Registry local
Harbor là một giải pháp Docker Registry mã nguồn mở mạnh mẽ, được thiết kế để bảo vệ các artifact (các thành phần của ứng dụng như container image, Helm chart, v.v.) bằng cách áp dụng các chính sách kiểm soát truy cập dựa trên vai trò (RBAC) và quét lỗ hổng bảo mật. Không chỉ vậy, Harbor còn hỗ trợ ký các Docker image để đảm bảo chúng là nguồn đáng tin cậy, giúp bạn luôn yên tâm về tính toàn vẹn của những gì mình triển khai.
3.1 Yêu cầu hệ thống
| Resource | Minimum | Recommended |
| CPU | 2 CPU | 4 CPU |
| Memory | 4 GB | 8 GB |
| Disk | 40 GB | 160 GB |
| Software | Version | Description |
|---|---|---|
| Docker Engine | Version > 20.10 | Docker Engine Installation |
| Docker Compose | Docker compose > 2.3 | Docker Compose is part of Docker Engine |
| OpenSSL | Latest (optional) | Used to generate certificate and keys for Harbor |
3.2 Cài đặt harbor
Bước 1: download file cài đặt https://github.com/goharbor/harbor/releases/download/v2.13.1/harbor-online-installer-v2.13.1.tgz
Bước 2: Giải nén tar xvf harbor-online-installer-v2.13.1.tgz
Bước 3: Đổi tên file harbor.yml.tmpl thành harbor.yml
harbor/prepare
harbor/LICENSE
harbor/install.sh
harbor/common.sh
harbor/harbor.yml.tmpl
mv harbor/harbor.yml.tmpl harbor/harbor.yml
Bước 4: Tạo chứng chỉ SSL (self-signed)
sudo mkdir -p /opt/harbor/cert
cd /opt/harbor/cert
#Tạo private key
sudo openssl genrsa -out ca.key 4096
#Tạo ca certificate
sudo openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt
#Tạo private key cho Harbor
sudo openssl genrsa -out harbor.key 4096
#Tạo CSR
sudo openssl req -new -key harbor.key -out harbor.csr
#Ký chứng chỉ với CA
sudo openssl x509 -req -in harbor.csr -CA ca.crt -CAkey ca.key -out harbor.crt -days 3650 -sha256
cd harbor
nano harbor.yml
Sửa các thông tin sau
hostname: 10.100.1.33
....
certificate: /opt/harbor/cert/harbor.crt
private_key: /opt/harbor/cert/harbor.key
data_volume: /opt/harbor/data
....
log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor
logger_sweeper_duration: 1
cd /opt/harbor
sudo ./prepare

sudo ./install.sh

3.3 Thực hiện login tới web quản trị
https://IP_SERVER

3.4 Sử dụng Harbor
Tạo Project


docker login -u admin IP_SERVER
docker push IP_SERVER image_docker
docker pull image_docker
PHẦN 2: TRIỂN KHAI DỰ ÁN SHOPPING CART DUNG JAVA SPRING BOOT
1. Cấu trúc thư mục dự án
│ .gitignore
│ pom.xml
│ README.md
│ shoe_shopdb.sql
└───src
├───main
│ ├───java
│ └───resources
└───test
2. Build Docker file
2.1 Các file cần tạo:
File .env: Chứa các biến môi trường của dự án
File Dockerfile: Chứa các thông tin để build dự án
File nginx.conf: Cấu hình nginx là reverse proxy để chạy FrontEnd
File docker-compose.yml: Để chạy toàn bộ dự án.
2.2 Vị trí các file sau khi được tạo ra.
│ .env
│ .gitignore
│ docker-compose.yml
│ Dockerfile
│ nginx.conf
│ pom.xml
│ README.md
│ shoe_shopdb.sql
└───src
│ ├───main
│ │ ├───java
│ │ └───resources
│ └───test
└───frontend
2.3 Nội dung các file
.env
MYSQL_ROOT_PASS=xxxx
MYSQL_DB_NAME=shoeshop_db
Dockerfile
FROM maven:3.8.6-openjdk-17 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
FROM eclipse-temurin:17-jdk
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s \
CMD curl -f http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-jar", "app.jar"]
nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
# Serve frontend static files
location / {
try_files $uri $uri/ /index.html;
}
location / {
proxy_pass http://shop-backend:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
docker-compose.yml
services:
db:
image: mysql:8.0
container_name: shop-db
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASS}
MYSQL_DATABASE: ${MYSQL_DB_NAME}
ports:
- "3306:3306"
volumes:
- db_data:/var/lib/mysql
- ./shoe_shopdb.sql:/docker-entrypoint-initdb.d/shoe_shopdb.sql:ro
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
backend:
image: beobeo/shoes-shop:latest
container_name: shop-backend
depends_on:
db:
condition: service_healthy
ports:
- "8080:8080"
frontend:
image: nginx:alpine
container_name: shop-frontend
volumes:
- ./frontend/dist:/usr/share/nginx/html:ro
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "80:80"
depends_on:
- backend
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 5s
retries: 3
volumes:
db_data:
Cần phải sửa file src\main\resources\application.properties để thay đổi connection string kết nối với database
spring.datasource.url=jdbc:mysql://shop-db:3306/shoeshop_db
spring.datasource.username=root
spring.datasource.password=Password_Root
shop-db: Tên container mysql được khai báo trong filedocker-compose.yml
shoesshop_db: Tên database được khai báo trong file.env
spring.datasource.username: user root của DB
spring.datasource.password: mật khẩu root của DB đươc khai báo trong file.env
Lưu ý: Cần sửa file này trước khi build Dockerfile
3. Build Image và Push lên Docker Hub
Build Image
docker build -t beobeo/shoes-shop:latest .
Push image lên Docker Hub
docker login
docker push beobeo/shoes-shop:latest
4. Triển khai dự án
4.1 Triển khai dự án trên Windows
Dự án đặt tại C:\Project\devops-coaching\shoeshop
Các image đã được đẩy lên docker hub
cd C:\Project\devops-coaching\shoeshop
C:\Project\devops-coaching\shoeshop> docker compose up -d


http://localhost

4.2 Triển khai trên Linux
Dự án đặt ở $HOME$/project/devops-coaching/shoeshop
cd $HOME$/project/devops-coaching/shoeshop
ls
drwxrwxr-x 3 iadmin iadmin 4096 Jul 21 21:43 frontend
drwxrwxr-x 7 iadmin iadmin 4096 Jul 21 21:46 .git
-rw-rw-r-- 1 iadmin iadmin 364 Jul 21 21:46 .gitignore
-rw-rw-r-- 1 iadmin iadmin 578 Jul 21 21:46 nginx.conf
-rw-rw-r-- 1 iadmin iadmin 3060 Jul 21 21:46 pom.xml
-rw-rw-r-- 1 iadmin iadmin 616 Jul 21 21:46 README.md
-rw-rw-r-- 1 iadmin iadmin 2650849 Jul 21 21:46 shoe_shopdb.sql
drwxrwxr-x 4 iadmin iadmin 4096 Jul 21 21:43 src
docker compose up -d
[+] Running 4/4
✔ Network shoeshop_default Created
✔ Container shop-db Healthy
✔ Container shop-backend Started
✔ Container shop-frontend Started

Kiểm tra
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
shop-backend beobeo/shoes-shop:latest "java -jar app.jar" backend About a minute ago Up About a minute (unhealthy) 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp
shop-db mysql:8.0 "docker-entrypoint.s…" db About a minute ago Up About a minute (healthy) 0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp, 33060/tcp
shop-frontend nginx:alpine "/docker-entrypoint.…" frontend About a minute ago Up About a minute (healthy) 0.0.0.0:80->80/tcp, [::]:80->80/tcp
http://localhost
