Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Деплой Продакшен и Деплой

Деплой

Теперь, когда у нас есть готовый образ приложения, выполним его деплой. Деплой через Docker содержит такие шаги:

  1. Скачивание нужного образа на сервера
  2. Остановка старого контейнера
  3. Запуск нового контейнера из скаченного образа

В продвинутых сценариях деплой образов выполняется с помощью Kubernetes. А здесь мы выполняем деплой напрямую, с помощью Ansible. Почему именно он? Ansible наиболее простой и удобный инструмент, из существующих, который позволяет буквально небольшим yaml файлом описать процесс деплоя и использовать его для любого количества серверов. Ansible берет на себя обработку ошибок, параллельное выполнение и многое другое.

Подготовка сервера

Подготовка сервера для деплоя Docker приложения, очень простая задача. В таком случае, вся настройка сведется добавлению ssh-ключей для доступа без пароля и установке Docker.

Создайте самый дешевый сервер (Droplet в терминах DigitalOcean, Compute Cloud у Yandex Cloud) для деплоя. Его стоимость 5$ в месяц. Здесь есть хитрость, по умолчанию DO предлагает сервера с чистыми операционными системами, но если переключиться на вкладку Markeplace, то там есть Ubuntu с предустановленным Docker. То что нам нужно.

Создание дроплета на DO

Во время создания, вам предложат выбор как подключаться к серверу: по паролю или через ssh-ключ. Выберите ssh-ключ и добавьте его. Если у вас нет ssh-ключа, то создайте его по этой инструкции.

Когда сервер будет готов, DO покажет вам его ip-адрес. Возьмите этот адрес и попробуйте подключиться к серверу по ssh. Если у вас получилось, то можно готовиться к деплою.

Подготовка к деплою

Для деплоя нам понадобится настроенный Ansible. Установите его локально на свой компьютер. Все файлы Ansible мы будем хранить в директории ansible.

Создадим плейбук, который выполняет всю работу по деплою приложения. Первым делом нам нужно установить python-пакет docker, который используется Ansible для управления Docker. В свою очередь python-пакеты устанавливаются через pip3, который тоже нужно установить. В ручную мы бы сделали это так:

# Работает на Ubuntu
apt update # обновляем список последних пакетов
apt install python3-pip
pip install docker

Теперь тоже самое, но через Ansible:

# file: ansible/release.yml
- hosts: all
  tasks:
    - apt:
        name: python3-pip
        update_cache: yes
        cache_valid_time: 604800 # 1 week

    - pip:
        name: docker

Осталось добавить старт приложения и можно пробовать запускать. Для работы с Docker у Ansible есть специальный модуль community.docker.docker_container. У него много настроек, но нам сейчас нужны лишь некоторые:

- hosts: all
  tasks:
    - apt:
        name: python3-pip
        update_cache: yes
        cache_valid_time: 604800 # 1 week

    - pip:
        name: docker

    - community.docker.docker_container:
        name: app
        # Обязательно указываем тег, который хотим деплоить
        # Если образа на сервере нет, Ansible его автоматически скачает
        image: "hexletcomponents/devops-example-app:{{ version }}"
        # Подключаем супервизор
        # Если контейнер остановится, например, из-за ошибок
        # супервизор Docker его перезапустит
        restart_policy: always
        # Запускаем, если не запущен
        state: started
        # Делаем доступным снаружи
        ports:
          - 3000:3000
        env: # Настраиваем
          NODE_ENV: production

Процесс деплоя состоит буквально из одной задачи, которая скачивает новый образ и перезапускает приложение.

Осталось создать inventory-файл. Здесь все просто. Добавляем группу webservers с одним сервером web1:

# ansible/inventory.yml
all:
  children:
    webservers: # группа веб-серверов
      hosts:
        web1: # имя сервера выбрано произвольно
          # Поменяйте на ip вашего сервера
          ansible_host: 65.108.149.193

По необходимости сюда легко добавляются новые сервера. Схема с деплоем на множество серверов рассматривается в одном из следующих уроков.

Деплой

Когда все готово, остается запустить одну команду, которая выполнит деплой:

ansible-playbook ansible/release.yml -i ansible/inventory.yml -vv --extra-vars "version=v5"

Во время деплоя передается версия, которую мы хотим выкатить. В нашем случае она совпадает с именем тега у Docker-образа и git-репозитория.

У такого способа деплоя, когда рестартует контейнер, есть одна особенность о которой нужно знать. Остановка старого контейнера и запуск нового — не моментальная операция. Какое-то время не будет запущен ни один контейнер, а значит пользователь увидит ошибку. Чтобы избежать этого, нужно перед приложением добавить реверспрокси (Nginx, Caddy, ...), в котором будет настроена обработка подобных ошибок и возврат красивой страницы с объяснением того, что происходит. Об этом в следующем уроке.

Откат

Во время деплоя могут возникнуть проблемы и тогда потребуется откат. Как его выполнять? Секрет в том, что откатов не существует. Мы всегда движемся вперед, даже если переключаемся на старую версию кода. Все что нужно — выполнить плейбук с нужной версией кода:

ansible-playbook ansible/release.yml -i ansible/inventory.yml -vv --extra-vars "version=v4"

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

Разделение плейбуков

Плейбук, который мы создали выше, состоит из двух независимых частей — настройки сервера и самого деплоя. В простейшем случае мы можем оставить все как есть, но настройка может усложниться и замедлить скорость деплоя. Поэтому, лучше, вынести настройку в отдельный плейбук и запускать ее независимо. Такая схема безопаснее, если вы захотите обновить сервер, то случайно не перезапустите приложение и наоборот, если захотите деплоить, то случайно не обновите сервер.

# Лучше перенести в другой файл
# file: ansible/setup.yml
- hosts: all
  tasks:
    - apt:
        name: python3-pip
        update_cache: yes
        cache_valid_time: 604800 # 1 week

    - pip:
        name: docker

Самостоятельная работа

  1. Создайте сервер в облачном провайдере и задеплойте туда devops-example-app

  2. Зарегистрируйте домен в любом регистраторе на выбор. Например NameCheap.com или Reg.ru

  3. Привяжите созданный домен к NS-серверам облачного провайдера. Инструкция для DO и Яндекс Облака

  4. Подключите созданный домен к серверу

В результате у вас будет создан сайт доступный по домену с указанием порта, например, example.com:3000


Дополнительные материалы

  1. Управление конфигурацией
  2. Что такое ssh
  3. Blue-Green деплой
  4. Что такое хостинг и домен сайта

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»