所以我一直在努力研究如何部署一个 dockerized 应用程序。该应用程序由 react 前端和快速 API 组成。
我的 docker-compose.yml
开发环境如下所示:
version: '3'
services:
# Express Container
backend:
build: ./backend
expose:
- ${BACKEND_PORT}
env_file:
- ./.env
environment:
- PORT=${BACKEND_PORT}
ports:
- ${BACKEND_PORT}:${BACKEND_PORT}
volumes:
- ./backend:/backend
command: npm run devstart
links:
- mongo
# React Container
frontend:
build: './frontend'
expose:
- ${REACT_APP_PORT}
env_file:
- ./.env
environment:
- REACT_APP_BACKEND_PORT=${BACKEND_PORT}
ports:
- ${REACT_APP_PORT}:${REACT_APP_PORT}
volumes:
- ./frontend/src:/frontend/src
- ./frontend/public:/frontend/public
links:
- backend
command: npm start
mongo:
image: mongo
ports:
- "27017:27017"
但是我一直在努力研究如何构建它以进行生产。
我已经看到基本上有 3 个选项:
我想我会选择选项 3,因为它会使开发和生产环境非常相似。 (请告诉我这是否是不良结构,此应用程序预计会收到大量流量。)
我是否应该忘记 docker-compose 并创建一个使用多阶段构建来复制前端和后端代码的多阶段 dockerfile?这样我可以部署单个 Docker 容器吗?
我的文件夹结构如下所示:
app/
.env
docker-compose.yml
docker-compose.prod.yml
.gitignore
frontend/
Dockerfile
... react stuff
backend
Dockerfile
.. express stuff
我在这一切都错了吗?您如何使用 docker-compose 将应用程序部署到生产环境(最好在 kubernetes 上)。
我可以找到大量关于如何让这些东西在开发中运行的东西,但是当涉及到部署这种类型的堆栈的方向时,我迷失了方向。
最佳答案
您可以先阅读 Kubernetes documentation并了解什么是直截了当的,什么不是。您最感兴趣的是部署和服务,可能还有 Ingress。具有关联持久状态的 MongoDB 设置会更复杂,您可能会查看预打包的解决方案,例如 the stable/mongodb Helm chart或 MongoDB's official operator .
请注意,Kubernetes 设置的一个重要部分是几乎总是有多个 Node ,并且您无法完全控制 Pod 将放置在哪个 Node 上。特别是这意味着 Docker Compose volumes:
您展示的在 Kubernetes 环境中无法正常工作——除了执行所有正常的 Kubernetes 部署工作外,您还需要将应用程序源代码复制到每个 Node 。这是同一部署工作的两倍。通常你会希望所有的应用程序代码都包含在 Docker 镜像中,典型的基于 Node 的 Dockerfile 看起来像
FROM node:10
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install
COPY ./ ./
RUN yarn build
EXPOSE 3000
CMD yarn start
就在
docker-compose.yml
内你显示的文件:volumes:
使您的容器与您可能在生产中运行的容器大不相同;删除它们。 expose:
的端口和默认 command:
要运行,它们是镜像的正确组成部分(每次运行镜像时它们都是相同的),因此将它们移动到 Dockerfile 中。 links:
这些天是多余的,你可以删除它们。在 Docker Compose 中,您始终可以通过服务块的名称来访问另一个服务的名称。 localhost
当您实际在 Docker 之外开发应用程序时,mongo
在您显示的配置中,mongo.myapp.svc.cluster.local
在 Kubernetes 中,或者您可以选择完全在 Docker 之外运行它。您通常希望这些是可配置的,通常使用环境变量。 这给你一个
docker-compose.yml
文件更像:version: '3'
services:
backend:
build: ./backend
environment:
- MONGO_URL: 'mongo://mongo'
ports:
- 3000:3000
frontend:
build: './frontend'
environment:
- BACKEND_URL: 'http://backend'
ports:
- 8000:8000
mongo:
image: mongo
ports:
- "27017:27017"
正如@frankd 在他们的回答中暗示的那样,使用 Webpack 之类的工具将 React 应用程序预编译为一组静态文件也很常见。根据您实际部署它的方式,提前运行此编译步骤并将那些编译的 Javascript 和 CSS 文件推送到其他一些静态托管服务,并将其完全从 Docker/Kubernetes 中删除可能是有意义的。
关于node.js - 将 React + Express 应用程序部署到 Kubernetes。如何用docker构建它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56384713/