後端容器化
前端容器化之後,接著準備進行後端的容器化。首先把寫死的 MongoDB 連線字串透過環境變數注入,修改 server/app.js
連線資料庫的部分成
mongoose.connect(process.env.MONGO_URI || `mongodb://localhost:27017/test`);
接著一樣新建 server/Dockerfile
FROM node:10
# 指定工作目錄為 /usr/src/app,接下来的指令全部在這個路徑下操作
WORKDIR /usr/src/app
# 將 package.json 複製到根目錄
COPY package*.json ./
# 安裝 npm 依賴
RUN npm install
# 複製全部程式內容
COPY . .
# 設定環境變數
ENV NODE_ENV=production
ENV MONGO_URI=mongodb://db:27017/test
ENV HOST=0.0.0.0
ENV PORT=3000
# 曝露出 3000 port
EXPOSE 3000
# 設定映像檔內執行的指令
CMD ["npm", "start"]
和前端一樣建立 server/.dockerignore
確定不會把 node_modules
給映射進容器裡
裡面也只有一行:
node_modules
Docker Compose
Docker Compose 可以讓我們很好的管理 docker 容器,只需要透過一個 YAML 檔就可以修改設定。
在專案的根目錄下建立(跟 client 和 server 兩個資料夾同層)docker-compose.yml
version: '3'
services:
db:
image: mongo
restart: always
api:
build: server
restart: always
ports:
- 3000:3000
nginx:
build: client
restart: always
ports:
- 8080:80
可以看到我們建立了三個 service
,對應到前面說的 db
、api
、nginx
- db:指定使用 mongo 映像檔,然後當服務意外停止則總是重啟
- api:映像檔透過
server
資料夾內來建立,對外 port 為3000:3000
- nginx:映像檔透過
client
資料夾內來建立,對外 port 為8080:80
,外部的 8080 port 會指向到內部 80 port
如果 docker-compose.yml 中的 service 使用 image 指定映像檔,則會去Docker Hub 上拉回指定的映像檔。若是使用
build
則會根據指定目錄下的Dockerfile
來建立映像檔。
接著就是測試的時間!打開 Docker 之後,在終端機輸入
docker-compose up --build
第一次執行會多花一些時間,因為先前提過的要從Docker Hub 上拉回指定的映像檔,如下圖
可以藉由
docker ps
來觀察目前所有的容器狀態,看起來沒問題的話就可以開啟 localhost:8080
來看看專案是不是跟原本一樣
MongoDB 身份驗證
在之前的設定中我們的 MongoDB 資料庫並沒定任何身份驗證,所以任何人只要能夠發送請求到資料庫都可以對資料庫做修改,這是一個可怕的資安問題!接著我們要來搞定 MongoDB 的身份驗證,增加系統的安全性
修改 MongoDB 連線設定
打開 server/app.js
,修改連線資料庫的部分成以下
ongoose.connect(process.env.MONGO_URI || `mongodb://localhost:27017/test`, {
useNewUrlParser: true,
useUnifiedTopology: true,
user: process.env.MONGO_USER,
pass: process.env.MONGO_PASSWORD,
});
這代表
- useNewUrlParser:使用新的 MongoDB 驅動 URL 解析器
- useUnifiedTopology:使用新的連線管理引擎,支持重新連線,這樣可以大大提升連線穩定性
- user:連線的使用者名稱,通過環境變數注入
- pass:連線使用的密碼,通過環境變數注入
Dockerfile 中注入環境變數
在 server/Dockerfile
中加入下面的環境變數:
ENV NODE_ENV=production
ENV MONGO_URI=mongodb://db:27017/admin
ENV MONGO_USER=mongoadmin
ENV MONGO_PASSWORD=secret
ENV HOST=0.0.0.0
ENV PORT=3000
可以發現一些不同的地方,調整了 MONGO_URI
,把預設的 test
換成 admin
,這是為了啟用驗證功能並且
使用 admin
作為 Authentication Database 的使用者。
設定 Docker Compose 預設密碼
接著在 docker-compose.yml
裡面幫 db
服務加入預設密碼的環境變數
db:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: mongoadmin
MONGO_INITDB_ROOT_PASSWORD: secret
測試
首先使用
docker-compose down --volumes
不只關閉了原本運行中的 docker 容器,還透過 --volumes
把原本的建立 MongoDB 的容器徹底刪除。若不這麼做,之後重啟容器會跳過初始化使用者的過程,這樣我們的驗證資料庫就沒辦法被建立,會複用之前的資料
接著重新啟動容器
docker-compose up --build
應該會看到網頁一切正常,不過資料庫已經有了驗證,不是「裸奔」的狀態了
留言
張貼留言