Sau khi hoàn thành coding cho ứng dụng Spring Boot, là đến lúc chúng ta sẽ cần deploy lên Server để public các dịch vụ của mình đến người dùng. Hôm nay TheCodeRoot gửi đến các bạn bài viết hướng dẫn deploy ứng dụng Spring Boot lên môi trường Linux với Nginx làm proxy đầu vào.

1. Giới thiệu:

Để deploy được ứng dụng lên một public server để cung cấp dịch vụ từ website của bạn đến cho người dùng đòi hỏi khá nhiều công đoạn. Việc đầu tiên trước hết là bạn phải có một con public Server, tốt hơn hết là các bạn nên đặt mua (hoặc thuê) các dịch vụ Server bên ngoài, hiện tại gía thành Server VPS cũng đã trở nên khá phải chăng và vừa túi tiền với nhiều người, nhất là các bạn developer có nhu cầu cần Server cấu hình vừa phải để thực hành các pet project của mình. Tiếp theo đó chúng ta sẽ phải setup các phần mềm và môi trường cần thiết,  và thực hiện các bước hướng dẫn sau:

Trong bài viết này người viết sẽ không đi chi tiết vào việc chúng ta sẽ mua VPS  và các setting ban đầu như thế nào. TheCodeRoot đã có bài hướng dẫn các bạn các việc cần làm khi mới mua hoặc thuê VPS Linux, các bạn có thể tìm đọc lại ở đây Trong bài hướng dẫn này người viết sử dụng Hệ điều hành CentOS 7 cho Server.

Có thể sẽ có bạn hỏi rằng vì sao lại không hướng dẫn luôn deploy ứng dụng Spring Boot có database này kia luôn mà chỉ là Hello World. Vì những ứng dụng đòi hỏi Database hay Redis Cache sẽ đòi hỏi sẽ cần cài thêm và config cho những phần mềm đó, hơn nữa mục tiêu của bài viết này chỉ tập trung vào mục đích hướng dẫn các bạn có cách nhìn tổng quan nhất về việc deploy một ứng dụng Spring Boot. Và những phần mở rộng phức tạp hơn sẽ được hướng dẫn sau để không làm các bạn bị rối vì quá nhiều thông tin trong một bài viết.

2. Cài đặt môi trường:

Bài viết giả sử các bạn đã có Server và đã tiến hành cài đặt các bước cần thiết, có một user riêng ngoài root.

Chúng ta sẽ cần cài đặt môi trường Java và một số tools đi kèm để phục vụ cho việc deploy:

  • Open JDK 8
  • Maven 3 

Trong hướng dẫn này, do chúng ta chỉ demo deploy ví dụ Spring Boot Hello World nên chúng ta sẽ không cần Database. Trong các bài tiếp theo The Code Root sẽ hướng dẫn các bạn cài đặt Database và cách config từ file application.properties từ bên ngoài.

Các bạn lần lượt thực hiện các bước sau:

- Update các gói cài đặt cho Server:

sudo yum update

- Cài đặt Open JDK 8:

sudo yum install java-1.8.0-openjdk-devel

Sau khi cài đặt, các bạn chạy thử lệnh:

java --version

Nếu ra được output tương tự như sau nghĩa là đã cài đặt Open JDK 8 thành công:

openjdk version "1.8.0_161"
 OpenJDK Runtime Environment (build 1.8.0_161-b14)
 OpenJDK 64-Bit Server VM (build 25.161-b14, mixed mode)

- Cài đặt Maven:

sudo yum install maven

Kiểm tra cài đặt Maven thành công hay chưa:

mvn -version

Chúng ta sẽ nhận được output tương tự như sau:

Apache Maven 3.0.5 
Maven home: /usr/share/maven
Java version: 1.8.0_191, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el7_5.x86_64/jre
Default locale: en_US, platform encoding: UTF-8

 

3. Build và upload gói deploy của Spring Boot

Đầu tiên các bạn cần chuẩn bị sẵn source code của ví dụ Spring Boot Hello World, các bạn có thể xem lại bài viết tại đây Chúng ta sẽ build gói Jar của ứng dụng bằng Maven:

mvn clean install
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15.208s
[INFO] Finished at: Fri May 24 13:05:32 UTC 2019
[INFO] Final Memory: 30M/106M
[INFO] ------------------------------------------------------------------------

Sau khi hoàn tất build, chúng ta sẽ có folder target chứa 2 file jar, chúng ta sẽ chỉ quan tâm đến gói jar không có chữ 'original'. Tiếp theo cần upload gói jar lên Server bằng command scp. Ở bước này các bạn có thể dùng phần mềm WinSCP,  trong bài hướng dẫn này người viết dùng command line thuần.

"Các bạn lưu ý là các bước này vẫn đang thực hiện ở máy local của chúng ta nhé"

scp -P 22 /home/local-pc/springboot-p1/target/springboot-p1.jar username@ip-server:/home/dev/springboot-p1.jar

Trong đó:

  • /home/local-pc/springboot-p1/target/springboot-p1.jar: là address của folder chứa gói jar, các bạn chỉnh lại theo đúng đường dẫn folder trên máy của mình.
  • usenamer@ip-server: username và địa chỉ IP của Server.
  • /home/dev/springboot-p1.jar: vị trí upload gói jar ở Server.

Đến đây chúng ta đã hoàn tất upload gói jar lên Server và bước tiếp theo là chuẩn bị các script deploy.

3. Tạo script deploy và shutdown ứng dụng Spring Boot.

start.sh

#!/bin/bash
deploy_folder=/home/dev/
nohup /usr/bin/java -jar $deploy_folder/target/spring-boot-p1.jar  > /tmp/spring-boot.log 2>&1 &

Sau khi build xong gói jar ở trên chúng ta sẽ chạy file start.sh dưới dạng một Thread và ghi log của Spring Boot ra file /tmp/spring-boot.log. Về bản chất file start.sh cũng sử dụng câu lệnh java -jar để chạy gói jar Spring Boot, tuy nhiên tiến trình của Spring Boot sẽ không được thực thi dưới dạng background, khi các bạn bấm Ctrl+C ngừng tiến trình là ứng dụng Spring Boot cũng sẽ bị tắt theo - nghĩa là ứng dụng web sẽ không được chạy.

shutdown.sh

#!/bin/bash
proccess_id=$( ps aux | grep frontend | grep 'spring-boot-p1' | awk '{print $2}')
if test -n "$proccess_id"; then
    echo "Attempting to kill $proccess_id..."
    kill -9 $proccess_id
        echo "Process $proccess_id terminated"
else
    echo "Application is not running"
fi;

Cho phép 2 file sh trên có quyền execute:

chmod +X start.sh
chmod +X shutdown.sh

Trường hợp chúng ta sau khi chỉnh sửa, fix bug, thêm chức năng trong source code của project,   và cần thay thế gói jar mới, tiến trình của gói jar cần phải được shutdown trước, nếu không gói jar mới sẽ không được deploy do port của ứng dụng vẫn còn đang bị chiếm bởi gói jar cũ.

Để chuẩn bị cho 1 gói jar được deploy lần đầu cần tốn khá nhiều công sức chuẩn bị nhưng kể từ các lần deploy tiếp theo các bạn chỉ cần thực hiện chạy các file sh là được.

4. Cấu hình Nginx trỏ về Spring Boot.

Chúng ta vẫn có thể  hoàn toàn không dùng Nginx làm proxy đầu vào mà dùng trực tiếp ứng dụng Spring Boot với port 80. Nhưng khi sử dụng Nginx chúng ta có thể chủ động làm được nhiều việc hơn như:

  • Compress HTML output đầu ra theo chuẩn Gzip tiết kiêm băng thông
  • Chủ động cache các static file HTML, CSS, JS, ...
  • Dễ dàng cài đặt SSL hơn. 
  • Làm Load Balancer chủ động hơn. 
  • Config các trang hiển thị lỗi 404, 500, 502, ... dễ dàng hơn. 

Kinh nghiệm sử dụng Nginx TheCodeRoot sẽ chia sẻ các bạn trong các bài viết sau.

Cài đặt Nginx:

sudo yum install nginx
sudo service nginx start

systemctl enable nginx​

Forward request từ Nginx đến Spring Boot:

Chúng ta sẽ thêm config vào trong file conf của nginx:

  • upstream  springbootapp {
       server localhost:8080
    }

    Vào ngay dưới thẻ http { }. http là thẻ lớn nhất của file nginx.

  •  location / {
                proxy_pass https://springbootapp;
            }
    

    Vào ngay dưới thẻ server. Thẻ server nằm bên trong thẻ http.

Sau khi thêm xong config, cần phải khởi động lại Nginx:

sudo service nginx restart

Đến đây xem như chúng ta hoàn thành việc deploy gói Jar của Spring Boot lên Server, và hoàn toàn có thể truy cập bằng địa chỉ IP public của Server hoặc tên miền (nếu có).

Chúc các bạn thành công.

AutoCode.VN

 

minhnhatict@gmail.com Linux