# 前言

通常 Vue 部屬都是先打包成靜態網頁再部屬到 web 服務器上,但如此無法做到程式碼上傳版控後自動部屬,因為上傳的是原始碼,不是打包後的靜態網頁。

所以 Vue 搭配 Docker 時,有種作法是把原始碼直接直接 build 成執行 npm run dev 的 docker image 後放在 server 執行。

這種作法產生的 docker image 很大,枉費還用 Vue

# 縮減方式

使用 Multi-stage builds,在第一個 stage build 出靜態網頁,複製到第二個 stage 跟 web service 打包成 image。

假設原本 Dockerfiler 如下

fat Dockerfile
FROM node:18-slim
COPY . .
RUN npm install --production=false
EXPOSE 5173
CMD ["npm","run","dev"]

加上第二個 stage,並且使用 thttpd 作為靜態網頁的 web service

slim Dockerfile
# 第一個 stage
FROM node:18-slim AS builder
COPY . .
RUN npm install --production=false
# build static html 檔案,檔案會產生在 /dist 內
RUN npm run build
# 第二個 stage
FROM alpine
# 安裝 thttpd
RUN apk update && apk upgrade && apk add --no-cache thttpd
# 複製第一個 stage 產生的 static html 到 /front
COPY --from=builder /dist /front
EXPOSE 5173
# container 啟動時執行 thttpd
CMD ["thttpd", "-D", "-h", "0.0.0.0", "-p", "5173", "-d", "/front", "-l", "-", "-M", "60"]

# 比較

Docker image 大小
修改前 504MB
修改後 11.1MB