使用连接到 MongoDb 的 Node.js 后端对 React 应用程序进行 Docker 化
亲爱的程序员们,大家好!欢迎阅读我关于Node.js和Docker系列的最后一篇技术文章。希望你喜欢!
问题:
我们已经在本系列的上一篇文章中了解了如何将 Docker 与 Node 和 Mongo 结合使用。为了完成我们的 MERN 堆栈应用程序,我们需要添加前端部分。在本例中,前端将使用 React 实现。让我们学习如何创建包含前端、后端、数据库的完整应用程序,并在 Docker 中运行所有内容!
1. 克隆后端 Node.js
在本系列的前几篇文章中,我们结合 Docker 使用 MongoDb 创建了一个 Node.js 应用。在本教程中,我们需要使用相同的项目。您可以从此处克隆源代码或运行以下命令:
git clone https://github.com/vguleaev/Express-Mongo-Docker-tutorial.git
克隆完成后,将文件夹从test-mongo-app
重命名为api
。这将是我们的后端。
要测试一切正常,请打开api
文件夹并运行npm install
。依赖项安装完成后,让我们检查一切是否正常。🍾
docker-compose up
此命令将使用我们的docker-compose.yml
拉取 mongo 镜像并启动连接到 MongoDb 的 express 服务器。
如果一切正常,您应该在控制台中看到类似这样的内容:
web_1 | Listening on 8080
web_1 | MongoDb connected
在浏览器中打开http://localhost:8080/users端点,你应该会得到一个空数组作为响应。这是正确的,因为我们的数据库目前完全是空的。
2. 创建 React 应用
现在该开发前端部分了。回到父目录并运行:
npm i create-react-app -g
create-react-app ui
现在我们的文件夹结构应该是这样的:
...
═── / api
└── / ui
(其中 api 是克隆的后端应用程序,ui 是新创建的 React 应用程序。)
为了确保一切正常,让我们打开ui文件夹并启动 React 应用程序:
cd ui
npm start
你应该可以在http://localhost:3000看到基本的 React 应用。🎈
3. Docker化React应用
在ui文件夹中创建一个.dockeringore
文件:
node_modules
.git
.gitignore
(如果没有这个文件,我们的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"]
让我们测试一下 React 能否在 docker 中运行。首先,我们将构建一个带有 react:app 标签的镜像:
docker build -t react:app .
现在运行我们标记的图像并使用相同的 docker 端口:
docker run -p 3000:3000 react:app
打开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
然后选择所需的 ID 并停止容器。
docker stop 06c982ce6ae9
4. 从 React 应用调用 API
打开ui文件夹并安装axios
cd ui
npm i axios
我们将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;
由于前端运行在 3000 端口,而后端运行在 8080 端口,因此我们可能会遇到CORS问题。为了避免这个问题,请前往api项目并安装 cors 包。
npm i cors
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());
// ...
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'
我们的根文件夹结构现在如下所示:
...
═── / 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
打开http://localhost:3000/并点击按钮创建用户。打开开发者工具查看调用情况。现在,我们从 docker 运行前端和后端!
6. 使用 React 生产构建
现在,我们用开发服务器启动 React 应用,这可能不是我们想要在生产环境中使用的。但我们可以轻松解决这个问题。
我们只需要修改我们的Dockerfile
UI项目。我们将启动生产版本并使用 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;"]
由于我们现在暴露了端口 80,所以我们需要在 中将其从 3000 更改为 80 docker-compose.yml
。
ui:
build: ./ui
ports:
- '80:80'
depends_on:
- api
现在再次运行 magic 命令来启动 docker 中的所有内容🔮
docker-compose up --build
打开http://localhost/您应该会看到完全相同的工作应用程序,但现在 React 正在生产模式下运行。
源代码请见此处。尽情享用吧!
恭喜你成功将 React、Nodejs 和 Mongodb docker 化!🎉🎉🎉
🚀 如果你从那篇文章中读到了什么有趣的内容,请点赞并关注我,我会分享更多文章。谢谢你,亲爱的程序员!😏
文章来源:https://dev.to/vguleaev/dockerize-a-react-app-with-node-js-backend-connected-to-mongodb-10ai