对 React.js 应用程序进行 Docker 化

2025-06-10

对 React.js 应用程序进行 Docker 化

在本文中,我们将对一个 React 应用程序进行 docker 化。我们将设置 Docker 的自动重新加载功能,用于开发环境的设置,并针对生产部署优化多阶段 docker 构建。我们甚至可以使用相同的流程对 Next.js 或 Gatsby 静态构建进行 docker 化。

使用 Docker 有很多优势。目前,Docker 已成为容器化应用程序的事实标准。使用 Docker 构建、打包、共享和发布应用程序非常便捷。由于 Docker 镜像具有可移植性,因此可以轻松地将应用程序部署到任何现代云提供商。

初始化 React 应用程序

让我们从创建一个 React 应用程序开始。您可以使用现有的 React 项目。在本篇博文中,我将使用 创建一个全新的 React 应用程序create-react-app

$ npx create-react-app react-docker
Enter fullscreen mode Exit fullscreen mode

这里我创建了一个名为 的新 React 应用react-docker。让我们通过npm start在项目目录中运行命令来验证该应用。

$ npm start
Enter fullscreen mode Exit fullscreen mode

它将启动应用程序,我们可以通过在浏览器中访问http://localhost:3000来验证。应用程序应该正在运行。

编写 Dockerfile。

现在让我们为 React 应用程序创建一个 Docker 镜像。我们需要一个 Dockerfile 来创建 Docker 镜像。让我们Dockerfile在 React 应用程序的根目录中创建一个名为的文件。

Dockerfile

FROM node:14-alpine

WORKDIR /app

COPY package.json ./

COPY yarn.lock ./

RUN yarn install --frozen-lockfile

COPY . .

EXPOSE 3000

CMD ["npm", "start"]
Enter fullscreen mode Exit fullscreen mode

这里我们使用 Node v14 Alpine 作为基础镜像来构建和运行应用程序。我们运行的npm start命令是默认命令,它将运行 React 开发服务器。我们还需要.dockerignore防止node_modules其他不需要的文件被复制到 Docker 镜像中。

.dockerignore

node_modules
npm-debug.log
Dockerfile
.dockerignore
Enter fullscreen mode Exit fullscreen mode

让我们通过运行命令从 Dockerfile 构建 Docker 镜像docker build。这里我们用 name 标记它react-docker

$ docker build -t react-docker .
Enter fullscreen mode Exit fullscreen mode

构建完docker镜像后,我们可以通过运行命令来验证镜像docker images。我们可以看到一个名为 的镜像react-docker被创建了。

$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
react-docker        latest              6b782301e271        2 minutes ago       438MB
Enter fullscreen mode Exit fullscreen mode

我们可以使用以下命令运行 Docker 镜像。这里我们将系统端口 3000 映射到 Docker 容器端口 3000。我们可以通过访问http://localhost:3000docker run验证应用程序是否正在运行。

$ docker run -p 3000:3000 react-docker
Enter fullscreen mode Exit fullscreen mode

添加 Docker Compose

React 应用程序在 docker 容器中运行良好,但每次对源文件进行任何更改时,我们都需要构建并运行 docker 容器,因为自动重新加载功能在这种设置下无法正常工作。我们需要将本地文件夹挂载src到 docker 容器src文件夹,这样每次在src文件夹内进行任何更改时,它都会根据代码更改自动重新加载页面。

我们将文件添加docker-compose.yml到项目的根目录,以将本地src文件夹挂载到/app/src容器的文件夹中。

docker-compose.yml

version: "3"

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./src:/app/src
    ports:
      - "3000:3000"
Enter fullscreen mode Exit fullscreen mode

运行docker-compose up命令启动容器。React 开发服务器将在容器内运行并监视该src文件夹。

$ docker-compose up
Enter fullscreen mode Exit fullscreen mode

由于此 Docker 镜像未经优化且内部运行着开发服务器,我们无法将其发布到生产环境。让我们重命名镜像DockerfileDockerfile.dev更新docker-compose.yaml文件以使用该Dockerfile.dev文件。我们将使用 docker-compose 和该Dockerfile.dev文件进行开发。我们将为生产环境构建创建一个新的 Dockerfile。

$ mv Dockerfile Dockerfile.dev
Enter fullscreen mode Exit fullscreen mode

docker-compose.yml

version: "3"

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - ./src:/app/src
    ports:
      - "8000:8000"
Enter fullscreen mode Exit fullscreen mode

添加生产 Dockerfile

yarn build让我们首先通过运行命令来构建生产应用程序,以验证 React 应用程序生产配置。

$ yarn build
Enter fullscreen mode Exit fullscreen mode

我们可以通过在本地运行来验证生产版本。我用它serve来提供build文件夹文件。

$ npx serve -s build
Enter fullscreen mode Exit fullscreen mode

在本地验证服务器后,我们可以为生产环境创建一个新的 Dockerfile。我们将使用多阶段构建来创建 Docker 镜像。一个阶段用于构建生产环境文件,另一个阶段用于提供这些文件。

Dockerfile

FROM node:14-alpine AS builder
WORKDIR /app
COPY package.json ./
COPY yarn.lock ./
RUN yarn install --frozen-lockfile
COPY . .
RUN yarn build

FROM nginx:1.19-alpine AS server
COPY --from=builder ./app/build /usr/share/nginx/html
Enter fullscreen mode Exit fullscreen mode

这个builder阶段与之前的 Dockerfile 几乎相同。npm start我们不是在这里运行命令,而是运行yarn build构建生产文件的命令。

我们将使用Nginx它来提供文件服务。它将创建一个非常轻量级的镜像。在构建阶段,我们需要将build文件夹中的文件复制到该/usr/share/nginx/html文件夹​​。Nginx Docker 镜像使用此文件夹来提供内容。Nginx Docker 镜像将使用指定的端口80来提供文件服务,并自动公开该端口。

让我们通过运行命令再次构建图像​​,docker build并通过运行命令验证图像是否已构建docker images

$ docker build -t react-docker .
Enter fullscreen mode Exit fullscreen mode
$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
react-docker        latest              5f885aeca09e        7 seconds ago       23.1MB
Enter fullscreen mode Exit fullscreen mode

生产环境的 Docker 镜像比开发环境的镜像要小得多。让我们用以下docker run命令运行 Docker 镜像。这里我们将主机3000端口映射到容器的端口。80

docker run -p 3000:80 react-docker
Enter fullscreen mode Exit fullscreen mode

应用程序应该可以在http://localhost:3000上正常运行。现在让我们验证一下客户端路由是否正常工作。为此,我们需要react-router-dom在应用程序中安装。

$ yarn add react-router-dom
Enter fullscreen mode Exit fullscreen mode

我们还需要添加一些路由和链接来验证。我只是从react-router 官网复制了示例来测试。

import React from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/users">Users</Link>
            </li>
          </ul>
        </nav>
        <Switch>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/users">
            <Users />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

function Home() {
  return <h2>Home</h2>;
}

function About() {
  return <h2>About</h2>;
}

function Users() {
  return <h2>Users</h2>;
}
Enter fullscreen mode Exit fullscreen mode

让我们通过运行开发服务器来验证本地设置,访问网页并单击每个链接并刷新页面。

$ npm start
Enter fullscreen mode Exit fullscreen mode

该应用程序在本地开发服务器上应该可以正常工作。现在尝试使用 docker-compose 进行同样的操作。首先,我们需要重新构建镜像,因为自动重新加载仅适用于src文件夹,因为我们只挂载了该文件夹。对于文件夹之外的更改src,我们需要使用命令重新构建镜像docker-compose build

$ docker-compose build
$ docker-compose up
Enter fullscreen mode Exit fullscreen mode

现在让我们用生产环境的docker build尝试同样的事情。首先,我们需要构建docker镜像并再次运行该镜像。

docker build -t react-docker .
docker run -p 3000:80 react-docker
Enter fullscreen mode Exit fullscreen mode

直接访问索引以外的页面应该会抛出 404 错误。此处的 React 应用是单页应用。因此,路由是在客户端使用 JavaScript 进行的。当我们访问任何路由时,它首先会访问 Nginx 服务器并尝试在那里查找文件,如果找不到文件,就会抛出 404 错误。

我们需要将自定义的 Nginx 配置传递给 docker 镜像。我们将etc在项目的根目录中创建一个文件夹,并nginx.conf在其中创建一个文件。

etc/nginx.conf

server {
    listen   80;
    listen   [::]:80 default ipv6only=on;

    root /usr/share/nginx/html;
    index index.html;

    server_tokens  off;
    server_name _;

    gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 0;
    gzip_types text/plain application/javascript text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype;

    location / {
        try_files $uri /index.html;
    }
}
Enter fullscreen mode Exit fullscreen mode

这里我们配置了 Nginx,/index.html当无法找到路由时,它会回退到原来的路由。我们还启用了内容的 gzip 压缩。

我们需要将自定义的 Nginx 配置文件复制到该/etc/nginx/conf.d文件夹​​。Ngnix 将自动读取该文件夹中的所有配置。

FROM node:14-alpine AS builder
WORKDIR /app
COPY package.json ./
COPY yarn.lock ./
RUN yarn install --frozen-lockfile
COPY . .
RUN yarn build

FROM nginx:1.19-alpine AS server
COPY ./etc/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder ./app/build /usr/share/nginx/html
Enter fullscreen mode Exit fullscreen mode

复制自定义 Nginx 配置文件后,我们需要再次构建并运行 docker 镜像。

$ docker build -t react-docker .
$ docker run -p 3000:80 react-docker
Enter fullscreen mode Exit fullscreen mode

访问所有路线并刷新页面应该可以正常工作。

本教程的所有源代码均可在GitHub上找到。

对于dockerizing node后端应用程序,请阅读其他博客文章

鏂囩珷鏉ユ簮锛�https://dev.to/rsbh/dockerizing-a-react-js-app-1ca3
PREV
TryHackMe | 搜索技巧 | RSCyber​​Tech 1️⃣ 任务 1 - 简介 2️⃣ 任务 2 - 搜索结果评估 3️⃣ 任务 3 - 搜索引擎 4️⃣ 任务 4 - 专业搜索引擎 5️⃣ 任务 5 - 漏洞和利用 6️⃣ 任务 6 - 技术文档 7️⃣ 任务 7 - 社交媒体 8️⃣ 任务 8 - 结论
NEXT
一个很酷的 Python 新进度条!