Chủ Nhật, 5 tháng 9, 2021

Bài 5: Ứng dụng docker để tạo lập môi trường phát triển ứng dụng với Maven

Xây dựng môi trường hỗ trợ làm việc nhóm với Docker

Bài 5: Ứng dụng docker để tạo lập môi trường phát triển ứng dụng với Maven

Kiều Trọng Khánh, Nguyễn Lê Nhật Trường

 

Mục đích: Vận dụng các nội dung giới thiệu trong các bài viết về “Tổng quan về docker” và “Giới thiệu về dockerfile, volume và network”, chúng ta sẽ sẽ thực hiện xây dựng và cấu hình services về môi trường để có thể deploy ứng dụng web (web container) phát triển bằng Maven có kết nối cơ sở dữ liệu với mục tiêu có thể sử dụng độc lập trên tất cả các máy của thành viên của team trong việc phát triển dự án hay trên máy tính của người học lập trình ứng dụng. Trong quá trình thiết lập, chúng ta sẽ áp dụng các khái niệm liên quan đến volume, network và layer trong docker file. Bên cạnh đó, chúng ta thiết lập nội dung cấu hình trực tiếp trong ngay project của ứng dụng để đảm bảo toàn bộ nội dung có thể được đồng bộ và lưu trữ trên các svn kèm theo dự án.

Yêu cầu về kiến thức cơ bản

·         Nắm vững các kiến thức về docker từ khái niệm đến việc cài đặt docker desktop (tham khảo tại địa chỉ Docker Documentation | Docker Documentation)

·         Nắm vững kiến thức và các sử dụng tài nguyên trên Docker Hub (tham khảo tại địa chỉ Docker Hub - Container Image Library | Docker )

·         Tìm hiểu các lệnh docker-compose (tham khảo tại địa chỉ Compose file | Docker Documentation)

·         Tìm hiểu cú pháp lệnh của tập tin YAML (tham khảo tại địa chi YAML Ain’t Markup Language (YAML™) Version 1.2)

·         Nắm vững là đã thực hiện xong bài viết “Xây dựng môi trường hỗ trợ làm việc nhóm với Docker” (tham khảo tại địa chỉ http://www.kieutrongkhanh.net/search/label/Docker )

·         Nắm vững và đã thức hiện phát triển ứng dụng web với mô hình MVC2 sử dụng ant tool (tham khảo tại địa chỉ http://www.kieutrongkhanh.net/search/label/Servlet%26JSP , http://www.kieutrongkhanh.net/search/label/Video_Servlet, http://www.kieutrongkhanh.net/search/label/Video_JSP )

·         Nắm vững và đã thức hiện phát triển ứng dụng web với mô hình MVC2 sử dụng Maven (tham khảo tại địa chỉ http://www.kieutrongkhanh.net/2021/02/xay-dung-ung-dung-java-web-voi-maven.html )

·         Nắm vững cấu trúc của gói ứng web được deploy vào web container (war file) (tham khảo tại địa chỉ Application Developer's Guide (7.0.109) - Deployment (apache.org))

Công cụ thực hiện

·         Để thực hiện và thao táo trong quá trình xây dựng services – tool Microsoft Visual Code (Download Visual Studio Code - Mac, Linux, Windows)

·         Docker Desktop (Docker Desktop for Mac and Windows | Docker)

·         Microsoft SQL Server Management Studio (Download SQL Server Management Studio (SSMS) - SQL Server Management Studio (SSMS) | Microsoft Docs) hay DBeaver (DBeaver Community | Free Universal Database Tool) hay bất kỳ công cụ hỗ trợ kết nối dữ liệu với DBMS (tool Netbeans IDE cũng hỗ trợ trong Services/Database)

·         Netbeans từ 8.x trở lên (tham khảo tại địa chỉ Welcome to Apache NetBeans)

·         Maven đã được cấu hình trên máy thực hiện (tham khảo tại địa chỉ http://www.kieutrongkhanh.net/2021/02/xay-dung-ung-dung-java-web-voi-maven.html)

 

Xây dựng service-docker cho môi trường triển khai ứng dụng với Maven

·         Chúng ta mở lại ứng dụng web Maven đã thực hiện trong tool, ở đây chúng tôi thực hiện với tool Netbeans (tham khảo tại địa chỉ http://www.kieutrongkhanh.net/2021/02/xay-dung-ung-dung-java-web-voi-maven.html).

o   Chúng ta có thể chạy lại để kiểm tra việc thực thi ứng dụng Maven bằng cách click phải chuột trên project, chọn Run Maven và chạy các goal. Ở đây chúng ta thực hiện clean and build với lệnh clean, install

o   Deploy ứng dụng vào tomcat đã được start trong Netbeans

o   Test lại việc ứng dụng thực thi

o   Ứng dụng đã sẵn sàng cho việc đưa vào sử dụng làm project mẫu cho bắt đầu triển khai để phát triển tiếp

·         Chúng ta kiểm tra việc thiết lập môi trường Maven đã được cấu hình sẵn sàng hay chưa bằng cách sử dụng command prompt vời lệnh mvn –version

·         Chúng ta bắt đầu thiết lập docker services vào trong ứng dụng

o   Trong Netbeans, chúng ta mở cửa sổ File để thao tác bằng cách click chọn menu Windows và chọn Files

o   Chúng ta thực hiện tạo thư mục docker bằng cách click phải chuột lên trên project, chọn New, chọn Other…. Trong cửa sổ New File, chúng ta chọn Other và chọn Folder

o   Chúng ta nhấn Next, đặt đên Folder là docker và nhấn Finish

o   Chúng ta thực hiện tương tự để tạo thư mục prepare trong thư mục docker

o   Chúng ta thực hiện tạo YAML file trong thư mục docker bằng cách click chuột phải trên thư mục docker và thực hiện các bước tương tự như cách tạo thư mục docker nhưng chọn YAML File và đặt tên là docker-compose

o   Chúng ta thực hiện bổ sung các nội dung vào file docker-compose.yml như sau

§  Chúng ta bắt đầu tìm hiểu phần khai báo cấu hình như sau

·         Chúng ta khai báo 2 services trong docker-compose là demo-db và demo-tomcat (dòng 3 và dòng 20)

·         Ở bài này, chúng ta sẽ chọn volume làm cơ chế mount dữ liệu dài hạn (persist data) do chúng ta cần đặc tính auto pre-populate của volume. Cụ thể trong image đã có sẵn dữ liệu (database và file war), chúng ta sẽ cần copy các dữ liệu ra vùng nhớ được mount trong lần đầu khởi chạy. Do đó, chúng ta khai báo 2 volumes để lưu trữ dữ liệu dài hạn là db và webapps. Hai volume này đều dùng driver local và bind nơi lưu dữ liệu vào một thư mục của máy host.

·         Do service demo-tomcat phải giao tiếp được với service demo-db để gửi và nhận dữ liệu. Với mục đích giao tiếp thân thiện và gợi nhớ hơn, chúng ta khai báo alias cho service demo-db là db.demo.com (dòng 17-19) và đồng thời chỉ định network mà 2 service này kết nối đến là demo-networks (dòng 17 và dòng 30).

·         Các lệnh cấu hình networks từ 44 đến 46 cho phép khai báo network được sử dụng trong docker-compose là demo-networks kèm với thông tin về driver của networks. Do hai service sẽ được deploy lên trên cùng một Docker host nên chúng ta sẽ dùng driver bridge cho trường hợp này.

·         Chúng ta khai báo mounting dữ liệu dài hạn của từng service ra volume tương ứng (dòng 14-15 và dòng 27-28). Chúng ta đã khá quen thuộc với các khai báo này trong các bài viết 1 và 2 cùng với các giải nghĩa trong bài 3 và 4

·         Các khai báo cấu hình services với container chứa cơ sở dữ liệu MySQL từ dòng 2 đến dòng 19

o   Chúng ta cũng đã khá quen thuộc với việc xác định tên image được xây dựng cùng việc việc đọc cấu hình từ build context đang được xác định là thư mục prepare mà chúng ta tạo lập ở các bước trên. Sau đó, từ build context đó chúng ta sẽ đọc các instruction thiết lập trong docker file với tên gọi là db.Dockerfile

§  Ở đây, chúng ta thấy quá trình tạo image phải thiết lập dữ liệu ban đầu từ tập tin db.sql trong build context (thư mục prepare). Chúng ta thực hiện tạo tập tin db.sql trong thư mục preprare tương tự như tạo folder

§  Các nội dung cơ bản trong tập tin sql tương tự như bài 1 là tạo DB Schema, tạo Table và insert các dữ liệu

§  Chúng thực hiện thêm tập tin db.Dockerfile vào thư mục prepare như cách chúng ta thêm mới thư mục

§  Chúng ta bổ sung các nội dung vào db.Dockerfile tương tự như trong bài 1 để load MySQL container

·         Dòng 1: chúng ta mong muốn chỉ định base image là mysql với tag là 5.7.35

·         Dòng 2: chúng ta cần chuẩn bị dữ liệu ban đầu (schema và data) cho database. Chúng ta tham chiếu tại nôi dung giới thiệu của image mysql trong docker hub, chúng ta có thể thấy hướng dẩn để khai báo dữ liệu ban đầu ở mục “Initializing a fresh instance”.

Cụ thể tai nội dung này, mysql sẽ thực thi các file có đuôi sql trong thư mục /docker-entrypoint-initdb.d trong lần đầu khởi chạy container. Do đó, chúng ta tiến hành copy file db.sql đã chuẩn bị trong buildContext và thư mục /docker-entrypoint-initdb.d bên trong image.

§  Chúng ta đã hoàn tất cấu hình dành cho thiết lập container chứa đựng cơ sở dữ liệu cùng với khởi tạo dữ liệu ban đầu

o   Chúng ta xác định port cấu hình mapping từ docker container đến docker host ở dòng 8 và 9

o   Chúng ta thiết lập các thông tin truy cập đến MySQL thông qua các environment từ dòng 10 đến dòng 13 (Các nội dung này chúng ta có thể tìm kiếm trên DockerHub - Docker Hub)

·         Các lệnh từ dòng 20 đến dòng 30 dùng để cấu hình services liên quan đến container chứa đựng web container. Ở đây, chúng ta lại sử dụng lại tomcat – nội dung này khá quen thuộc với chúng ta khi chúng ta đã trải nghiệm tại bài số 2. Tuy nhiên, điểm khác biệt chúng ta cần lưu ý là việc thiết lập của chúng ta là thực hiện trong project dự án cùng với việc dự án chúng ta được sử dụng Maven để build

o   Việc xác định build context từ dòng 22 đến dòng 24 của chúng ta không phải là thư mục prepare nữa mà phải từ thư mục gốc của project. Với các thiết lập này chúng ta mới cần lấy các thành phần của project một cách thuận lợi để thực hiện tạo ra gói deploy để có thể triển khai trên môi trường thực thi

o   Chúng ta nhìn thấy build context là từ thư mục chứa file YAML, chúng ta sẽ chuyển ra thư mục gốc của project chính là thư mục cha của thư mục docker. Do vậy, chúng ta dùng ký hiệu “..”

o   Chúng ta vẫn đọc cấu hình trong file docker file trong thư mục prepare. Bây giờ, chúng ta phải xác định đường dẫn từ build context là thư mục gốc project và đi đến thư mục prepare để chứa file

§  Chúng ta thực hiện tạo file web.Dockerfile trong thư mục prepare với các nội dung như sau

§  Ở đây, chúng ta sẽ áp dụng multi-state build để tách biệt môi trường build và môi trường thực thi ứng dụng.

§  Với môi trường build, chúng ta sẽ sử dụng jdk8 với maven build image ở dòng số 1

§  Thiết lập thư mục build làm hiện hành của quá trình tương tác trong image đang được tạo tại dòng số 2

§  Do dependencies ít khi thay đổi trong quá trình phát triển dự án, chúng ta nên đặt bước chuẩn bị dependency lên đầu để tận dụng cache cho các lần build sau (dòng 3, 4). Phần source code thường bị thay đổi hơn, chúng ta sẽ đặt bên dưới (dòng 5,6). Ở các lần build sau, nếu không thay đổi về cấu hình file pom.xml, docker sẽ chủ động dùng cache cho dòng 3, 4 và chỉ tập trung build lại source code đã thay đổi, từ đó tiết kiệm được thời gian build image.

§  Chúng ta thực hiện copy file pom.xml của project đang thực hiện từ build context vào thư mục build tại dòng số 3

§  Chúng ta thực hiện clean và tải về tất cả các dependencies từ các repositories chúng ta cần trong ứng dụng web đang phát triển tại dòng 4 trong quá trình build image bằng lệnh của maven

·         Tại chỗ này, vì chúng ta sẽ kết nối với DB là mySQL nên chúng ta cần cấu hình lại DataSource trong context.xmldependencies trong file pom.xml

·         File pom.xml, chúng ta xóa đi dependency của Microsoft sql server vì trong bài web maven chúng ta đang kết nối với DB của SQL Server. Chúng ta thay thế bằng dependency đến MySQL

·         File context.xml, chúng ta thay đổi việc thiết lập datasource đến DB container chúng ta đã thiết lập tương ứng với driver MySQL và networks chúng ta đã cấu hình ở trên

§  Chúng ta copy toàn bộ thư mục chứa mã nguồn của ứng dụng chúng ta đã làm trong thư mục src vào thư mục build tại dòng 5. Chúng ta có thể nhìn lại cấu trúc của thư mục project chúng ta trong cửa sổ File của Netbeans để hình dung rõ hơn

§  Chúng ta thực hiện biên dịch và đóng gói thành gói deploy tại dòng thứ 6 bằng lệnh của maven. Gói ứng dụng được đóng gói để deploy sẽ được đặt trong thư mục build/targer trong image

§  Tại dòng thứ 7, chúng ta sẽ load docker container của web container của build image tomcat từ docker hub

§  Chúng ta thực hiện deploy vào trong web container bằng cách copy gói war của ứng dụng trong build/target vào trong tomcat container, cụ thể là thư mục webapps

o   Các dòng thiết lập port và volums từ dòng 25 đến dòng 28, chúng ta đã biết qua trong bài 2 và các giải thích tương tự như ở phần thiết lập cơ sở dữ liệu ở trên

o   Quá trình cấu hình và thiết lập các services hoàn tất, chúng ta bắt đầu thực hiện test thử

·         Chúng ta thực hiện mở tool Microsoft VS Code với truy cập đến thư mục project bởi vì Netbeans không hỗ trợ console lệnh

o   Chúng ta mở terminal và chuyển đến thư mục docker bằng lệnh cd

o   Chúng ta thực hiện build services demo-db

§  Quá trình build mySQL image container đã thành công

o   Chúng ta thực hiện test load container để sử dụng. Chúng ta thực hiện lệnh up với docker-compose

§  Quá trình thực thi

§  Chúng ta nhận thấy MySQL container đã được host xong ở port 3306

§  Chúng ta có thể nhìn thấy trên docker desktop

§  Chúng ta có thể test kết nối thử với Netbeans

§  Chúng ta có thể sử dụng kết nối bẳng MySQL Workbench

o   Vì trên terminal thì DB container đang chạy nên chúng ta cần mở thêm một terminal thứ 02 để thực hiện build và test với service demo-tomcat trong file cấu hình yaml

§  Chúng ta tiếp tục thực hiện build image với service demo-tomcat

Quá trình này sẽ khá lâu tùy theo project, chúng ta dùng các repository nào và tốc độ đường truyền mạng để download (các lần build sau, nếu chúng ta dùng cache của docker thì việc build image sẽ tiết kiệm được thời gian để download các thư viện từ repositories)

§  Quá trình build image cho web container đã hoàn tất. Chúng ta có thể kiểm tra thử qua docker image ls

o   Chúng ta thực hiện load container để test thử với docker-compose up

§  Quá trình thực thi như sau

§  Chúng ta nhìn trên docker desktop

§  Chúng ta cũng có thể dùng lệnh để kiểm tra các container với docker ps

§  Chúng ta thực hiện test ứng dụng thử từ browser

 

o   Chúng ta nhìn thấy các volumes được mapping trong máy tính theo đường dẫn được cấu hình

o   Chúng ta nhìn thấy trên visual chúng ta có đến 02 cửa sổ terminal như sau

§  Vấn đề này là do chúng ta, đang test thử từng service riêng biệt

§  Khi mọi thứ đã chạy ổn, chúng ta chỉ cần thực hiện lệnh docker-compose up là đủ mà không cần ghi thêm tên service cụ thể. Toàn bộ cấu hình thiết lập sẽ được chạy và nạp các container cho chúng ta

 

Chúc mừng quí vị đã hoàn tất việc vận dụng các kiến thức liên quan đến docker từ volumes, networks, layer và việc thiết lập trong docker file để tạo ra môi trường làm việc với ứng dụng được build với Maven.

Ở bài tiếp theo, chúng ta sẽ tìm hiểu cách thức để đưa các image local lên các repository để dùng chung và sử dụng ở các nơi khác nhau.

Hy vọng nội dung của bài viết này hỗ trợ quí vị trong công việc và nghiên cứu học tập.

Rất mong sự góp ý chân thành và chia sẻ của quí vị về loạt series này. Hẹn gặp quí vị ở các tiếp theo trong loạt series này.

Không có nhận xét nào:

Đăng nhận xét