Docker 化 React 应用
在创建 ReactJS 应用时,你可能无需过多考虑如何部署它们。ReactJS 应用可以轻松地打包在一个文件夹中,其中包含纯 HTML、CSS 和 JavaScript 文件。只需将其上传到 S3 Bucket、托管在Github Pages上,甚至集成Netlify或Zeit等优秀服务即可实现快速自动化部署。
但这周,我的任务是将一个用create-react-app创建的 React 应用部署到子域名下的 VPS 上。我不想使用老旧的 FTP,而是想为我的应用创建一个自动化的 Docker 容器,这样我就可以在任何地方部署,而无需进行太多配置。
我创建了一个演示应用程序,其中包含了本文详细介绍的所有配置。代码可在此处获取。
准备我们的Dockerfile
我们首先在Dockerfile
项目根文件夹中创建一个包含以下内容的文件:
# This image won't be shipped with our final container
# we only use it to compile our app.
FROM node:12.2.0-alpine as build
ENV PATH /app/node_modules/.bin:$PATH
WORKDIR /app
COPY . /app
RUN npm install
RUN npm run build
# production image using nginx and including our
# compiled app only. This is called multi-stage builds
FROM nginx:1.16.0-alpine
COPY --from=build /app/build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/conf.d
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
在上面的代码片段中,我们使用了一项名为多阶段构建的功能。它需要 Docker 17.05 或更高版本,但此功能的好处非常巨大,我将在下文中进行解释。在脚本的前半部分,我们基于node:12.2.0-alpine
一个包含 Node 的非常小的 Linux 镜像来构建 Docker 镜像。现在请注意as build
第一行末尾的 。这将创建一个包含依赖项的中间镜像,可以在构建后丢弃。此后不久,我们将安装 React 应用程序中的所有依赖项npm install
,然后执行npm run build
来编译针对生产进行优化的 React 应用程序。
在代码的后半部分,我们基于它创建了一个新的 Docker 镜像,nginx:1.16.0-alpine
它也是一个包含nginx 的小型 Linux 系统,nginx 是一个高性能的 Web 服务器,用于服务我们的 React 应用。我们使用命令COPY
从之前的镜像中提取内容build
并将其复制到 中/usr/share/nginx/html
。接下来,我们删除默认的 nginx 配置文件,并在其下添加自定义配置,nginx/nginx.conf
内容如下:
# To support react-router, we must configure nginx
# to route the user to the index.html file for all initial requests
# e.g. landing on /users/1 should render index.html
# then React takes care of mouting the correct routes
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
此配置对于使用React Router 的应用程序非常重要。每当您共享指向 React 应用程序的链接时,比如说,指向 的链接/users/1/profile
,此链接都会告诉浏览器从 Web 服务器请求此路径。如果 Web 服务器配置不正确,我们的 React 应用程序将无法呈现包含我们的 React 应用程序的初始index.html文件。
使用我们的自定义配置,我们告诉 nginx 将所有请求路由到根文件夹/usr/share/nginx/html
,该文件夹是我们之前在镜像构建期间复制 React 应用程序的目录。我们不应忘记 React 应用程序是单页应用程序,这意味着在第一个请求时只有一个页面需要呈现,其余工作由浏览器上的 React 负责。
构建我们的 Docker 镜像
我们已经拥有构建 Docker 镜像所需的所有代码。让我们执行 Docker 命令来构建它:
# Make sure to be on the same folder of your React app
# replace 'my-react-app' with whatever name you find appropriate
# this is the image tag you will push to your Docker registry
docker build -t my-react-app .
当图像构建完成后,让我们使用以下命令检查刚刚生成的图像的大小:
# List all the images on your machine
docker images
# You should see something like this:
REPOSITORY TAG IMAGE ID CREATED SIZE
my-react-app latest c35c322d4c37 20 seconds ago 22.5MB
好了,我们的 Docker 镜像已经准备好上传到 Docker Registry 了。这个镜像的一个特点是它只有 22.5MB。这对于部署来说非常有利,因为小镜像可以让自动化流水线在下载、构建和上传镜像时运行得更快。
使用 docker-compose 运行我们的 React 应用
我们现在需要的是如何运行这个 Docker 镜像。为了在本地测试,我们创建一个名为的文件,docker-compose.yml
内容如下:
version: '3.7'
services:
my_react_app:
build:
context: .
ports:
- '8000:80'
如果镜像不存在, Docker Compose将负责构建镜像,并将本地机器的端口绑定到容器上的8000
端口。80
让我们使用以下命令启动我们的容器:
docker-compose up
现在打开浏览器localhost:8000
,检查我们的 React 应用是否正在运行。你应该看到类似这样的内容:
结论
使用 Docker 运行 React 应用可能并非最佳部署方式,但如果您需要像我一样运行 Docker,它可以非常简单高效。这为许多自动化流水线打开了大门,您可以在项目中连接这些流水线,例如Github Actions或Gitlab CI/CD,从而实现部署流程的自动化。您可以在此处找到本文的代码。
文章来源:https://dev.to/bpaulino0/dockerizing-react-apps-591l