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

Для тех кто пропустил, начало

Поскольку мы изначально начали создавать приложение путем разделения компонентов на небольшие сервисы, которые можно развертывать и использовать независимо друг от друга давайте рассмотрим из чего в дальнейшем будет состоять наше приложение. А состоять оно будет из следующих сервисов:

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 и запустим наш контейнер.

Комментарии (0)