对接基于React,Express和MongoDB构建的应用程序

这篇文章的作者(我们今天将发表其译文)想谈谈如何将基于React,Express和基于MongoDB的Web应用程序打包到Docker容器中。在这里,我们将考虑形成此类项目的文件和文件夹结构,创建文件Dockerfile以及使用Docker Compose技术的功能。



开始工作


为简单起见,我假设您已经有一个工作的应用程序,由客户端和服务器部分提供,已连接到数据库。

客户端和服务器代码最好位于同一文件夹中。该代码可以位于一个存储库中,但也可以存储在不同的存储库中。在这种情况下,应使用命令将项目合并到一个文件夹中git submodule我就是这样做的。


父存储库文件树

反应应用


在这里,我使用了一个项目,该项目使用Create React App创建并配置为支持TypeScript。这是一个包含多个视觉元素的简单博客。

首先,Dockerfile在根目录中创建一个文件client为此,只需运行以下命令:

$ touch Dockerfile

打开文件,然后输入以下命令。如前所述,我在TypeScript应用程序中使用它,因此需要首先构建它。然后,您需要采取措施并以静态资源的格式部署所有内容。为了实现这一目标,我使用了构建Docker映像的两步过程。

第一步是使用Node.js构建应用程序。我使用Alpine图像作为基本图像。这是非常紧凑的图像,将有利地影响容器的尺寸。

FROM node:12-alpine as builder
WORKDIR /app
COPY package.json /app/package.json
RUN npm install --only=prod
COPY . /app
RUN npm run build

因此开始我们的Dockerfile。首先是团队node:12-alpine as builder。然后,我们设置工作目录-在本例中为this /app。因此,将在容器中创建一个新文件夹。在此容器文件夹中,复制package.json并安装依赖项。然后,/app我们从文件夹中复制所有内容/services/client。该工作由项目的组装完成。

现在,您需要为新创建的程序集组织托管。为此,请使用NGINX。而且,这将是该系统的Alpine版本。和以前一样,我们正在这样做以节省空间。

FROM nginx:1.16.0-alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

在此,将nginx上一步中获得的项目装配结果复制到文件夹中然后打开端口80容器将在此端口上等待连接。文件的最后一行用于启动NGINX。

这是泊坞应用程序客户端部分所需的全部。结果Dockerfile将如下所示:

FROM node:12-alpine as build
WORKDIR /app
COPY package.json /app/package.json
RUN npm install --only=prod
COPY . /app
RUN npm run build
FROM nginx:1.16.0-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Express API


我们的Express API也非常简单。在这里,为了组织端点,使用了RESTful技术。端点用于创建发布,支持授权以及解决其他问题。让我们从Dockerfile在根目录中创建开始api我们将像以前一样行动。

在应用程序服务器端的开发过程中,我使用了ES6的功能。因此,要运行代码,我需要对其进行编译。我决定使用Babel处理代码。您可能已经猜到了,这里将再次使用多阶段组装过程。

FROM node:12-alpine as builder
WORKDIR /app
COPY package.json /app/package.json
RUN apk --no-cache add --virtual builds-deps build-base python
RUN npm install
COPY . /app
RUN npm run build

这里的所有内容都与Dockerfile我们在项目的客户端使用的内容非常相似,因此我们不再赘述。但是,有一个功能:

RUN apk --no-cache add --virtual builds-deps build-base python

在将密码存储在数据库中之前,我使用bcrypt对其进行哈希处理这是一个非常受欢迎的程序包,但是在基于Alpine的图像中使用它会遇到一些问题。在这里,您可能会遇到类似以下错误消息的信息:

node-pre-gyp WARN Pre-built binaries not found for bcrypt@3.0.8 and node@12.16.1 (node-v72 ABI, musl) (falling back to source compile with node-gyp)
npm ERR! Failed at the bcrypt@3.0.8 install script.

这是一个众所周知的问题。她的解决方案是在安装npm软件包之前先安装其他软件包和Python。

与客户端一样,构建映像的下一步是采用上一步中形成的内容,并使用Node.js运行它。

FROM node:12-alpine
WORKDIR /app
COPY --from=builder /app/dist /app
COPY package.json /app/package.json
RUN apk --no-cache add --virtual builds-deps build-base python
RUN npm install --only=prod
EXPOSE 8080 
USER node
CMD ["node", "index.js"]

这里还有另一个功能,即仅安装那些专为项目在生产中使用而设计的软件包。我们不再需要Babel-毕竟,所有内容都已经在组装的第一步中进行了编译。接下来,我们打开8080应用程序服务器端将等待请求到达的端口,然后运行Node.js。

这是摘要Dockerfile

FROM node:12-alpine as builder
WORKDIR /app
COPY package.json /app/package.json
RUN apk --no-cache add --virtual builds-deps build-base python
RUN npm install
COPY . /app
RUN npm run build
FROM node:12-alpine
WORKDIR /app
COPY --from=builder /app/dist /app
COPY package.json /app/package.json
RUN apk --no-cache add --virtual builds-deps build-base python
RUN npm install --only=prod
EXPOSE 8080 
USER node
CMD ["node", "index.js"]

Docker撰写


我们工作的最后一个阶段是带来容器apiclient包含MongoDB的容器。为此,我们将使用docker-compose.yml位于父存储库根目录中的文件这样做的原因是,可以从此位置访问Dockerfile项目的客户端和服务器部分的文件

创建一个文件docker-compose.yml

$ touch docker-compose.yml

现在,项目文件结构应如下图所示。


项目文件的最终结构

现在,我们将添加docker-compose.yml以下命令:

version: "3"
services:
  api:
    build: ./services/api
    ports:
      - "8080:8080"
    depends_on:
      - db
    container_name: blog-api
  client:
    build: ./services/client
    ports:
      - "80:80"
    container_name: blog-client
  db:
    image: mongo
    ports:
      - "27017:27017"
    container_name: blog-db

一切都安排得非常简单。我们有三个服务:clientapidb。 MongoDB没有选择Dockerfile-Docker将从其中心下载适当的映像并从中创建一个容器。这意味着我们的数据库将为空,但是对于初学者来说,这将适合我们。

在这些部分中apiclient有一个键,build其值包含指向Dockerfile相应服务的文件(到根目录apiclient的路径。文件中分配的容器端口将在DockerfileDocker Compose托管的网络上打开。这将允许应用程序进行交互。api此外,在配置服务时,使用密钥depends_on他告诉Docker,在启动此服务之前,您需要等待直到容器完全启动db因此,我们可以防止container中的错误api

并且-这是与MongoDB有关的另一件事。在后端代码库中,您需要更新数据库连接字符串。通常它指示localhost

mongodb://localhost:27017/blog

但是,使用Docker Compose技术,我们必须使其指向容器的名称:

mongodb://blog-db:27017/blog

我们工作的最后一步是通过在项目根文件夹(文件所在的位置docker-compose.yml)中执行以下命令来启动所有这些操作

$ docker-compose up

摘要


我们研究了一种基于React,Node.js和MongoDB的容器化应用程序的简单技术。我们相信,如果您需要它,则可以轻松地使其适合您的项目。

PS我们在RUVDS网站上启动了市场一键安装Docker镜像您可以在VPS上检查容器的操作免费为新客户提供3天的测试。

亲爱的读者们!您是否使用Docker Compose?


All Articles