使用连接到 MongoDb 的 Node.js 后端对 React 应用程序进行 Docker 化

2025-05-28

使用连接到 MongoDb 的 Node.js 后端对 React 应用程序进行 Docker 化

亲爱的程序员们,大家好!欢迎阅读我关于Node.jsDocker系列的最后一篇技术文章。希望你喜欢!

问题:

我们已经在本系列的上一篇文章中了解了如何将 Docker 与 Node 和 Mongo 结合使用。为了完成我们的 MERN 堆栈应用程序,我们需要添加前端部分。在本例中,前端将使用 React 实现。让我们学习如何创建包含前端、后端、数据库的完整应用程序,并在 Docker 中运行所有内容!

1. 克隆后端 Node.js

在本系列的前几篇文章中,我们结合 Docker 使用 MongoDb 创建了一个 Node.js 应用。在本教程中,我们需要使用相同的项目。您可以从此处克隆源代码或运行以下命令:

git clone https://github.com/vguleaev/Express-Mongo-Docker-tutorial.git
Enter fullscreen mode Exit fullscreen mode

克隆完成后,将文件夹从test-mongo-app重命名为api。这将是我们的后端。

要测试一切正常,请打开api文件夹并运行npm install。依赖项安装完成后,让我们检查一切是否正常。🍾

docker-compose up
Enter fullscreen mode Exit fullscreen mode

此命令将使用我们的docker-compose.yml拉取 mongo 镜像并启动连接到 MongoDb 的 express 服务器。

如果一切正常,您应该在控制台中看到类似这样的内容:

web_1    | Listening on 8080
web_1    | MongoDb connected
Enter fullscreen mode Exit fullscreen mode

在浏览器中打开http://localhost:8080/users端点,你应该会得到一个空数组作为响应。这是正确的,因为我们的数据库目前完全是空的。

2. 创建 React 应用

现在该开发前端部分了。回到父目录并运行:

npm i create-react-app -g
create-react-app ui
Enter fullscreen mode Exit fullscreen mode

现在我们的文件夹结构应该是这样的:
...
═── / api
└── / ui
其中 api 是克隆的后端应用程序,ui 是新创建的 React 应用程序。

为了确保一切正常,让我们打开ui文件夹并启动 React 应用程序:

cd ui
npm start
Enter fullscreen mode Exit fullscreen mode

你应该可以在http://localhost:3000看到基本的 React 应用。🎈

3. Docker化React应用

ui文件夹中创建一个.dockeringore文件:

node_modules
.git
.gitignore
Enter fullscreen mode Exit fullscreen mode

(如果没有这个文件,我们的docker build命令将只是挂在 Windows 上。)

还在ui文件夹中创建一个Dockerfile文件

FROM node:8
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
COPY package*.json ./

RUN npm install --silent
# Copy app source code
COPY . .

#Expose port and start application
EXPOSE 3000
CMD ["npm", "start"]
Enter fullscreen mode Exit fullscreen mode

让我们测试一下 React 能否在 docker 中运行。首先,我们将构建一个带有 react:app 标签的镜像:

docker build -t react:app .
Enter fullscreen mode Exit fullscreen mode

现在运行我们标记的图像并使用相同的 docker 端口:

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

打开http://localhost:3000,你就会看到由 Docker 提供的 React 服务。👍

⚠️ 如果你像平常一样使用 Ctrl+C 关闭容器,容器不会停止运行。要停止容器运行,请执行docker ps以下命令。

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
06c982ce6ae9        react:app           "docker-entrypoint.s…"   12 days ago         Up About a minute   0.0.0.0:3000->3000/tcp   strange_montalcini
Enter fullscreen mode Exit fullscreen mode

然后选择所需的 ID 并停止容器。

docker stop 06c982ce6ae9
Enter fullscreen mode Exit fullscreen mode

4. 从 React 应用调用 API

打开ui文件夹并安装axios

cd ui
npm i axios
Enter fullscreen mode Exit fullscreen mode

我们将App稍微修改组件,添加一个按钮来创建用户并显示用户 ID 列表。我们将从Nodejs 应用调用/user-create/users GET 端点。

将其粘贴到 App.js 文件中:

import React, { Component } from 'react';
import logo from './logo.svg';
import axios from 'axios';
import './App.css';

const apiUrl = `http://localhost:8080`;

class App extends Component {
  state = {
    users: []
  };

  async createUser() {
    await axios.get(apiUrl + '/user-create');
    this.loadUsers();
  }

  async loadUsers() {
    const res = await axios.get(apiUrl + '/users');
    this.setState({
      users: res.data
    });
  }

  componentDidMount() {
    this.loadUsers();
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <button onClick={() => this.createUser()}>Create User</button>
          <p>Users list:</p>
          <ul>
            {this.state.users.map(user => (
              <li key={user._id}>id: {user._id}</li>
            ))}
          </ul>
        </header>
      </div>
    );
  }
}

export default App;
Enter fullscreen mode Exit fullscreen mode

由于前端运行在 3000 端口,而后端运行在 8080 端口,因此我们可能会遇到CORS问题。为了避免这个问题,请前往api项目并安装 cors 包。

npm i cors
Enter fullscreen mode Exit fullscreen mode

server.js然后在文件中使用它:

const express = require('express');
const app = express();
const connectDb = require('./src/connection');
const User = require('./src/User.model');
const cors = require('cors');

app.use(cors());
// ...
Enter fullscreen mode Exit fullscreen mode

5. 在 Docker 中同时运行 React 和 Node

最后一步!现在docker-compose.yml从目录api中删除,并在根文件夹中创建docker-compose.yml。粘贴以下内容:

version: '2'
services:
  ui:
    build: ./ui
    ports:
      - '3000:3000'
    depends_on:
      - api
  api:
    build: ./api
    ports:
      - '8080:8080'
    depends_on:
      - mongo
  mongo:
    image: mongo
    ports:
      - '27017:27017'

Enter fullscreen mode Exit fullscreen mode

我们的根文件夹结构现在如下所示:
...
═── / api
═── / ui
└── docker-compose.yml

我们有一个 docker-compose 文件,它描述了我们想要在 Docker 中运行哪些服务。在我们的例子中,有三个服务:ui、api 和mongo。🐋

每个服务都会Dockerfile在每个项目中使用 Docker 镜像创建。我们在 build 行中指定路径。(例如build: ./ui

对于mongo我们没有项目来构建图像,因为我们使用来自 docker hub的预定义图像。(例如image: mongo

我们还指定了端口和依赖项。在我们的例子中,第一个容器将在端口27017上启动mongo,因为 api 依赖于 mongo。第二个容器是api,在端口8080上启动,因为ui依赖于它。最后一个容器是ui ,它在端口3000上启动

最后,从根文件夹使用一个命令运行所有服务!🧙

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

打开http://localhost:3000/并点击按钮创建用户。打开开发者工具查看调用情况。现在,我们从 docker 运行前端和后端!

替代文本

6. 使用 React 生产构建

现在,我们用开发服务器启动 React 应用,这可能不是我们想要在生产环境中使用的。但我们可以轻松解决这个问题。

我们只需要修改我们的DockerfileUI项目。我们将启动生产版本并使用 nginx 服务器提供服务。将所有内容替换为以下内容:

# build environment
FROM node:12.2.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json /app/package.json
RUN npm install --silent
RUN npm install react-scripts@3.0.1 -g --silent
COPY . /app
RUN npm run build

# production environment
FROM nginx:1.16.0-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Enter fullscreen mode Exit fullscreen mode

由于我们现在暴露了端口 80,所以我们需要在 中将其从 3000 更改为 80 docker-compose.yml

  ui:
    build: ./ui
    ports:
      - '80:80'
    depends_on:
      - api
Enter fullscreen mode Exit fullscreen mode

现在再次运行 magic 命令来启动 docker 中的所有内容🔮

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

打开http://localhost/您应该会看到完全相同的工作应用程序,但现在 React 正在生产模式下运行。

源代码请见此处。尽情享用吧!

恭喜你成功将 React、Nodejs 和 Mongodb docker 化!🎉🎉🎉


🚀 如果你从那篇文章中读到了什么有趣的内容,请点赞并关注我,我会分享更多文章。谢谢你,亲爱的程序员!😏

文章来源:https://dev.to/vguleaev/dockerize-a-react-app-with-node-js-backend-connected-to-mongodb-10ai
PREV
软件开发的阴暗面 不断跟上新技术 项目经理和产品经理 不切实际的要求 不健康的薪酬竞争
NEXT
使用 VS Code Docker 化 Node.js 应用