# Контейнеризация приложений

### Построение стенда
Схема виртуального лабораторного стенда
<center>
<div drawio-diagram="483"><img src="https://docs.resds.ru/uploads/images/drawio/2024-02/AwDOhWxrdwibVqmJ-drawing-3-1709036890.png"></div>

Рисунок 1. Схема стенда</center>


1. Создать виртуальные машины для работы

|Название виртуальной машины|Источник |Тип инстанса|Сети для внешнего подключения |
|-|-|-|-|
|web-server|Образ-Ubuntu-server20.04|medium|external-net|

Так же нужно проверить развернутую инфраструктуру на соответствие схеме на рисунке 1.


### 1. Установка Docker

1) Обновляем информацию о пакетах в репозиториях и обновляем установленные пакеты:
    ```bash
    sudo apt update
    sudo apt full-upgrade -y
    ```
2) Добавляем репозитории официальные репозитории  Docker:
    ```bash
    sudo install -m 0755 -d /etc/apt/keyrings
    sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
    sudo chmod a+r /etc/apt/keyrings/docker.asc
  
    echo \
    "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
    $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
    sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    sudo apt-get update
    ```
3) Установим пакеты Docker
    ```bash
    sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
    ```
4) Проверка работы Docker 
    ```bash
    sudo docker run hello-world
    ```
    [![](https://docs.resds.ru/uploads/images/gallery/2024-02/scaled-1680-/3mL8S7rzPW4UFfr9-image-1707222387974.png)](https://docs.resds.ru/uploads/images/gallery/2024-02/3mL8S7rzPW4UFfr9-image-1707222387974.png)

5)  Добавляем пользователя в группу `docker`
   
    ```bash
    sudo groupadd docker
    sudo usermod -aG docker $USER
    ```
    После того как текущий пользователь был добавлен в группу Docker, мы можем проверить функциональность Docker без необходимости использования привилегий суперпользователя.
    ```bash
    docker run hello-world
    ```


### 2. Написание Dockerfile

1. Клонируем исходный проект с использованием системы контроля версий Git.
    ```bash
    sudo apt install git -y
    git clone https://gitlab.resds.ru/itt/sample-project.git
    cd sample-project
    ```
    в данном проекте собраны все компоненты из прошлой работы
   

3. Пишем Dockerfile для frontend части проекта
Для выполнения этой задачи предлагаем создать файл с названием Dockerfile в директории notes-app.
    ```Dockerfile
    FROM node:18-slim
    WORKDIR /usr/local/app
    COPY package*.json ./
    RUN npm i && npm cache clean --force
    COPY . .
    RUN npm run build -- --prod
    CMD ["npx","serve","-s","build"]
    ```
4. Запускаем сборку контейнера и проверяем его работоспособность
   ```bash
   docker build -t notes-app:latest .
   docker run -p 3000:3000 notes-app:latest
   ```
   И проверяем работоспособность приложения открыв в браузере страницу
4. Проделываем аналогичные действия для notes-backend
   ```Dockerfile
    FROM node:18-slim
    WORKDIR /usr/local/app
    COPY package*.json ./
    RUN npm i && npm cache clean --force
    COPY . .
    CMD ["npm","start"]
   ```
   Собираем контейнер и проверяем
   ```bash
   docker build -t notes-back:latest .
   docker run -p 5000:5000 notes-back:latest
   ```
   Для проверки можно использовать запрос к API
   ```bash
   curl --location --request POST 'http://127.0.0.1:5000/api/notes' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "index": "1",
        "note": "test message"
    }'
   ```
   > Как можно заметить, приложения, запущенные внутри виртуальной машины, становятся доступными извне.


5. Создаем общий файл Docker-compose для запуска приложения.
   ```docker-compose
   services:
      notes-app:
        build: ./notes-app/
        restart: always
      notes-back:
        build: ./notes-backend/
        restart: always
      nginx:
        image: nginx:1.25.3-alpine-slim
        volumes:
          - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
        ports:
          - "80:80"
        restart: always
        depends_on:
          - notes-app
          - notes-back
   ```
   > С учетом данного способа запуска контейнеров следует обратить внимание на то, что только порт 80 становится общедоступным.