Hướng dẫn Deploy Spring Boot & MySQL lên VPS bằng Docker Compose
Hướng dẫn chi tiết cách deploy website Spring Boot Java 17 và MySQL 8 lên VPS Ubuntu sử dụng Docker Compose. Tích hợp Nginx Proxy Manager để cài SSL (HTTPS) miễn phí chỉ trong 5 phút.
Mở đầu
Bạn vừa hoàn thành xong một dự án website bằng Spring Boot (Java) và muốn đưa nó lên môi trường internet thực tế? Việc cài đặt thủ công Java, Tomcat, MySQL trên VPS Linux thường tốn nhiều thời gian và dễ gặp lỗi xung đột phiên bản.
Trong bài viết này, mình sẽ hướng dẫn các bạn cách Deploy ứng dụng Spring Boot lên VPS Ubuntu 22.04 sử dụng Docker & Docker Compose. Đây là phương pháp hiện đại, giúp hệ thống hoạt động ổn định, dễ dàng nâng cấp và backup dữ liệu.
Công nghệ sử dụng:
-
Java 17 (Spring Boot 3.x)
-
MySQL 8.0
-
Docker & Docker Compose
-
Nginx Proxy Manager (Để quản lý tên miền và SSL)
Phần 1: Chuẩn bị môi trường VPS
Đầu tiên, bạn cần SSH vào VPS. Thay vì cài đặt Docker thủ công phức tạp, chúng ta sẽ sử dụng script cài đặt tự động chính chủ để đảm bảo sự ổn định.
Chạy lệnh sau để cài đặt Docker:
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
Kiểm tra cài đặt thành công:
docker compose version
Phần 2: Đóng gói ứng dụng (Dockerfile)
Bước 1 : Tại máy tính cá nhân, bạn build dự án ra file .jar
Bạn đứng trong thư mục project chạy lệnh :
mvn clean package -DskipTests
Thông thường nó sẽ tạo ra file .jar ở đường dẫn `project/target`

Bước 2 :Upload lên VPS (ví dụ thư mục ~/my-website).
Upload file `.jar`, thư mục `uploads` và file `.sql` của bạn lên nhé.
Tạo file Dockerfile tại thư mục gốc của dự án trên VPS để định nghĩa môi trường chạy cho Java:
# Sử dụng Base Image Java 17 bản nhẹ (Alpine Linux)
FROM eclipse-temurin:17-jdk-alpine
# Thiết lập thư mục làm việc mặc định trong container
WORKDIR /app
# Copy file .jar vào container
COPY quyenlt-com.jar app.jar
# Lệnh khởi chạy ứng dụng
ENTRYPOINT ["java", "-jar", "app.jar"]

Phần 3: Cấu hình Docker Compose (Quan trọng)
Đây là bước quan trọng nhất để kết nối Spring Boot, MySQL và Nginx lại với nhau. Hãy tạo file docker-compose.yml:
version: '3.8'
services:
# 1. Database MySQL
mysqldb:
image: mysql:8.0.28 # Dùng bản 8.0.28 để ổn định với nhiều dòng CPU
container_name: mysqldb
restart: always
environment:
MYSQL_ROOT_PASSWORD: mat_khau_database
MYSQL_DATABASE: ten_database
command: --default-authentication-plugin=mysql_native_password
volumes:
- db_data:/var/lib/mysql
- ./data.sql:/docker-entrypoint-initdb.d/init.sql # Tự động import dữ liệu lần đầu
# 2. Ứng dụng Spring Boot
webapp:
build: .
container_name: webapp
restart: always
expose:
- "8080" # Chỉ mở port nội bộ cho Nginx, không lộ ra ngoài
depends_on:
- mysqldb
environment:
# Lưu ý: Host database là 'mysqldb', không phải localhost
SPRING_DATASOURCE_URL: jdbc:mysql://mysqldb:3306/ten_database?useSSL=false&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: mat_khau_database
SPRING_JPA_HIBERNATE_DDL_AUTO: update
# Cấu hình để đọc file upload từ thư mục map bên ngoài
SPRING_WEB_RESOURCES_STATIC_LOCATIONS: classpath:/static/,file:/app/
volumes:
# Map thư mục uploads từ VPS vào trong Container
- ./uploads:/app/uploads
# 3. Nginx Proxy Manager (Quản lý SSL)
nginx-proxy:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
depends_on:
- webapp
volumes:
db_data:
Lưu ý quan trọng về thư mục Uploads:
Để chức năng upload ảnh hoạt động và lưu trữ lâu dài trên VPS (không mất khi xóa container), bạn cần:
-
Map volume:
- ./uploads:/app/uploads(VìWORKDIRlà/app). -
Cấp quyền ghi cho thư mục trên VPS:
Bashsudo chmod -R 777 uploads
Phần 4: Khởi chạy và Cài đặt SSL
1. Khởi chạy hệ thống
Tại thư mục chứa file cấu hình, chạy lệnh:
sudo docker compose up -d --build
2. Trỏ tên miền (DNS)
Truy cập trang quản trị tên miền của bạn, trỏ 2 bản ghi A (@ và www) về địa chỉ IP của VPS.
3. Cấu hình HTTPS miễn phí
Truy cập vào trang quản trị Nginx: http://IP-VPS:81
-
Email:
[email protected] -
Password:
changeme

Vào mục Proxy Hosts -> Add Proxy Host:
-
Domain Names: Nhập tên miền của bạn.
-
Forward Hostname / IP: Nhập
webapp. -
Forward Port:
8080. -
Tab SSL: Chọn "Request a new SSL Certificate" và bật "Force SSL".
Bấm Save và tận hưởng thành quả! Website của bạn giờ đây đã chạy mượt mà với ổ khóa xanh bảo mật.

Các lỗi thường gặp (Troubleshooting)
1. Lỗi kết nối Database (Connection Refused)
-
Kiểm tra xem tên host trong URL kết nối JDBC có đúng là
mysqldb(tên service trong docker-compose) chưa. Tuyệt đối không dùnglocalhost.
2. Ảnh upload không hiển thị (404 Not Found)
-
Kiểm tra lại đường dẫn map volume. Nếu Dockerfile dùng
WORKDIR /app, volume phải map vào/app/uploads. -
Thêm cấu hình
SPRING_WEB_RESOURCES_STATIC_LOCATIONSvào environment để Spring Boot cho phép đọc file từ thư mục này.
3. Nginx báo "Internal Error" khi xin SSL
-
Kiểm tra xem bạn đã trỏ DNS tên miền về IP VPS chưa.
-
Đảm bảo tường lửa (Firewall) đã mở port 80 và 443.
Kết luận
Việc sử dụng Docker để deploy Spring Boot giúp bạn tiết kiệm hàng giờ đồng hồ cài đặt và debug lỗi môi trường. Hy vọng bài viết này giúp ích cho quá trình triển khai dự án của bạn.
Nếu có bất kỳ thắc mắc nào, hãy để lại bình luận bên dưới nhé!