Dockerizing Node.js web app



  • Trong bài viết này mình sẽ chỉ cho các bạn cách đưa một ứng dụng node.js vào một docker container. Tuy nhiên hướng dẫn chỉ cho môi trường develop, không phải cho môi trường product. Ngoài ra trong đây còn mô tả về cài đặt docker cũng như cấu trúc cơ bản của một ứng dụng Node.js

    Docker ra đời cho giải pháp đóng gói, vận chuyển và triển khai ứng dụng hết sức nhanh chóng và đơn giản. Với Docker, các thành viên trong team (cũng như với người muốn trải nghiệm thử project) sẽ triển khai ngay được môi trường ứng dụng mà không phải mất nhiều thời gian, công việc của SysAdmin cũng nhẹ nhàng hơn.

    Mình sẽ hướng dẫn cách đóng gói build image docker cho ứng dụng Nodejs một cách cơ bản nhất.

    Tạo Node.js app

    Mỗi ứng dụng viết bằng Nodejs bắt buộc đều phải có package.json, lưu thông tin về các gói cần thiết, nhiều thông tin khác về tên, phiên bản, ...

    {
      "name": "docker_web_app",
      "version": "1.0.0",
      "description": "Node.js on Docker",
      "author": "First Last <[email protected]>",
      "main": "server.js",
      "scripts": {
        "start": "node server.js"
      },
      "dependencies": {
        "express": "^4.16.1"
      }
    }
    

    Với file package.json, chạy npm install. Nếu bạn sử dụng npm version >= 5.0, file package-lock.json được tạo ra sẽ được copy vào Docker image
    Tiếp theo, tạo một server.js file để định nghĩa ứng dụng sử dung Express.js framework:

    'use strict';
    
    const express = require('express');
    
    // Constants
    const PORT = 8080;
    const HOST = '0.0.0.0';
    
    // App
    const app = express();
    app.get('/', (req, res) => {
      res.send('Hello world\n');
    });
    
    app.listen(PORT, HOST);
    console.log(`Running on http://${HOST}:${PORT}`);
    

    Bước tiếp theo, chúng ta học cách chạy một ứng dụng bên trong một docker container sử dụng docker image. Trước tiên, ta cần build một docker image của ứng dụng.

    Tạo Dockerfile

    Tạo một file trống Dockerfile và mở trong editor:

    touch Dockerfile
    Mở file Dockerfile bằng Editor. Đầu tiên, cần định nghĩa ứng dụng sẽ build trên image nào. Danh sách các image Nodejs có tại đây.

    FROM node:carbon

    Tạo thư mục chứa toàn bộ code ứng dụng ở trong image, đây sẽ là thư mụn làm việc cho ứng dụng của bạn.

    # Create app directory
    WORKDIR /usr/src/app
    

    Image trên sẽ có sẵn Node.js và Nmp, vì vậy, chúng ta chỉ cần cài ứng dụng một cách độc lập sử dung npm binanry. Chú ý rằng nếu bạn sử dụng npm version <= 4. thì file package-lock.json sẽ không được sinh ra.

    # Install app dependencies
    # A wildcard is used to ensure both package.json AND package-lock.json are copied
    # where available ([email protected]+)
    COPY package*.json ./
    
    RUN npm install
    # If you are building your code for production
    # RUN npm install --only=production
    

    Thay vì copy toàn bộ thư mục, ta chỉ copy file package.json. Bundle source code ứng dụng trong docker image :

    # Bundle app source
    COPY . .
    

    sử dụng EXPOSE để mở PORT 8080 trên Container, thay 8080 bằng port ứng dụng của bạn:

    EXPOSE 8080
    

    Cuối cùng quan trọng nhất là lệnh để khởi động ứng dụng Nodejs, lệnh CMD sẽ chạy npm start, cũng như start node app.js được định nghĩa trong package.json

    CMD [ "npm", "start" ]
    

    Cuối cùng được Dockerfile hoàn chỉnh như thế này:

    FROM node:carbon
    
    # Create app directory
    WORKDIR /usr/src/app
    
    # Install app dependencies
    # A wildcard is used to ensure both package.json AND package-lock.json are copied
    # where available ([email protected]+)
    COPY package*.json ./
    
    RUN npm install
    # If you are building your code for production
    # RUN npm install --only=production
    
    # Bundle app source
    COPY . .
    
    EXPOSE 8080
    CMD [ "npm", "start" ]
    

    .dockerignore file

    Tạo .dockerignore file trong cùng thư mục của Dockerfile với nội dung:

    node_modules
    npm-debug.log
    

    Build image

    Cd đến thư mục chứa Dockerfile, chạy lệnh bên dưới để build image. --tag dùng để đặt tên cho ảnh dễ nhớ, nhớ đừng bỏ xót dấu chấm ở cuối.

    $ docker build -t <your username>/node-web-app .
    

    Sau khi build thành công, xem lại danh sách Docker image bằng:

    $ docker images
    
    # Example
    REPOSITORY                      TAG        ID              CREATED
    node                            carbon     1934b0b038d1    5 days ago
    <your username>/node-web-app    latest     d64d3505b0d2    1 minute ago
    

    Khởi chạy image

    Run docker image với tùy chọn -d sẽ chạy container dưới background, tùy chọn -p sẽ mapping port của máy thật (public) với port của container (private)

    $ docker run -p 49160:8080 -d <your username>/node-web-app
    

    Xem danh sách các container và log đang chạy:

    # Get container ID
    $ docker ps
    
    # Print app output
    $ docker logs <container id>
    
    # Example
    Running on http://localhost:8080
    

    Nếu cần truy cập vào container đang chạy, sử dụng:

    # Enter the container
    $ docker exec -it <container id> /bin/bash
    

    Test

    $ docker ps
    
    # Example
    ID            IMAGE                                COMMAND    ...   PORTS
    ecce33b30ebf  <your username>/node-web-app:latest  npm start  ...   49160->8080
    

    Trong ví dụ trên, docker map cổng 8080 của container ra cổng 49160 của máy bạn
    Test: truy cập thử ứng dụng bằng trình duyệt: http://localhost:49160

    Bây giờ bạn có thể gọi ứng dụng bằng curl (cài đặt: sudo apt-get install curl):

    $ curl -i localhost:49160
    
    HTTP/1.1 200 OK
    X-Powered-By: Express
    Content-Type: text/html; charset=utf-8
    Content-Length: 12
    ETag: W/"c-M6tWOb/Y57lesdjQuHeB1P/qTV0"
    Date: Mon, 13 Nov 2017 20:53:59 GMT
    Connection: keep-alive
    
    Hello world
    

    Chúc các bạn chạy được ứng dụng Node.js đơn giản trên Docker.
    Nguồn: Viblo


Hãy đăng nhập để trả lời
 

Có vẻ như bạn đã mất kết nối tới LaptrinhX, vui lòng đợi một lúc để chúng tôi thử kết nối lại.