有个需求是要将 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 且执行,问题解决