Weather Forecast
April 12, 2023

WeatherForecast. Виртуальная машина. Docker.

Предисловие

Замечательно, когда у вашего любимого провайдера есть готовые образы виртуальных машин с установленными docker-ом и docker compose-ом. Но если нет, то ничего страшного. Docker устанавливается по инструкции с официального сайта (сразу даю ссылочку на вариант установки из репозитория "Install using the apt repository"):

https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository

Заводите виртуальную машину (описание тут), только выберите конфигурацию "пожирнее", я для теста взял 2 vCPU, 4RAM, 15 ГБ HDD. Настраивайте подключение по ssh и устанавливайте docker, опыта копирования команд из инструкции вам должно хватить.

И так виртуальная машина готова. Docker установлен.

Поехали

Начнем с решения проблем. Если вы успешно установили docker под root-ом и потом создали своего пользователя, настроили ssh и подключились к виртуальной машине (как это сделал я), то использованием docker-а возникнут проблемы:

Для решения нам нужно добавить своего пользователя в группу "docker". Кстати посмотреть список всех групп в системе можно командой:

 cat /etc/group

А проверить список групп, в которые входит ваш пользователь:

groups

Добавляемся в группу "docker" командой:

sudo usermod -aG docker ${USER}

Для того, чтобы изменения применились, нужно разлогиниться и залогиниться, после проверяем:

Работает. Теперь логинимся в наш Container Registry командой:

docker login cr.selcloud.ru

Для проверки скачаем образ нашего приложения и утилиты:

docker pull cr.selcloud.ru/deploy2production/weather-forecast-app-img:v2.0
docker pull cr.selcloud.ru/deploy2production/weather-forecast-setup-img:v2.0

УПС

Посыплю голову пеплом. В пролом посте я накосячил с копированием команд, и собрал один и тот же образ под разными именами (хотя в тексте поста все корректно), и "залил" так в Container Registry. Будь я зорким как орел, я бы заметил одинаковый хэш образов. Но нет. Поэтому я пересобрал опубликовал образы с новым тегом-версией v2.0. Учимся на ошибках - дважды проверяем, хэши нам в помощь.

Продолжим. Давайте для разминки запустим наше приложение в "dev" варианте, как мы это делаем локально, с базами данных в контейнерах.

 mkdir dev
 cd dev
 nano ./docker-compose.yml

Нам понадобится docker-compose файл с некоторыми изменениями:

name: "weather-forecast"

networks:
  weather-forecast-net:

services:
  postgres:
    image: "postgres"
    container_name: "weather-forecast-postgres"
    networks:
      - weather-forecast-net
    ports:
      - "5432:5432"
    environment:
      POSTGRES_PASSWORD: postgres
  redis:
    image: "redis"
    container_name: "weather-forecast-redis"
    networks:
      - weather-forecast-net
    ports:
      - "6379:6379"
  app:
    image: "cr.selcloud.ru/deploy2production/weather-forecast-app-img:v2.0"
    container_name: "weather-forecast-app"
    networks:
      - weather-forecast-net
    ports:
      - "80:80"
    environment:
       ASPNETCORE_ENVIRONMENT: Development
       DOTNET_PRINT_TELEMETRY_MESSAGE: false
       ConnectionStrings__Postgres: Host=weather-forecast-postgres;User Id=postgres;Password=postgres;Database=postgres
       ConnectionStrings__Redis: weather-forecast-redis:6379
    depends_on:
      postgres:
        condition: service_started
      redis:
        condition: service_started

Теперь сервис app использует образ из Container Registry вместо сборки из docker-файл. Ещё мы используем порт хота 80.

Поднимаем наши контейнеры:

docker compose up -d

Без удобного клиента Docker Desktop проверить какие контейнеры запущены можно командой:

docker ps

Фаервол на виртуальной машине мы ещё не настраивали, поэтому мы должны увидеть наш сайт снаружи:

И убедившись в том, что всё работает, останавливаем и удаляем контейнеры:

docker compose down

Теперь попробуем запустить наше приложение с базами данных от Selectel. Как создать базы данных в Selectel, вы уже знаете. Я прошлые базы данных удалил, поэтому создаю новые пользуясь своей же инструкцией, удобно =)

cd ~
mkdir dev-db
cd dev-db
nano ./docker-compose.yml

Содержимое файла docker-compose.yml:

name: "weather-forecast"

networks:
  weather-forecast-net:

services:
  app:
    image: "cr.selcloud.ru/deploy2production/weather-forecast-app-img:v2.0"
    container_name: "weather-forecast-app"
    networks:
      - weather-forecast-net
    ports:
      - "80:80"
    environment:
       ASPNETCORE_ENVIRONMENT: Development
       DOTNET_PRINT_TELEMETRY_MESSAGE: false
       ConnectionStrings__Postgres: Host=192.168.0.107;User Id=delilah;Password=*******;Database=weatherforecast
       ConnectionStrings__Redis: 192.168.0.222:6379,password==*********

В этот раз запустим приложение в интерактивном режиме, чтобы увидеть лог:

docker compose up

И мы видим, что приложение успешно запускается и работает, но происходит ошибка при выполнении второго sql-скрипта, который настраивает схему базы данных, создает пользователя для приложения. Вот такой вот сюрприз, пользователь, которого мы создали через интерфейс личного кабинет (а это единственный доступный вариант), просто не имеет необходимых прав. Такое вот ограничение облачной базы данных Postgres в Selectel, связано это с реализацией на стороне Selectel. Но не унываем, значит нам нужно будет учесть этот момент и внести изменения в свой код ;)

Останавливаем приложение, Ctrl+C. Удаляем:

docker compose down

Давайте, для полноты картины создадим compose файлы для приложения и утилиты настройки базы данных так, как бы мы делали в "бою".

cd ~
mkdir prod
cd prod
mkdir setup
cd setup
nano ./docker-compose.yml
services:
  setup:
    image: "cr.selcloud.ru/deploy2production/weather-forecast-setup-img:v2.0"
    container_name: "weather-forecast-setup"
    environment:
       ConnectionStrings__Postgres: Host=192.168.0.107;User Id=delilah;Password=pwd;Database=weatherforecast
docker compose up
cd ~/prod
mkdir app
cd app
nano ./docker-compose.yml
name: "weather-forecast"

networks:
  weather-forecast-net:

services:
  app:
    image: "cr.selcloud.ru/deploy2production/weather-forecast-app-img:v2.0"
    container_name: "weather-forecast-app"
    networks:
      - weather-forecast-net
    ports:
      - "80:80"
    environment:
       ASPNETCORE_ENVIRONMENT: Production
       DOTNET_PRINT_TELEMETRY_MESSAGE: false
       ConnectionStrings__Postgres: Host=192.168.0.107;User Id=delilah;Password=pwd;Database=weatherforecast
       ConnectionStrings__Redis: 192.168.0.222:6379,password==pwd
docker compose up -d
docker compose ps

Подведем итоги. Мы разобрались на базовом уровне как разрабатывать, упаковывать и распространять приложение с помощью docker-а, и запускать его потом на виртуальной машине. Теперь дальше мы будем двигаться глубже =)