有個需求是要將 React 專案 Deploy 在公司開發用的 Docker 上,簡單寫個筆記,以後有類似的需求可以直接複製貼上使用
新建 React 專案
現在主流大致上就是以 【Create React App】 或 【Vite】 來建置,這篇文章的範例是使用 Vite,如果是使用 Create React App 麻煩自行做對應的調整
新建測試專案 test-vite-docker,執行指令
npm create vite@latest
大家很熟的東西就不再多說
Docker 設定
新增 Dockerfile
在新建的 React 專案目錄下新增一支 Dockerfile 檔案,內容如下
FROM node:20.11-alpine as build
WORKDIR /app
COPY . /app
RUN npm install
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
簡單說明一下,這裏 node 用的版本是 20.11.0 LTS,如果需要用別的版本請自行更換,docker image 用的都是 alpline,其實我一直搞不懂差在哪裏,只知道檔案比較小,跑起來沒什麼問題就一直用下去了
docker 是使用 multi-stage builds 的語法,簡單說就是將拆成兩個 stage
- node stage:build react 專案
- nginx stage:將 node build 後的結果複製到 nginx,然後執行
multi-stage builds 的詳細說明,可參考官方文件【Multi-stage builds】
新增 .dockerignore
在 Dockerfile 同一個目錄下增加一支 .dockerignore 檔案,作用很像 git 的 .gitignore,在上傳 docker 時會忽略掉這些目錄和檔案,內容如下,可以自行新增或減少內容
build
dist
node_modules
package-lock.json
README.md
建立 Docker Image 檔案
範例 image 名稱叫做 test-vite-docker
docker build -t test-vite-docker .
建立 Docker Container 且執行
範例 container 名稱也叫 test-vite-docker,port 改成 8081
docker run --name test-vite-docker -p 8081:80 test-vite-docker
然後點選瀏覽器,port 用 8081 就可以看到測試網頁了
解決 Nginx 配置正確處理 Router 的 history 模式
不過 deploy 後有點問題,直接在瀏覽器點連結時會出現 404 (從首頁的連結點擊就會正常),同時記錄一下解決方法
在根目錄增加一支檔案 nginx.conf,內容如下:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
然後修改 Dockerfile,增加一行如下
FROM node:20.11-alpine as build
WORKDIR /app
COPY . /app
RUN npm install
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf # 增加這一行
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
重新建立 Docker Image 檔案和建立 Docker Container 且執行,問題解決