Bài 10. Build docker image cho ứng dụng Angular

Giới thiệu

Hôm nay, mình sẽ đi qua một ví dụ khác về cách xây dựng một Docker Image cho một ứng dụng Angular và chạy nó trên Ubuntu Server. Web tĩnh đơn giản chỉ là tập hợp của các tệp tin HTML, CSS, JavaScript, và người dùng sẽ truy cập vào tệp tin HTML để thu về trang web với nội dung được viết sẵn trong đó. Hiện nay, các ứng dụng Web App Frontend được xây dựng và tạo ra web tĩnh, ngoại trừ việc trong web tĩnh này có các thành phần tương tác tốt hơn so với web tĩnh truyền thống chỉ hiển thị thông tin. Trong bài viết này, chúng ta sẽ tạo ra Docker Image cho một ứng dụng Angular từ source code được clone từ GitHub.

Chuẩn bị

Chúng ta sẽ sử dụng source code từ kho lưu trữ astronot-angular. Máy tính của bạn cần phải cài đặt Git, Docker và chạy trên Ubuntu Server.

Bước 1: Cài đặt Docker trên Ubuntu Server (Nếu chưa có)

Trước tiên, chúng ta cần cài đặt Docker trên Ubuntu Server. Chạy các lệnh sau:

sudo apt-get update
sudo apt-get install -y docker.io
sudo systemctl start
docker sudo systemctl enable docker 

Bước 2: Clone source code từ GitHub

Tiếp theo, chúng ta sẽ clone source code từ kho lưu trữ GitHub.

cd ~
git clone https://github.com/mesinkasir/astronot-angular 
cd astronot-angular

Xây dựng Image

Bước 1: Viết Dockerfile và Nginx Config

- Dockerfile là tệp tin text chứa các chỉ dẫn để Docker Build Image của bạn. Trong thư mục gốc của dự án vừa clone về, tạo một file tên là Dockerfile và thêm vào các dòng sau:

##### Dockerfile #####
## build stage ##
FROM node:18.18-alpine as build
WORKDIR /app
COPY . .
RUN npm cache clean --force && npm install
RUN npm run build

## run stage ##
FROM nginx:alpine
RUN rm -rf /run
RUN mkdir /run
COPY --from=build /app/dist /run
COPY nginx.conf /etc/nginx/nginx.conf

- nginx.conf là tệp tin text chứa thông tin cấu hình Nginx Server

# Định nghĩa người dùng mà các tiến trình worker của Nginx sẽ chạy dưới quyền
user nginx;

# Đặt số lượng tiến trình worker
worker_processes 1;

# Chỉ định vị trí tệp nhật ký lỗi và mức độ nhật ký
error_log /var/log/nginx/error.log warn;

# Chỉ định vị trí của tệp PID lưu trữ ID tiến trình của tiến trình chính
pid /var/run/nginx.pid;

# Khối events để đặt cấu hình xử lý kết nối
events {
    # Số lượng kết nối đồng thời tối đa mà một tiến trình worker có thể mở
    worker_connections 1024;
}

# Khối HTTP để định nghĩa các thiết lập máy chủ HTTP
http {
    # Bao gồm định nghĩa các loại MIME
    include /etc/nginx/mime.types;

    # Đặt loại MIME mặc định cho các tệp
    default_type application/octet-stream;

    # Định nghĩa định dạng nhật ký cho nhật ký truy cập
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';

    # Chỉ định vị trí và định dạng của nhật ký truy cập
    access_log /var/log/nginx/access.log main;

    # Bật sendfile để cải thiện hiệu suất bằng cách giảm các chuyển đổi ngữ cảnh giữa kernel và user space
    sendfile on;

    # Đặt thời gian chờ cho các kết nối keep-alive với client
    keepalive_timeout 65;

    # Khối server để định nghĩa các thiết lập máy chủ
    server {
        # Lắng nghe trên cổng 80 (HTTP)
        listen 80;

        # Định nghĩa tên máy chủ
        server_name webclient;

        # Khối location để định nghĩa cách xử lý các yêu cầu cho địa chỉ gốc
        location / {
            # Định nghĩa thư mục gốc cho các yêu cầu
            root /run;

            # Chỉ định tệp index để phục vụ khi một thư mục được yêu cầu
            index index.html;

            # Cố gắng chạy trên tệp, nếu không tìm thấy thì chuyển hướng tới /index.html
            try_files $uri $uri/ /index.html;
        }

        # Định nghĩa các trang lỗi tùy chỉnh cho các mã trạng thái HTTP cụ thể
        error_page 500 502 503 504 /50x.html;

        # Khối location để phục vụ các trang lỗi tùy chỉnh
        location = /50x.html {
            # Định nghĩa thư mục gốc cho trang lỗi
            root /usr/share/nginx/html;
        }
    }
}

Bước 2: Build Image từ Dockerfile

Chạy lệnh sau để Build Image cho ứng dụng Angular:

docker build -t astronot-angular .

Lệnh trên sẽ Build một Docker Image với tên angular5-typescript-calculator từ thư mục hiện tại (dấu chấm).

 

Bước 3: Kiểm tra image

Liệt kê các Image có trong Docker Host:

docker images

Bạn sẽ thấy có Image với tên là astronot-angular.

Bước 4: Push image lên Docker Hub (Tùy chọn)

Nếu bạn muốn chia sẻ Docker Image của mình với người khác hoặc deploy trên một server khác, bạn có thể Push Image lên Docker Hub.

1. Đăng nhập vào Docker Hub:

docker login

2. Tag Docker image:

# cú pháp
docker tag astronot-angular <username>/<image_name>:<image_tag>
# ví dụ
docker tag astronot-angular dothiengiang0001/astronot-angular:v1

3. Push Docker image lên Docker Hub:

# cú pháp
docker push <username>/<image_name>:<image_tag>
# ví dụ
docker push dothiengiang0001/astronot-angular:v1

Thực thi tạo container từ image

Yêu cầu

  • Đưa container xuống chạy ngầm
  • Đặt tên cho containerangular5-typescript-calculator-container:v1
  • Tạo cổng kết nối thông từ 80 trên host vào cổng 5000 bên trong container

Tạo container từ image đã tạo:

# chạy với tên container tên angular5-typescript-calculator-container qua imagge dothiengiang0001/angular5-typescript-calculator:v1
docker run -d --name angular5-typescript-calculator-container -p 5000:80 dothiengiang0001/angular5-typescript-calculator:v1
# kiểm tra container
docker ps

Test thành quả

Mở trên Ubuntu bằng lệnh:

curl localhost:5000

Test trên browser google chrome

Thực hiện mở cổng kết nối qua Virtual Box:

- Lần này chúng ta mở cổng 5000 expose ra ngoài:

Trên Google Chrome chúng ta truy cập 127.0.0.120:5000 như thiết lập trên và xem kết quả:

Kết luận

Trong bài viết này, chúng ta đã đi qua quy trình chi tiết để xây dựng và triển khai một ứng dụng Anguular sử dụng Docker trên Ubuntu Server từ source code được clone từ GitHub. Các bước từ chuẩn bị mã nguồn, cài đặt Docker, viết Dockerfile, xây dựng Image, kiểm tra Image, đẩy Image lên Docker Hub, và cuối cùng là chạy container từ Image đã tạo đều được thực hiện một cách tuần tự và rõ ràng. Với việc sử dụng Docker, chúng ta không chỉ đảm bảo tính nhất quán trong môi trường triển khai mà còn tăng cường khả năng mở rộng và quản lý ứng dụng dễ dàng hơn.


Tác giả: Đỗ Thiên Giang

Chú ý: Tất cả các bài viết trên TEDU.COM.VN đều thuộc bản quyền TEDU, yêu cầu dẫn nguồn khi trích lại trên website khác.

Lên trên