0%

如何在 Docker 上啟動一個 mern stack web app

先決條件

  • 需要先安裝 docker
    在安裝完成後在終端機執行

    1
    docker

    應該要看到有顯示類似下面的東西

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Usage:  docker [OPTIONS] COMMAND

    A self-sufficient runtime for containers

    Options:
    --config string Location of client config files (default "/Users/den19980107/.docker")
    -c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with
    "docker context use")
    -D, --debug Enable debug mode
    -H, --host list Daemon socket(s) to connect to
    -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
    --tls Use TLS; implied by --tlsverify
    --tlscacert string Trust certs signed only by this CA (default "/Users/den19980107/.docker/ca.pem")
    --tlscert string Path to TLS certificate fil
  • 確定該 app run 的起來

  • 如果有用到 mongodb,monodb 的 url 不能用 localhost 應該要改成這樣

    1
    mongodb://localhost:27017 => mongodb://mongo:27017/online-compile

    其中 mongo 是你 mongo image 的名稱 註:mongodb image 名稱

將 app 部署到 docker 上

  • 首先在專案根目錄建立一個名為 Dockerfile 的檔案,並在裡面輸入以下內容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    # 指定 node 版本 建議用現在本機的版本避免出錯
    FROM node:8.4.0-alpine

    # 設定這個 app 在 docker 上的工作目錄
    WORKDIR /usr/src/app

    # 把 package.json 和 package.locl.json 複製到工作目錄中
    COPY package*.json ./

    # -- 如果有使用到 bcrypt 或是任何需要 node-pre-gyp 提前編譯的套件需輸入下面的指令 --
    # 需要先安裝 python 到 container 上 node 才有辦法用 node-pre-gyp 預先編譯 bcrypt
    RUN apk --no-cache add --virtual builds-deps build-base python
    # 再重新編譯 bcrypt
    RUN npm rebuild bcrypt --build-from-source
    # ------------------------------------------------------------------------

    # install npm 套件
    RUN npm install

    # 把專案內的東西全部拷貝進 docker 的工作目錄中
    COPY . .

    # 設定 app 要對外的 port 此範例是 port 5000
    EXPOSE 5000

    # 設定執行時要 run 的指令 這邊就看你平常是怎麼把你的專案 on 起來的就輸入哪個
    CMD npm run production
  • 再來一樣在專案目錄下建立一個名為 docker-compose.yml 的檔案

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    version: '2' # docker-compose 版本
    services: # 固定的不要改
    app: # 取你想取的名字代表這個 app
    container_name: docker-online-compile # 這個 app run 起來後的 container 名稱 也是任意取
    restart: always # 當出現問題壞掉時自動重啟
    build: . # build 全部的東西
    # 指定 app 佔用的口
    ports:
    #左邊的 80 是 docker run 起來後本機要輸入 localhost:80 才看得到 app
    #右邊得則是你 app 原本 on 的 port 要跟 Dockerfile 的 EXPOSE 一樣
    - '80:5000'
    # 表示你的 app 需要依賴於 mongo 這邊的 mongo 就是 (1) 所寫的名稱
    links:
    - mongo
    mongo: #(1)
    # mongodb 的 container 名稱
    #跟上面講的 [mongodb image 名稱] 一樣
    container_name: mongo

    # 因為我們不是自己安裝 mongodb
    # docker 會幫我們上網抓 mongo 的image下來
    # 那個 mongo image 的名稱就叫 mongo
    image: mongo
    ports: # mongo 的 port
    - '27017:27017'
  • 一樣在根目錄下新增一個 .dockerignore 的檔案,功能跟 gitignore 一樣過濾掉一些不想傳到 docker 上的東西

    1
    2
    node_modules
    npm-debug.log
  • 最後就可以在終端機執行

    1
    docker-compose up

    這樣就會看到一堆東西在跑,等到跑完之後就可以打開瀏覽器去 localhost:80 看看有沒有成功了

  • 如果要關掉的話執行

    1
    docker-compose down

    基本指令

  • docker images 顯示本機所有已安裝的 images

  • docker image rm [image id] -f 刪除 image by id

  • docker ps 顯示所有 container