Развертывание приложения React + Express для Kubernetes.Как структурировать это с помощью докера? - PullRequest
0 голосов
/ 30 мая 2019

Так что я боролся с тем, как развернуть докеризованное приложение. Приложение состоит из внешнего интерфейса и экспресс-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. Развертывание внешнего интерфейса и внутреннего интерфейса отдельно на разных серверах. В этом случае интерфейс реакции будет находиться на каком-либо веб-хостинге, а экспресс-сервер будет размещен на kubernetes
  2. Экспресс-заявка подает заявку на реагирование
  3. Разделяйте приложения, но используйте NGINX для прокси-запросов API к экспресс-приложению

Я думал, что пойду с вариантом 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).

Я могу найти тонны вещей о том, как запустить этот материал в разработке, но я теряюсь, когда дело доходит до направления для развертывания этого типа стека.

Ответы [ 3 ]

1 голос
/ 03 июня 2019

Вы могли бы начать с чтения документации Kubernetes и понимания того, что просто, а что нет. Вы больше всего заинтересованы в развертываниях и услугах, и, возможно, Ingress. Настройка MongoDB со связанным постоянным состоянием будет более сложной, и вы можете посмотреть на готовое решение, такое как диаграмма стабильного / mongodb Helm или официальный оператор MongoDB .

Обратите внимание, что важной частью настройки Kubernetes является то, что почти всегда будет несколько узлов, и вы не получите большого контроля над тем, на каком узле будет размещен Pod. В частности, это означает, что Docker Compose volumes:, который вы показываете, не будет хорошо работать в среде Kubernetes - в дополнение к обычной работе по развертыванию Kubernetes, вам также необходимо будет реплицировать исходный код приложения на каждый узел. Это вдвое больше работы для одного и того же развертывания. Обычно вы хотите, чтобы весь код приложения содержался в образе Docker, а типичный Docker-файл на основе узла выглядит примерно так:

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.

0 голосов
/ 31 мая 2019

Мне нравится вариант 1 больше, чем 3, так как он сохраняет внешний интерфейс и внутренний интерфейс отдельно. Огромным преимуществом является то, что вы можете разместить внешний интерфейс на чем-то вроде AWS S3 с CloudFront CDN . Таким образом, весь статический контент распространяется на пограничные серверы по всему миру. Это очень быстро доставит тяжелые элементы (изображения, большие js-библиотеки, css и т. Д.) Вашим конечным пользователям и значительно ускорит работу вашего приложения.

0 голосов
/ 30 мая 2019

Я оставляю переднюю часть и заднюю часть как полностью отдельные приложения.Каждый из них находится в своем собственном репозитории GitHub, со своими собственными тестовыми наборами, Dockerfiles, сборками Jenkins, всем.Это позволяет нам независимо их версии, что позволяет более частые итерации;меньшее развертывание с меньшим риском;и более быстрая, более эффективная разработка.

Все вызовы к внутреннему интерфейсу находятся в / API / пути, который обрабатывается входным контроллером nginx (очень просто) и направляется соответствующим образом в серверную службу.

...