Hí anh em, Công việc quá bận nên lâu lắm rồi mình mới viết bài trên Viblo,
Đối với anh em đã có kinh nghiệm, kiến thức về triển khai thì bài viết này là vô ích, còn đối với anh mới thì bài viết này sẽ là cái nhìn tổng quan về quy trình sau code!
Trong bài viết này mình sử dụng docker để build image và triển khai lên trên Cloud nhé, cloud mình chọn là AWS và service mình dùng là Kubernetes. Có rất nhiều dịch vụ cloud khác để các bạn lựa chọn như: AZURE, GOOGLE CLOUD,DIGITAL OCEAN ..v.v..
Bắt đầu thôi
Coding
Mình sẽ sử dụng ReactJS để làm demo cho bài viết này, các bạn có thể sử dụng các ngôn ngữ khác mà các bạn biết nhé!
Tạo mới project ReactJS
Các bạn mở command trên thư mục mà các bạn muốn tạo, nhập lệnh này vào:
npx create-react-app react-demo-app
Lệnh trên sẽ tạo project reactjs với tên là React-demo-app, à mà nhớ cài NodeJS trước khi chạy dòng trên nhé *>
Nó đang chạy và đang tạo project cho mình rồi, đợi nó chạy xong thì các bạn mở project vừa tạo bằng Visual Studio Code hoặc các IDE khác mà các bạn hay dùng , mình thì hay dùng Visual!
Bạn sẽ thấy nó project sẽ như thế này và mở file App.js lên, mình sẽ không tạo các components mà sẽ code trực tiếp vào App.js luôn cho đỡ mất thời gian!
Mình sẽ không tạo project backend mà mình sẽ sử dụng https://mockapi.io để fake data cho nhanh Các bạn truy cập vào trang https://mockapi.io và tạo tài khoản và tạo project mới nhé
đây là cấu trúc mà mình sẽ genarate data, các bạn có thể tự tạo theo ý mình nhé!
sau khi tạo xong thì mình có 1 api endpoint như này: https://63f9c016beec322c57e72a16.mockapi.io/quo/blogs các bạn cũng có thể dùng luôn cái api endpoin này của mình cũng được hi
À quên, sau khi các bạn tạo project xong thì nhớ import thư viện Axios vào project nhé npm i axios
thư viện này để connect với api mà backend trả ra!
Viết một giao diện
Mình sẽ viết một giao diện demo thôi, mình sẽ hiện thị tất cả các giá trị của trường Name ra màn hình,
Nhưng mình sẽ không code bằng tay, mình lười lắm nên mình sẽ nhờ ChatGPT code hộ mình
Xong rồi đấy, coppy và paste vào file App.js thôi, và save lại và chạy lệnh npm start rồi quay lại google nhập url: http://localhost:3000/ thì sẽ thấy như này Xấu vc nhỉ, nhưng không sao mình test mà
import React, { useState, useEffect } from 'react';
import axios from 'axios'; const App = () => { const [blogs, setBlogs] = useState([]); useEffect(() => { axios.get('https://63f9c016beec322c57e72a16.mockapi.io/quo/blogs') .then(response => { setBlogs(response.data); }) .catch(error => { console.log(error); }); }, []); return ( <div> <h1>List of Blogs</h1> <ul> {blogs.map(blog => ( <li key={blog.id}>{blog.name}</li> ))} </ul> </div> );
}; export default App;
coppy và paste vào App.js
Build Docker Image
Nói qua một chút về Docker cho ai chưa biết, thì Docker hiểu nôm na nó như 1 môi trường chung vậy, nơi mà các bạn không phải lo đến conflic môi trường, version bla bla,
Thế còn image nó là cái gì, nó như một cái túi nilon vậy, nó gói tất cả những thứ cần thiết để có thể chạy một ứng dụng như soucre code, thư viện .v.v. muốn tìm hiểu sâu thì vào https://docs.docker.com/ đọc nhá chứ viết ra thì dài lắm hjx
Trước khi build một image thì bạn phải cài docker desktop trên máy của mình trước nhé, cài như nào thì cứ lên trang chủ Docker để xem nhá, dễ lắm
Để build một image thì bạn cần có 1 file có tên là Dockerfile tạo nó cùng cấp với src hoặc ở trong mộ thư mục nào đó trong project cũng được và nhớ D viết hoa, nội dung file sẽ như này
Dockerfile là nơi mà mình định nghĩ ra từng bước mà docker sẽ phải làm để build ra được 1 image
FROM node as base
//môi trường sử dụng nodejs WORKDIR /app
//chỗ làm việc của image COPY package*.json ./
// coppy các file package.json và package-lock.json vào image RUN npm install
// install những dependency vào image COPY . .
// coppy toàn bộ soucre vào image RUN npm run build
// build project FROM nginx:1.21-alpine
COPY --from=base /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
// ở đây mình sử dụng nginx để làm server triển khai luôn và exposed luôn port 80
các bạn có thể coppy nội dung này
để build được thì bạn chạy lệnh sau
docker build -t user-docker-hub/image-name:tag .
ví dụ
docker build -t thaond12052001/react-demo:2.0 .
tại sao lại cần user-docker-hub thì tý nữa mình nói sau!
như này là xong và bạn đã có 1 image rồi, để run được image này bạn sẽ sử dụng lệnh sau:
docker run -p 80:80 thaond12052001/react-demo:2.0
do trong Dockerfile mình có config nginx port 80 nên mình sẽ phải ánh xạ từ port 80 ra nhé! rồi bây giờ bạn truy cập http://localhost:80 là có thể nhìn thấy ứng dụng đang chạy mà bạn không cần phải start từ project local của bạn,
Như vậy là xong, bạn đã có 1 image từ chính project của mình rồi, nhưng rồi image này có tác dụng gì?
cùng xem tiếp nào
Deploy ứng dụng trên môi trường production
Push image
Sau khi có image rồi thì mình sẽ deploy nó lên môi trường Production hay còn gọi là môi trường Live đó, hoặc bạn đã từng nghe nói để từ GO LIVE thì chính là lúc bạn public ứng dụng của bạn ra bên ngoài cho người khác có thể truy cập được!
OK, để triển khai được thì chúng ra cần 2 thứ: 1. Nơi lưu trữ image 2. Nơi deploy và expose ra ngoài
- Đối với nơi lưu trữ image thì mình chọn https://hub.docker.com/ cho thuận tiện nhất, các bạn có thể sử dụng các nền tảng khác để push image lên, bạn tạo tài khoản và tảo 1 repository trên con hub này,
Chú ý: tạo tên repo thì đặt đúng với tên image nhé
ví dụ:
- bạn tạo tên repo là react-demo và user name trên docker hub là thaond12052001
Như trên mình có đặt tên là: docker build -t thaond12052001/react-demo:2.0 .
thì thaond12052001 chíng là tên user của mình trên docker hub và react-demo chính là tên image còn :2.0 nó chính là Tag image hay có thể hiểu là version cũng được!
Và tại sao phải đặt tên như này vì để push được image lên docker hub thì phải theo quy chuẩn của docker hub và với lệnh comand trên thì khi chạy docker sẽ tự tìm đến user có tên là thaond12052001 và đẩy image vào repo có tên react-demo đến giờ thì bạn biết tại sao mình lại đặt tên như thế tùi nhỉ
Sau khi push lên thành công hãy check docker hub xem lên chưa - Click vào repo có tên react-demo VÀ Click sang phần Tag
Bạn đã thấy tag 2.0 đã lên rồi này
Thế push lên rồi thì làm gì nữa:
- sau khi push lên docker hub thì bạn có thể vứt cho bàn bè của bạn image này và bảo chúng nó run image lên là có thể xem được project của bạn mà không cần phải clone git của bạn và setup môi trường nữa
- hoặc bạn làm việc nhóm thì bạn cũng có thể sử dụng docker cho dự án của mình để tránh bị conflic môi trường
Deploy to Kubernetes (K8s)
Đây là bước cuối cùng trogn quy trình triển khai ứng dụng!
À tiện đây mình cũng chia sẻ luôn là, những gì mình chia sẻ từ đầu đến giờ chỉ là những bước tương đối cơ bản trong quy trình deploy ứng dụng thôi, mình có không có thời gian để hướng dẫ hết tất cả các bước deploy của 1 dự án thực tế vì nó rất dài và nhiều bước nên không thể nói trong 1 bài này được. Và phần này mình cũng sẽ lướt nhanh qua thôi
*Trước khi deploy lên kubernetes thì phải cần có image mà mình đã hướng dẫn ở trên, nhưng hầu như các dự án lớn thì không ai đi config và làm thủ công các bước như trên cả mà sẽ sử dụng các công nghệ khác nhau để tối ưu hó thời gian triển khai như sử dụng gitlab ci, jenkins, github ci và sẽ cấu hình 1 file config để sau khi commit code lên git thì sẽ tự động build, test, tự tạo image và tự push luôn lên registry có thể là docker hub hay registry riêng. Sau đó sẽ có những công nghệ khác để trickger sự thay đổi và dự động deploy lên K8s luôn nên mình sẽ không phải làm gì nhiều ngoài việc commit change repo git cả *
Nói thế thôi, bây giờ đến phần deploy nó lên kubernetes hay còn gọi là k8s
đầu tiên các bạn cần phải có 1 cluster kubernetes, sử dụng của bên nào cũng được, mình sẽ sử dụng của Amazon Web Service (aws)
ở đây mình sử dụng service EKS của AWS và mình có tạo 1 cluster có tên là thaond-cluster
Bây giờ mình sẽ phải cài Kubectl và Awscli vào máy, cái này các bạn tự cài, cũng dễ thôi,. Sau đó mình sẽ connect tới cluster bằng Kubectl
Mở terminal lên và chạy câu lệnh
aws eks update-kubeconfig --name cluster-name --region khu vực
và đây là câu lệnh mình sẽ chạy
aws eks update-kubeconfig --name thaond-cluster --region ap-southeast-1
đây là sau khi chạy xong
bây giờ mình sẽ viết 1 file config để deployment nhé!
các bạn tạo 1 folder bất kì trong máy, và tạo 1 file có tên tuỳ các bạn chọn, ở đây mình đặt là deployment-service.yaml
nội dung của file:
kind: Deployment
apiVersion: apps/v1
metadata: name: react-deployment
spec: replicas: 1 selector: matchLabels: app: react template: metadata: labels: app: react spec: containers: - name: react image: thaond12052001/react-demo:2.0 //đây chính là image mà vừa nãy mình đẩy lên docker hub đó, nó sẽ pull về từ docker hub imagePullPolicy: Always ports: - containerPort: 80 restartPolicy: Always ---
kind: Service
apiVersion: v1
metadata: name: react-service
spec: type: LoadBalancer ports: - port: 80 targetPort: 80 protocol: TCP selector: app: react
Ở đây mình dùng type: LoadBalancer cho nhanh, các bạn coppy vào folder kia!
Sau khi coppy xong thì mở terminal của thư mục mà các bạn chứa file config yaml kia và chạy lệnh sau:
kubectl apply -f deployment-service.yaml
sau khi chạy xong thì kiểm tra xem đã deploy ok chưa
thấy READY 1/1 là ok rồi này, à đây mình dùng tool K9S để quản lý cluster, các bạn có thể dùng terminal và chạy : kubectl get deployment
để xem nhé!
Bây giờ đến lúc xem thành quả deploy rồi, mở terminal lên và chạy : kubectl get service
Và sẽ hiển thị thông tin service ra đây, các bạn để ý dòng có NAME là react-service và cột EXTERNAL-IP thì sẽ thấy Loadbalancer tự động tạo ra cho mình 1 cái ip dài ngoằng thế kia, bạn cũng có thể coppy cái đoạn này và paste vào url browser để xem trang web bạn deploy thành công hay chưa, nhưng mình thấy dài quá, trông khó chịu vãiiiii, nên mình sẽ dùng ip của Pods để truy cập cho ngắn gọn bằng cách chạy lệnh command : nslookup EXTERNAL-IP
coppy cái EXTERNAL-IP ở trên và paste vào đây và sẽ thấy thông tin như sau:
Bạn sẽ thấy như thế này, bạn có thể sử dụng ip trên hay dưới để truy cập vào website của mình đều được, mình sẽ thử với ip 52.76.199.95 Oke rồi này, giống với local rồi này, bây giờ vác cái IP này vứt cho bạn bè bảo nó truy cập và xem thôi,
Lưu ý: sẽ không ai để ip kiểu này khi expose ra ngoài cả, mà sẽ dùng domain để trỏ tới vì ip này sẽ không ổn định và có thể bị thay đổi
Kết
vậy là cũg xong bài viết, cũng khá dài rồi Phần K8S mình nghĩ các bạn chỉ tham khảo thôi, còn nếu muốn tự deploy thì hãy tìm hiểu qua các trang document chính thức của k8s nhé thôi chào tạm biệt anh em, hẹn anh em ở bài viết khác!