Exam Reader

 

ExpressJS trên Docker

Cài đặt Docker

Xem cách cài đặt Docker ở đây

Tạo một NodeJS App

Xem cách tạo ứng dụng helloworld với ExpressJS ở đây

Tạo một image Docker

Trước hết ta tạo một file Dockerfile trống bằng câu lệnh

$touch Dockerfile

Copy nội dung sau vào file này:

FROM node:8.12.0-jessie
# Create app directory
WORKDIR /usr/src/app
# Bundle app src
COPY . .
# Install app dependencies
RUN npm install
EXPOSE 3000
CMD [ "node", "index.js" ]

Ý nghĩa:

  • Dòng FROM node:8.12.0-jessie chỉ ra rằng chúng ta muốn build từ image nào, ở đây mình dùng image 8.12.0-jessie có NodeJS version 8.12.0 LTS. Khi mình chạy lệnh build nó sẽ vào Docker Hub để lấy image này về để cho chúng ta thêm phần của mình vào .
  • Dòng WORKDIR /usr/src/app là nơi chứa code của chúng ta trong image.
  • Dòng COPY . . copy toàn bộ source của project vào trong image.
  • Dòng RUN npm install download các dependencies.
  • Dòng EXPOSE 3000 vì helloworld listen ở cổng 3000 nên ta sẽ EXPOSE ra tại cổng 3000.
  • Dòng cuối cùng CMD [ "node", "index.js" ] dùng CMD để chạy app.

Build image

Sử dụng câu lệnh sau

$docker build --rm -f Dockerfile -t helloworld:latest .

Nhớ có dấu . sau cùng nhen! Dấu . ở đây ám chỉ Dockerfile đang nằm trong thư mục hiện tại.

Sau khi nhấn ENTER, nó vào Internet pull image gốc về như hình

Sau khi chạy xong chạy lệnh kiểm tra xem nó đã tạo ra image chưa

$docker images

Run image

$docker run --rm -d -p 3000:3000 helloworld:latest

Rồi kiểm tra process bằng $docker ps

Vào Chrome chạy và test thử http://localhost:3000

Nếu màn hình xuất hiện chữ “Hello World!” là done. Congratulation!

Setup Docker trên Mac

Để cài đặt được Docker trên Mac, bạn chỉ cần truy cập trang sau:

https://docs.docker.com/docker-for-mac/install/#download-docker-for-mac

Để download phải đăng ký account trước. Account này không chỉ để dùng để download Docker mà còn dùng để download hay tạo các image sau này.

Sau khi đăng ký xong thì sẽ được tải về file docker.dmg rồi double click file để cài đặt. Đơn giản, bạn chỉ cần kéo thả biểu tượng con cá voi sang bên biểu tượng Application:

Sau khi setup xong thì biểu tượng cá voi xuất hiện trên thanh status bar. Click vào nó và đăng nhập với account đã tạo.

Whale in menu bar

Mở Terminal, chạy 2 lệnh sau xem quá trình cài đặt có OK không?

$docker version để kiểm tra version

$docker run hello-world để kiểm tra xem Docker có kéo image về như mong đợi hay không.

Nếu thành công. Xin chúc mừng đến với thế giới của Docker.

Tạo webapp Helloworld với ExpressJS

Yêu cầu đầu tiên cần phải setup NodeJS. Xem ở đây

Tếp theo là phải nghỉ ra cái tên cho webapp của mình. Ở đây mình đặt tên là helloworld.

Mở Terminal (giao diện dòng lệnh) ra gõ những dòng lệnh sau:

$mkdir helloworld
$cd helloworld

Chạy lệnh npm init để tạo ra file package.json trong folder helloworld. Xem thêm đặc tả package.json

$npm init

Khi chạy lệnh này nó sẽ hỏi một vài câu hỏi những câu trả lời của bạn sẽ được ghi vào nội dung của package.json. Đơn giản là cứ nhấn Enter. Mình còn có cơ hội chỉnh sữa lại sau.

Tiếp đến là install Express, chạy lệnh sau:

$npm install express --save

Đợi một vài phút để npm kéo module về.

Chạy lệnh sau để tạo file index.js

$touch index.js

Copy nội dung sau vào file index.js. Để tiện lập trình trong NodeJS, các bạn nên dùng một editor, mình dùng Visual Code của Microsoft, download ở đây.

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => res.send('Hello World!'))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

Cuối cùng, chạy lệnh sau để start cái web của bạn

$node index.js

Nếu thành công thì nó sẽ báo Example app listening on port 3000!

Mở browser vào địa chỉ http://localhost:3000/ Nếu nó xuất hiện chữ “Hello World” chúc mừng bạn đã thành công.

Tất cả các lệnh trên, các bạn có thể gom thành một lệnh duy nhất như sau:

$mkdir helloworld && cd helloworld && npm init -y && npm install express && touch index.js

Đây là cách cơ bản nhất, ngoài ra còn nhiều cách khác nữa. Thế giới NodeJS muôn hình vạn trạng!!!

Lịch sử hình thành Docker

Traditional Deployment

Xưa thật là xưa, mô hình máy chủ thường là máy chủ vật lý + hệ điều hành(OS) + application

Vấn đề gặp phải ở đây là lãng phí tài nguyên, một máy chủ chỉ cài được một OS, cho dù có ổ cứng khủng, ram khủng thì cũng không tận dụng hết lợi thế. Nếu để nhiều ứng dụng lên để tận dụng tài nguyên thì lúc đó lại phát sinh vấn đề về tương thích version library, runtime, version của OS…Không lẽ mỗi ứng dụng mua một server? chưa nói đến tiền, chỗ đâu để đặt server…? Vậy là cái khó ló cái khôn, thế giới công nghệ tiến hoá qua một thời kỳ mới “ảo hoá” (vitualization)

Virtualized Deployment

Cũng là xưa nhưng chưa xưa lắm, công nghệ ảo hoá ra đời, với công nghệ này, trên một máy chủ vật lý mình có thể tạo được nhiều máy ảo, các máy ảo này chạy độc lập, có thể cài đặt nhiều hệ điều hành khác nhau trên cùng một máy vật lý, tận dụng tài nguyên đã tốt hơn, giải quyết được những vấn đề nan giải của mô hình Traditional Deployment nhưng lúc này lại nảy sinh những yêu cầu mới để kịp với thời đại mới: tận dụng tài nguyên tốt hơn nữa, triển khai nhanh hơn…

  • Khi chạy máy ảo, bạn phải cung cấp “cứng” ổ cứng cũng như ram cho máy ảo đó, bật máy ảo lên để đó không làm gì thì máy thật cũng phải phân phát tài nguyên.
  • Việc khởi động, shutdown khá lâu, có thể lên tới hàng phút.

Những tên tuổi đại diện cho mô hình này: Vitualbox, VMware, Virtual Server. Nổi bật nhất là VMware trong lĩnh vực này.

  • Nếu ai đã từng khi triển khai một dự án run dưới local chạy demo thì ngon vãi nhưng khi deploy lên server thì sập vỡ mặt thì đã đến lúc nghỉ đến một bước tiến hoá mới containerization.
  • Nếu ai đã từng phải mất hàng ngày trời để setup môi trường DEV, SIT, UAT, PRD thì cũng đã đến lúc nghỉ đến một bước tiến hoá mới containerization.

Container Deployment

Ngày nảy ngày nay, người ta sinh ra công nghệ containerlization. Ở bước tiến hóa này, trên một máy chủ vật lý, ta sẽ sinh ra được nhiều “máy con” (giống với công nghệ ảo hóa vitualization), nhưng tốt hơn ở chỗ là các “máy con” này đều dùng chung phần nhân (OS kernel) của máy mẹ (host OS) và chia sẻ với nhau tài nguyên máy mẹ. Bên cạnh đó, nó giúp:

  • Tạo ra một môi trường chứa “mọi thứ” mà application cần để có thể chạy được.
  • Không bị các yếu tố liên quan đến môi trường hệ thống làm ảnh hưởng tới.
  • Cũng như không làm ảnh hưởng tới các phần còn lại của hệ thống.

Những tên tuổi đại diện cho mô hình này: Docker, rkt, RXD,… Nổi bật nhất là Docker trong lĩnh vực này.

Quá trình tiến hoá

Cài đặt Node.js

Để cài đặt Node bạn hãy vào trang https://nodejs.org/en/download/ tìm phiên bản thích hợp với hệ điều hành của bạn và cài đặt như ứng dụng bình thường

Nâng cao hơn 1 chút bạn có thể cài đặt nodejs qua thư viện nvm https://github.com/creationix/nvm . Thư viện này giúp bạn cài đặt và quản lý nhiều phiên bản nodejs trên cùng 1 máy . Với người dùng window bạn có thể dùng nvm-windows https://github.com/coreybutler/nvm-windows

Nếu cài đặt nodejs qua nvm bạn có thể tương tác dễ dàng qua CLI. Từ khi tổ chức quản lý Nodejs được thành lập vào năm ngoài với sự tham gia của Linux Foudation, nodejs bắt đầu có kế hoạch ra mắt rõ ràng. Trong kế hoạch đó các bạn sẽ thấy có 2 phiên bản nodejs : LTS và current . Phiên bản LTS là phiên bản hướng đến độ ổn định cao , ít cập nhật các tính năng mới es6 , chỉ tập trung vào sửa lỗi bảo mật cũng như tối ưu hệ thống. Hiện nay (thời điểm viết bài này) phiên bản LTS dừng ở bản 8.12.0. Phiên bản current hay còn gọi là phiên bản experimental luôn được cập nhật liên tục tính năng mới – tốc độ nâng cấp kinh hồn luôn 😐

Docker là gì?

alt text

Định nghĩa Docker

Nó là một công cụ tạo môi trường được “đóng gói” (còn gọi là Container) trên máy tính mà không làm tác động tới môi trường hiện tại của máy, môi trường trong Docker sẽ chạy độc lập. Xem thêm lịch sử hình thành Container

Một số khái niệm
– Docker images : Mỗi khi bạn muốn chạy ứng dụng Docker là thì bạn cần một cái image, cái image này có thể là HĐH Centos hoặc Linux, đã cài sẵn các ứng dụng PHP, Nginx

– Docker registries : Là kho chứa images. Người dùng có thể tạo ra các images của mình và tải lên bất kỳ đâu, miễn là người khác có thấy được, Hầu nết mình thường lên đây tham khảo https://hub.docker.com/

– Docker container : hoạt động giống như một thư mục (directory), chứa tất cả những thứ cần thiết để một ứng dụng có thể chạy được. Mỗi một docker container được tạo ra từ một docker image.

– Dockerfile : là một file chứa tập hợp các lệnh để Docker có thể đọc và thực hiện để đóng gói một image theo yêu cầu người dùng, chúng ta thường làm việc với tập tin này nhất

Khác biệt với máy ảo

Điểm khác biệt chính là các containers sử dụng chung kernel với Host OS nên các thao tác bật, tắt rất nhẹ nhàng, nhanh chóng. Do nó sử dụng chung nhân Linux nên rất có sự khác biệt so với dùng máy ảo Virtuhost

Các lệnh căn bản

  • Pull một image từ Docker Hub
    docker pull {image_name}
  • Liệt kê các images hiện có
    docker images
  • Xóa một image
    docker rmi {image_id/name}
  • Liệt kê các container đang chạy
    docker ps
    docker ps -a #Liệt kê các container đã tắt
  • Xóa một container
    docker rm -f {container_id/name}
  • Đổi tên một container
    docker rename {old_container_name} {new_container_name}
  • Khởi động một container
    docker start {new_container_name}
    docker exec -it {new_container_name} /bin/bash
  • Tạo mới một container, đồng thời khởi động với tùy chọn cổng và volume
    docker run --name {container_name} -p {host_port}:{container_port} -v {/host_path}:{/container_path} -it {image_name} /bin/bash
  • Xem các thay đổi trên container
    docker diff {container_name}
  • Commit các thay đổi trên container và image
    docker commit -m "message" {container_name} {image_name}
  • Save image thành file .tar
    docker save {image_name} > {/host_path/new_image.tar}
  • Tạo một image mới từ file .tar
    cat musashi.tar | docker import - {new_image_name}:latest
  • Xem lịch sử các commit trên image
    docker history {image_name}
  • Khôi phục lại images từ IMAGE_ID
    docker tag {iamge_id} {image_new_name}:{tag}
  • Build một image từ container
    docker build -t {container_name} .
    Dấu . ở đây ám chỉ Dockerfile đang nằm trong thư mục hiện tại.