D

Docker 化 React 应用

2025-06-04

Docker 化 React 应用

在创建 ReactJS 应用时,你可能无需过多考虑如何部署它们。ReactJS 应用可以轻松地打包在一个文件夹中,其中包含纯 HTML、CSS 和 JavaScript 文件。只需将其上传到 S3 Bucket、托管在Github Pages上,甚至集成NetlifyZeit等优秀服务即可实现快速自动化部署。

但这周,我的任务是将一个用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;"]
Enter fullscreen mode Exit fullscreen mode

在上面的代码片段中,我们使用了一项名为多阶段构建的功能。它需要 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;
  }

}
Enter fullscreen mode Exit fullscreen mode

此配置对于使用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 .
Enter fullscreen mode Exit fullscreen mode

当图像构建完成后,让我们使用以下命令检查刚刚生成的图像的大小:

# 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
Enter fullscreen mode Exit fullscreen mode

好了,我们的 Docker 镜像已经准备好上传到 Docker Registry 了。这个镜像的一个特点是它只有 22.5MB。这对于部署来说非常有利,因为小镜像可以让自动化流水线在下载、构建和上传镜像时运行得更快。

使用 docker-compose 运行我们的 React 应用

我们现在需要的是如何运行这个 Docker 镜像。为了在本地测试,我们创建一个名为的文件,docker-compose.yml内容如下:

version: '3.7'

services:
  my_react_app:
    build:
      context: .
    ports:
      - '8000:80'
Enter fullscreen mode Exit fullscreen mode

如果镜像不存在, Docker Compose将负责构建镜像,并将本地机器的端口绑定到容器上的8000端口。80

让我们使用以下命令启动我们的容器:

docker-compose up
Enter fullscreen mode Exit fullscreen mode

现在打开浏览器localhost:8000,检查我们的 React 应用是否正在运行。你应该看到类似这样的内容:

在 Docker 上运行的 React JS 应用

结论

使用 Docker 运行 React 应用可能并非最佳部署方式,但如果您需要像我一样运行 Docker,它可以非常简单高效。这为许多自动化流水线打开了大门,您可以在项目中连接这些流水线,例如Github ActionsGitlab CI/CD,从而实现部署流程的自动化。您可以在此处找到本文的代码。

文章来源:https://dev.to/bpaulino0/dockerizing-react-apps-591l
PREV
在我的 Web 开发中有用的 JS 库
NEXT
样式化组件和 TypeScript - 😍