Docker Mern Stack示例
#javascript #网络开发人员 #docker #todayilearned

Docker提供了轻巧的容器来与基础架构隔离运行服务,因此我们可以快速提供软件。在本教程中,我将向您展示如何使用Docker ComposeNginx

相关文章:

带有Docker概述的Mern Stack应用程序

假设我们有一个Fullstack React + Nodejs Express + MongoDB应用程序(Mern stack)。
问题是要容忍一个需要多个Docker容器的系统:

  • 对UI的反应
  • node.js for api
  • 数据库的mongodb

Docker组成的构成可帮助我们更容易,更有效地设置系统,而不是仅使用Docker。我们将遵循以下步骤:

  • 设置Nodejs应用程序与MongoDB数据库一起工作。
  • 为nodejs应用创建dockerfile。
  • 设置React App。
  • 为React App创建Dockerfile。
  • 写docker在yaml文件中构成配置。
  • 设置Docker组成的环境变量
  • 运行系统。

目录结构:

docker-mern-nginx-example-structure

设置nodejs app

您可以从以下教程中的一个:

中读取并获取github源代码

使用上面的代码库,我们将nodejs项目放入 bezkoder-api 文件夹中,然后修改某些文件以与环境变量一起使用。

首先,让我们将dotenv模块添加到 package.json

{
  ...
  "dependencies": {
    "dotenv": "^10.0.0",
    ...
  }
}

接下来,我们在 server.js 中导入dotenv并使用process.env来设置CORS和端口。

require("dotenv").config();
...
var corsOptions = {
  origin: process.env.CLIENT_ORIGIN || "http://localhost:8081"
};

app.use(cors(corsOptions));
..
// set port, listen for requests
const PORT = process.env.NODE_DOCKER_PORT || 8080;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}.`);
});

然后,我们更改修改数据库配置和初始化。

app / config / db.config.js

const {
  DB_USER,
  DB_PASSWORD,
  DB_HOST,
  DB_PORT,
  DB_NAME,
} = process.env;

module.exports = {
  url: `mongodb://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?authSource=admin`
};

我们还需要制作 .env 示例文件,以显示所有必要的参数。

bezkoder-api / .env.sample

DB_HOST=localhost
DB_USER=root
DB_PASSWORD=123456
DB_NAME=bezkoder_db
DB_PORT=27017

NODE_DOCKER_PORT=8080

CLIENT_ORIGIN=http://127.0.0.1:8081

为nodejs应用创建Dockerfile

Dockerfile定义了Docker用于设置Node.js应用程序环境的命令列表。因此,我们将文件放入 bezkoder-api 文件夹中。

因为我们将使用Docker组成,所以我们不会在此Dockerfile中定义所有配置命令。

bezkoder-api / dockerfile

FROM node:14

WORKDIR /bezkoder-api
COPY package.json .
RUN npm install
COPY . .
CMD npm start

让我解释一些要点:

  • FROM:安装node.js版本的图像。
  • WORKDIR:工作目录的路径。
  • COPY:复制 package.json 文件到容器,然后第二个复制项目目录中的所有文件。
  • RUN:在容器中执行命令行:npm install package.json
  • 中安装依赖项
  • CMD:构建图像后运行脚本npm start

设置React App

您可以从以下教程中的一个:

中读取并获取github源代码

使用上面的代码库,我们将React项目放入 bezkoder-ui 文件夹中,并进行一些工作。

首先,让我们删除 .env 文件,因为我们将与Docker的环境变量一起工作。

然后,我们打开 http-common.js ,用于用process.env.REACT_APP_API_BASE_URL更新axios实例的baseURL

import axios from "axios";

export default axios.create({
  baseURL: process.env.REACT_APP_API_BASE_URL || 'http://localhost:8080/api',
  headers: {
    "Content-type": "application/json"
  }
});

创建React App

的Dockerfile

我们将在Nginx服务器后面部署React应用程序。

与nodejs相同,我们将dockerfile放入 bezkoder-ui 文件夹中。

bezkoder-upi / dockerfile

# Stage 1
FROM node:14 as build-stage

WORKDIR /bezkoder-ui
COPY package.json .
RUN npm install
COPY . .

ARG REACT_APP_API_BASE_URL
ENV REACT_APP_API_BASE_URL=$REACT_APP_API_BASE_URL

RUN npm run build

# Stage 2
FROM nginx:1.17.0-alpine

COPY --from=build-stage /bezkoder-ui/build /usr/share/nginx/html
EXPOSE $REACT_DOCKER_PORT

CMD nginx -g 'daemon off;'

有两个阶段:

  • 阶段1:构建React应用程序

    • FROM:安装node.js版本的图像。
    • WORKDIR:工作目录的路径。
    • COPY:复制 package.json 文件到容器,然后第二个复制项目目录中的所有文件。
    • RUN:在容器中执行命令行:npm install package.json
    • 中安装依赖项
    • ARGENV:获取参数和设置环境变量(需要前缀REACT_APP_)。
    • 运行脚本npm run build构建图像后,产品将存储在 build 文件夹中。
  • 阶段2:将React应用程序与Nginx

    一起服务
    • 安装 nginx的图像 Alpine版本。
    • 将React构建从阶段1复制到/usr/share/nginx/html文件夹中。
    • 公开端口(应为80)到docker主机。
    • daemon off;指令告诉nginx留在前景中。

写Docker为Mern应用程序撰写

在项目目录的根部,我们将为Mern堆栈创建 docker-compose.yml 文件。遵循Docker定义的version 3语法:

version: '3.8'

services: 
    mongodb:
    bezkoder-api:
    bezkoder-ui:

volumes:

networks:
  • version:将使用Docker组成的文件格式版本。
  • services:孤立容器中的单个服务。我们的应用程序有三个服务:bezkoder-ui(react),bezkoder-api(nodejs)和mongodb(mongodb数据库)。
  • volumes:命名量,使我们的数据在重新启动后保持活力。
  • networks:促进容器之间的通信

让我们实现详细信息。

docker-compose.yml

version: '3.8'

services:
  mongodb:
    image: mongo:5.0.2
    restart: unless-stopped
    env_file: ./.env
    environment:
      - MONGO_INITDB_ROOT_USERNAME=$MONGODB_USER
      - MONGO_INITDB_ROOT_PASSWORD=$MONGODB_PASSWORD
    ports:
      - $MONGODB_LOCAL_PORT:$MONGODB_DOCKER_PORT
    volumes:
      - db:/data/db
    networks:
      - backend

  bezkoder-api:
    depends_on:
      - mongodb
    build: ./bezkoder-api
    restart: unless-stopped
    env_file: ./.env
    ports:
      - $NODE_LOCAL_PORT:$NODE_DOCKER_PORT
    environment:
      - DB_HOST=mongodb
      - DB_USER=$MONGODB_USER
      - DB_PASSWORD=$MONGODB_PASSWORD
      - DB_NAME=$MONGODB_DATABASE
      - DB_PORT=$MONGODB_DOCKER_PORT
      - CLIENT_ORIGIN=$CLIENT_ORIGIN
    networks:
      - backend
      - frontend

  bezkoder-ui:
    depends_on:
      - bezkoder-api
    build:
      context: ./bezkoder-ui
      args:
        - REACT_APP_API_BASE_URL=$CLIENT_API_BASE_URL
    ports:
      - $REACT_LOCAL_PORT:$REACT_DOCKER_PORT
    networks:
      - frontend  

volumes: 
  db:

networks:
  backend:
  frontend:
  • mongodb

    • image:官方Docker Image
    • restart:配置restart policy
    • env_file:指定我们 .env 路径,我们将在以后创建
    • environment:使用环境变量提供设置
    • ports:指定端口将被使用
    • volumes:地图卷文件夹
    • networks:加入backend网络
  • bezkoder-api

    • depends_on:依赖顺序, MongoDB bezkoder-api 之前启动了服务
    • build:在 dockerfile 中定义的构建时间上应用的配置选项
    • environment:节点应用程序使用的环境变量
    • networks:加入backendfrontent Networks
  • bezkoder-ui

    • depends_on:在bezkoder-api之后开始
    • build-args:添加构建参数 - 仅在构建过程中访问的环境变量
    • 才能访问
    • networks:仅加入frontent网络

您应该注意,主机端口(LOCAL_PORT)和容器端口(DOCKER_PORT)不同。网络服务到服务通信使用容器端口,外部使用主机端口。

docker构成环境变量

在服务配置中,我们使用了 .env 文件中定义的环境变量。现在我们开始编写它。

.env

MONGODB_USER=root
MONGODB_PASSWORD=123456
MONGODB_DATABASE=bezkoder_db
MONGODB_LOCAL_PORT=7017
MONGODB_DOCKER_PORT=27017

NODE_LOCAL_PORT=6868
NODE_DOCKER_PORT=8080

CLIENT_ORIGIN=http://127.0.0.1:8888
CLIENT_API_BASE_URL=http://127.0.0.1:6868/api

REACT_LOCAL_PORT=8888
REACT_DOCKER_PORT=80

与Docker Compose

运行Mern堆栈

我们只能使用一个命令轻松地运行整个命令:
docker-compose up

docker会拉动mongodb和node.js images(如果我们的计算机之前没有它)。

服务可以通过命令在后台运行:
docker-compose up -d

$ docker-compose up -d
Creating network "react-node-mongodb_backend" with the default driver
Creating network "react-node-mongodb_frontend" with the default driver
Creating volume "react-node-mongodb_db" with default driver
Pulling mongodb (mongo:5.0.2)...
5.0.2: Pulling from library/mongo
16ec32c2132b: Pull complete
6335cf672677: Pull complete
cbc70ccc8ebe: Pull complete
0d1a3c6bd417: Pull complete
960f3b9b27d3: Pull complete
aff995a136b4: Pull complete
4249be7550a8: Pull complete
cc105ff5aa3c: Pull complete
82819807d07a: Pull complete
81447d2c233f: Pull complete
Digest: sha256:93ea50c5f15f9814870b3509449d327c5bc4d38f2b17c20acec528472811a723
Status: Downloaded newer image for mongo:5.0.2
Building bezkoder-api
Sending build context to Docker daemon  20.48kB
Step 1/6 : FROM node:14
 ---> 256d6360f157
Step 2/6 : WORKDIR /bezkoder-api
 ---> Running in 630b36161cfc
Removing intermediate container 630b36161cfc
 ---> cce099c5509c
Step 3/6 : COPY package.json .
 ---> 966883cd8e24
Step 4/6 : RUN npm install
 ---> Running in 246256e84187
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN node-express-mongodb@1.0.0 No repository field.

added 82 packages from 128 contributors and audited 82 packages in 8.017s

2 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Removing intermediate container 246256e84187
 ---> bdab72a5d37b
Step 5/6 : COPY . .
 ---> e9069d0ee44a
Step 6/6 : CMD npm start
 ---> Running in 6f63286cae18
Removing intermediate container 6f63286cae18
 ---> 65452914f005
Successfully built 65452914f005
Successfully tagged react-node-mongodb_bezkoder-api:latest
WARNING: Image for service bezkoder-api was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Building bezkoder-ui
Sending build context to Docker daemon  67.07kB
Step 1/12 : FROM node:14 as build-stage
 ---> 256d6360f157
Step 2/12 : WORKDIR /bezkoder-ui
 ---> Running in e135a434b996
Removing intermediate container e135a434b996
 ---> 80292facc18b
Step 3/12 : COPY package.json .
 ---> 595fbe352edd
Step 4/12 : RUN npm install
 ---> Running in 9d8ef80ff165

added 1661 packages from 793 contributors and audited 1666 packages in 115.944s

94 packages are looking for funding
  run `npm fund` for details

found 10 vulnerabilities (1 low, 5 moderate, 4 high)
  run `npm audit fix` to fix them, or `npm audit` for details
Removing intermediate container 9d8ef80ff165
 ---> 18a4f1382bc7
Step 5/12 : COPY . .
 ---> f99e2a8ef053
Step 6/12 : ARG REACT_APP_API_BASE_URL
 ---> Running in 47dca1457fb2
Removing intermediate container 47dca1457fb2
 ---> 8986f1482c8d
Step 7/12 : ENV REACT_APP_API_BASE_URL=$REACT_APP_API_BASE_URL
 ---> Running in 95687ba2d936
Removing intermediate container 95687ba2d936
 ---> 7a20778bca2b
Step 8/12 : RUN npm run build
 ---> Running in d0074ed04394

> react-crud@0.1.0 build /bezkoder-ui
> react-scripts build

Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  52.78 KB  build/static/js/2.c9e8967b.chunk.js
  22.71 KB  build/static/css/2.fa6c921b.chunk.css
  2.39 KB   build/static/js/main.aae2fe51.chunk.js
  776 B     build/static/js/runtime-main.99b514f4.js
  144 B     build/static/css/main.9c6cdb86.chunk.css

The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.
You may serve it with a static server:

  npm install -g serve
  serve -s build

Find out more about deployment here:

  bit.ly/CRA-deploy

Removing intermediate container d0074ed04394
 ---> 9cd424a1901b
Step 9/12 : FROM nginx:1.17.0-alpine
 ---> bfba26ca350c
Step 10/12 : COPY --from=build-stage /bezkoder-ui/build /usr/share/nginx/html
 ---> 2b4cbdbd908e
Step 11/12 : EXPOSE $REACT_DOCKER_PORT
 ---> Running in ced23b1795d6
Removing intermediate container ced23b1795d6
 ---> 2850341d70f0
Step 12/12 : CMD nginx -g 'daemon off;'
 ---> Running in d596e17eec46
Removing intermediate container d596e17eec46
 ---> fef41917c48b
Successfully built fef41917c48b
Successfully tagged react-node-mongodb_bezkoder-ui:latest
WARNING: Image for service bezkoder-ui was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating react-node-mongodb_mongodb_1 ... done
Creating react-node-mongodb_bezkoder-api_1 ... done
Creating react-node-mongodb_bezkoder-ui_1  ... done

现在您可以检查当前的工作容器:

$ docker ps
CONTAINER ID   IMAGE                             COMMAND                  CREATED        STATUS         PORTS                                         NAMES
c9ee5ce3c370   react-node-mongodb_bezkoder-ui    "/bin/sh -c 'nginx -…"   Up 2 minutes   Up 2 minutes   0.0.0.0:8888->80/tcp, :::8888->80/tcp         react-node-mongodb_bezkoder-ui_1
f0c7d4174bdb   react-node-mongodb_bezkoder-api   "docker-entrypoint.s…"   Up 2 minutes   Up 2 minutes   0.0.0.0:6868->8080/tcp, :::6868->8080/tcp     react-node-mongodb_bezkoder-api_1
2f8390fc81dd   mongo:5.0.2                       "docker-entrypoint.s…"   Up 2 minutes   Up 2 minutes   0.0.0.0:7017->27017/tcp, :::7017->27017/tcp   react-node-mongodb_mongodb_1

和docker图像:

$ docker images
REPOSITORY                        TAG      IMAGE ID       CREATED         SIZE
react-node-mongodb_bezkoder-ui    latest   fef41917c48b   3 minutes ago   22MB
react-node-mongodb_bezkoder-api   latest   65452914f005   6 minutes ago   961MB
mongo                             5.0.2    269b735e72cb   7 minutes ago   682MB

测试React UI:

docker-mern-nginx-example-test-ui

mongoDB数据库:

docker-mern-nginx-example-test-database

和node.js express api:

docker-mern-nginx-example-test-api

停止应用程序

停止所有运行容器也很简单,只需一个命令:
docker-compose down

$ docker-compose down
Stopping react-node-mongodb_bezkoder-ui_1  ... done
Stopping react-node-mongodb_bezkoder-api_1 ... done
Stopping react-node-mongodb_mongodb_1      ... done
Removing react-node-mongodb_bezkoder-ui_1  ... done
Removing react-node-mongodb_bezkoder-api_1 ... done
Removing react-node-mongodb_mongodb_1      ... done
Removing network react-node-mongodb_backend
Removing network react-node-mongodb_frontend

如果您需要停止并删除 docker-compose.yml 文件中任何服务使用的所有容器,网络和所有图像,请使用命令:
docker-compose down --rmi all

结论

今天,我们成功地使用了Docker和Nginx创建了MERN应用程序。现在我们可以以一种非常简单的方式部署mern堆栈:react + nodejs express和mongodb: docker-compose.yml 。。

您可以将这种方式应用于以下项目之一:

快乐学习!再次见。

源代码

本教程的源代码可以在Github中找到。