node.js - 将 React + Express 应用程序部署到 Kubernetes。如何用docker构建它?

标签 node.js reactjs express kubernetes docker-compose

所以我一直在努力研究如何部署一个 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 个选项:
  • 将前端和后端分别部署到不同的服务器。在这种情况下,react 前端将托管在某个 Web 托管服务上,而 express 后端将托管在 kubernetes
  • 上。
  • 让 express 应用服务于 react 应用
  • 将应用程序分开,但使用 NGINX 将 API 请求代理到 express 应用程序

  • 我想我会选择选项 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 chartMongoDB'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:使您的容器与您可能在生产中运行的容器大不相同;删除它们。
  • 不要费心使容器内部端口可配置。在普通 Docker、Docker Compose 和 Kubernetes 中,您可以在部署时将容器内部端口重新映射到任意外部可访问端口。你可以在这里选择固定号码,这很好。
  • 您显示的一些详细信息,例如容器 expose: 的端口和默认 command:要运行,它们是镜像的正确组成部分(每次运行镜像时它们都是相同的),因此将它们移动到 Dockerfile 中。
  • links:这些天是多余的,你可以删除它们。在 Docker Compose 中,您始终可以通过服务块的名称来访问另一个服务的名称。
  • 其他相关服务的名称在不同的环境中会有所不同。例如,MongoDB 可能位于 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/

    相关文章:

    javascript - .app 文件夹是什么?如何将其转换为 .dmg 存档?

    node.js - nodeJS,将文件移动到新文件夹

    node.js - "This site can’ t be reached"using Nginx as reverse proxy for Express Nodejs

    apache - socket.io 与 Apache Tomcat

    javascript - 使用 React-Context 时对象不可迭代错误

    node.js - npm 强大的形式仅返回最后一个复选框值

    javascript - Iframe CDN 不响应 postMessage()

    reactjs - 我的组件在不应该的情况下改变了它的 props

    node.js - 在 Azure Web App 上的 iisnode 上运行 Next.js 时出现问题

    javascript - express js如何将数组转换为对象