# 如何在 docker 上啟動一個 mern stack web app ###### tags: `docker` `deploy` ## 先決條件 * 需要先安裝 [docker](https://www.docker.com/products/docker-desktop) 在安裝完成後在終端機執行 ``` docker ``` 應該要看到有顯示類似下面的東西 ``` 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 應該要改成這樣 ``` mongodb://localhost:27017 => mongodb://mongo:27017/online-compile ``` 其中 mongo 是你 mongo image 的名稱 註:`mongodb image 名稱` ## 將 app 部署到 docker 上 * 首先在專案根目錄建立一個名為 Dockerfile 的檔案,並在裡面輸入以下內容 ``` # 指定 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 的檔案 ``` yml 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 上的東西 ``` node_modules npm-debug.log ``` * 最後就可以在終端機執行 ``` docker-compose up ``` 這樣就會看到一堆東西在跑,等到跑完之後就可以打開瀏覽器去 localhost:80 看看有沒有成功了 * 如果要關掉的話執行 ``` docker-compose down ``` ## 基本指令 * `docker images` 顯示本機所有已安裝的 images * `docker image rm [image id] -f` 刪除 image by id * `docker ps` 顯示所有 container