这篇文章的作者(我们今天将发表其译文)想谈谈如何将基于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撰写
我们工作的最后一个阶段是带来容器api
和client
包含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
一切都安排得非常简单。我们有三个服务:client
,api
和db
。 MongoDB没有选择Dockerfile
-Docker将从其中心下载适当的映像并从中创建一个容器。这意味着我们的数据库将为空,但是对于初学者来说,这将适合我们。在这些部分中api
,client
有一个键,build
其值包含指向Dockerfile
相应服务的文件(到根目录api
和client
)的路径。文件中分配的容器端口将在Dockerfile
Docker 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?