【问题标题】:Deploying React + Express App to Kubernetes. How to structure it with docker?将 React + Express 应用程序部署到 Kubernetes。如何用 docker 构建它?
【发布时间】:2019-05-30 19:44:21
【问题描述】:

所以我一直在努力解决如何部署 dockerized 应用程序。该应用程序由一个反应前端和一个快速 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个选项:

  1. 将前端和后端分别部署到不同的服务器。在这种情况下,react 前端将位于某个网络托管服务上,而 express 后端将托管在 kubernetes 上
  2. 让 express 应用程序服务于 react 应用程序
  3. 将应用程序分开,但使用 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 上)。

我可以找到很多关于如何让这些东西在开发中运行的东西,但是当谈到部署这种类型的堆栈的方向时,我迷失了方向。

【问题讨论】:

    标签: node.js reactjs express kubernetes docker-compose


    【解决方案1】:

    您可以从阅读Kubernetes documentation 开始,了解什么是直截了当的,什么不是。您最感兴趣的是部署和服务,可能还有 Ingress。具有关联持久状态的 MongoDB 设置会更加复杂,您可能会查看预打包的解决方案,例如 the stable/mongodb Helm chartMongoDB's official operator

    请注意,Kubernetes 设置的一个重要部分是几乎总是会有多个节点,并且您无法完全控制 Pod 将放置在哪个节点上。这尤其意味着您展示的 Docker Compose volumes: 在 Kubernetes 环境中无法正常工作——除了完成所有正常的 Kubernetes 部署工作之外,您还需要将应用程序源代码复制到每个节点。这是相同部署工作量的两倍。通常你会希望所有的应用程序代码都包含在 Docker 镜像中,典型的基于节点的 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 中,您可以在部署时将容器内部端口重新映射到任意外部可访问端口。你可以在这里选择固定的数字就可以了。

    • 1234563将这些移到 Dockerfile 中。
    • links: 现在是多余的,您可以删除它们。在 Docker Compose 中,您始终可以通过服务块的名称来获取另一个服务的名称。

    • 其他相关服务的名称在不同的环境中会有所不同。例如,当您实际在 Docker 之外开发应用程序时,MongoDB 可能在 localhost,在您显示的配置中使用 mongo,在 Kubernetes 中使用 mongo.myapp.svc.cluster.local,或者您可能选择完全在 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 中取出是有意义的。

    【讨论】:

    • 哦,是的,我肯定会做所有这些事情,我只是在开发环境中展示我的docker-compose,事后看来,我也应该展示我预测用于生产的东西跨度>
    【解决方案2】:

    我将前端和后端作为完全独立的应用程序。他们每个人都在自己的 GitHub 存储库中,拥有自己的测试套件、Dockerfile、Jenkins 构建,以及一切。这允许我们独立地对它们进行版本控制,从而允许更频繁的迭代;更小、风险更低的部署;更快、更高效的开发。

    对后端的所有调用都在 /API/ 路径上,该路径由 nginx 入口控制器(非常简单)处理并适当地路由到后端服务。

    【讨论】:

    • 我认为这很理想,但唯一的问题是我们的开发人员是全栈的,并且经常会同时对前端和后端进行更改
    【解决方案3】:

    我喜欢选项 1 多于 3,因为它使前端和后端保持分离。一个巨大的优势是您可以将前端托管在AWS S3 with a CloudFront CDN 之类的地方。因此,所有静态内容都分发到世界各地的边缘服务器。这将非常快速地将繁重的项目(图像、大型 js 库、css 等)提供给您的最终用户,并使您的应用程序运行得更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-06
      • 2021-04-01
      • 1970-01-01
      • 2018-07-13
      • 2022-06-14
      • 2019-07-22
      • 1970-01-01
      • 2021-04-21
      相关资源
      最近更新 更多