Наш проект разрастается, что приводит к необходимости добавлять дополнительные службы, по сути отвечающие за один элемент логики.
Для тех кто пропустил, начало.
Поскольку мы изначально начали создавать приложение путем разделения компонентов на небольшие сервисы, которые можно развертывать и использовать независимо друг от друга давайте рассмотрим из чего в дальнейшем будет состоять наше приложение. А состоять оно будет из следующих сервисов:
1. Сервис Фронтенд Angular
2. Сервис API Nodejs
3. Сервис API Авторизации Node
4. API БД MongoDb
5. API Авторизации MongoDb
6. Сервис Nginx Proxy - основной сервис маршрутизатор
Для создания описанной выше структуры давайте внесем необходимые изменения, создадим каталоги: api, angular, nginx, auth. Перенесем файлы проекта в каталог angular.
Наши отдельные сервисы чрезвычайно просты и могут развертываться независимо друг от друга, а это значит, что для большей простоты и получения модели распределенной инфраструктуры необходимо упаковать службы в контейнер, что предоставит нам дополнительное удобство в развертывании и разработке нашего приложения, для этого мы будем использовать Docker, который позволяет запускать практически любое приложение, безопасно изолированное в контейнере. Безопасная изоляция позволяет запускать на одном хосте много контейнеров одновременно. Docker, состоит из образов, реестров и контейнеров.
Для создания контейнеров используются Образы которые в свою очередь хранятся в реестрах. Есть публичные и приватные реестры, из которых можно скачать либо загрузить образы. Каждый контейнер создается из образа и в нем содержится все, что нужно для работы приложения. Контейнеры могут быть созданы, запущены, остановлены, перенесены или удалены. Каждый контейнер изолирован и является безопасной платформой для приложения.
Подразумевается, что у вас уже установлен Docker.
В нашем приложении мы будем использовать несколько образов, поэтому приступим. Для создания нашего апи переходим в каталог api и создаем Docker файл.
Содержимое Docker файла в каталоге api
FROM node:14.15.0-alpine as development WORKDIR /usr/src/app COPY package*.json ./ RUN npm install glob rimraf RUN npm install --only=development COPY . . RUN npm run build FROM node:14.15.0-alpine as production ARG NODE_ENV=production ENV NODE_ENV=${NODE_ENV} WORKDIR /usr/src/app COPY package*.json ./ RUN npm install --only=production COPY . . COPY --from=development /usr/src/app/dist ./dist CMD ["node", "dist/main"]
Далее переходим в каталог angular и создаем там два файла, таким образом в дальнейшем мы рассмотрим несколько подходов разделения на prod и dev версии.
Содержимое файла Dockerfile.dev в каталоге angular
FROM node:14.15.0-alpine WORKDIR /usr/src/app COPY package*.json ./ RUN npm install COPY . . EXPOSE 4300 CMD npm run start
Содержимое Dockerfile.prod в каталоге angular
FROM node:13.12.0-alpine WORKDIR /usr/src/app COPY package*.json ./ RUN npm install COPY . . RUN npm run build RUN npm install -g serve
Добавляем в package.json строку необходимую для прослушивания всех интерфейсов из контейнера
"start": "ng serve --host 0.0.0.0 --poll 500",
Причина, по которой это важно, заключается в том, что без него процесс angular прослушивает только локальный интерфейс внутри контейнера, поэтому даже с сопоставлением портов докера соединения извне контейнера не принимаются.
Но если мы добавим параметр, --host 0.0.0.0 то процесс angular будет прослушивать все интерфейсы, а сопоставление портов докера позволит подключаться к нему из-за пределов контейнера.
После этого переходим в корень нашего проекта и создаем docker-compose.yml
Содержимое файла docker-compose.yml
version: '3.4' services: angular: container_name: art-pixel-angular_api_dev build: context: ./angular dockerfile: Dockerfile.dev command: npm run start volumes: - ./angular/src:/usr/src/app/src - /usr/node_modules ports: - 4300:4300 networks: - art-pixel-network restart: unless-stopped api-dev: container_name: art-pixel_api_dev image: art-pixel-api-dev:1.0.0 build: context: ./api target: development dockerfile: Dockerfile command: npm run start:debug volumes: - ./api/src:/usr/src/app/src - /usr/node_modules ports: - 3000:3000 - 9229:9229 environment: - PORT=3000 - HOST=http://localhost - MONGO_URL=mongodb://api-db:27017/api depends_on: - api-db networks: - art-pixel-network restart: unless-stopped api-db: image: mongo:4.4.4 container_name: mongo-api-db environment: - MONGO_INITDB_ROOT_USERNAME=admin - MONGO_INITDB_ROOT_PASSWORD=admin ports: - 27017:27017 volumes: - ./mongo-data-4.4:/data/db networks: - art-pixel-network restart: always api-prod: container_name: art-pixel_api_prod image: art-pixel-api-prod:1.0.0 build: context: ./api target: production dockerfile: ./Dockerfile command: npm run start:prod ports: - 3000:3000 - 9229:9229 networks: - art-pixel-network volumes: - ./api/src:/usr/src/app - /usr/src/node_modules restart: unless-stopped networks: art-pixel-network:
На сегодня все, в следующей части мы займемся созданием api на Nest.js и запустим наш контейнер.
