elixir-release

elixir-release

Эта роль Ansible развертывает релизы Elixir/Phoenix.

Она использует "релизы" Erlang с systemd для управления процессами, как описано в "Развертывание приложений Elixir с использованием Ansible" и "Лучшие практики развертывания приложений Elixir".

Структура директорий

Она использует структуру, похожую на Capistrano, для управления файлами релиза. Основная директива называется по имени приложения, например, /srv/foo, и имеет поддиректорию releases. Когда роль разворачивает релиз, она создает директорию с меткой времени, например, /srv/foo/releases/20190603T072116. Все файлы распаковываются в эту директорию, и создается символическая ссылка из /srv/foo/current на новую директорию.

Перезапуск

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

По умолчанию, когда elixir_release_restart_method: systemctl, это происходит с помощью команды:

sudo /bin/systemctl restart foo

У учетной записи пользователя развертывания должны быть соответствующие разрешения для перезапуска приложения. Вместо того, чтобы предоставлять учетной записи развертывания полный доступ к sudo, в конкретном конфигурационном файле sudo указывается, какие команды она может выполнять, например, /etc/sudoers.d/deploy-foo:

deploy ALL=(ALL) NOPASSWD: /bin/systemctl start foo, /bin/systemctl stop foo, /bin/systemctl restart foo

Лучше, если нам не нужно совсем предоставлять разрешения sudo. Один из вариантов - воспользоваться systemd для перезапуска приложения.

Установите elixir_release_restart_method: systemd_flag, процесс развертывания создаст файл restart.flag в директории /srv/foo/flags/ после развертывания кода. Systemd заметит и перезапустит его с новым кодом.

Смотрите mix-deploy-example для полного примера.

Пример плейбука

Минимальный плейбук для приложения под названием foo:

- hosts: '*'
  become: true
  vars:
    elixir_release_app_name: foo
  roles:
    - cogini.elixir-release

Положите это в ansible/playbooks/deploy-app.yml.

Сначала настройте целевую машину, например, установив пакеты и создав директории. Запустите это с вашей рабочей машины, указав пользователя с правами sudo:

ansible-playbook -u $USER -v -l web_servers playbooks/deploy-app.yml --skip-tags deploy -D

Затем разверните код. Запустите это с сервера сборки, от имени учетной записи пользователя с доступом по ssh к учетной записи развертывания на целевой машине:

ansible-playbook -u deploy -v -l web_servers playbooks/deploy-app.yml --tags deploy --extra-vars ansible_become=false -D

Более сильно настроенный плейбук:

- hosts: '*'
  become: true
  vars:
    elixir_release_app_name: foo
    elixir_release_app_user: bar
    elixir_release_deploy_user: deploy
    elixir_release_mix_env: frontend
    elixir_release_systemd_source: mix_systemd
    elixir_release_base_dir: /opt/bar
    elixir_release_app_dirs:
      - configuration
      - runtime
      - logs
      - tmp
      - state
      - cache
    elixir_release_tmp_directory_base: /var/tmp/bar
    elixir_release_state_directory_base: /var/bar
    elixir_release_http_listen_port: 8080
    elixir_release_cache_directory_mode: 0700
    elixir_release_configuration_directory_mode: 0755
    elixir_release_logs_directory_mode: 0755
    elixir_release_state_directory_mode: 0755
    elixir_release_tmp_directory_mode: 0755
    elixir_release_sudoers_file: "{{ elixir_release_app_user }}-{{ elixir_release_service_name }}"
    elixir_release_src_dir: "{{ playbook_dir }}/../../../foo"
  roles:
    - cogini.elixir-release

Переменные роли

Система, используемая для сборки релизов, либо "mix", либо "distillery".

elixir_release_release_system: "mix"

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

elixir_release_app_dir: "{{ role_path }}/../../.."

Имя Erlang приложения, используемое Distillery для названия директорий и скриптов.

elixir_release_app_name: my_app

Имя релиза, по умолчанию app_name, но часто MIX_ENV.

elixir_release_release_name: "{{ elixir_release_app_name }}"

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

elixir_release_service_name: "{{ elixir_release_app_name | replace('_', '-') }}"

Имя приложения Elixir. По умолчанию это версия CamelCase имени приложения:

elixir_release_app_module: "{{ elixir_release_service_name.title().replace('_', '') }}"

Версия приложения для релиза. Если не указана, будет считаться из файла start_erl.data в директории релиза.

elixir_release_version: "0.1.0"

Для безопасности мы используем отдельные учетные записи для развертывания приложения и его работы. Учетная запись развертывания владеет кодом и файлами конфигурации, и имеет право перезапускать приложение. Обычно мы используем отдельную учетную запись под названием deploy. Приложение работает под отдельной учетной записью с минимально необходимыми правами. Обычно мы создаем имя, совпадающее с названием приложения, например, foo, или используем общее название, например, app.

Файлы релиза принадлежат deploy:app с режимом 0644, чтобы приложение могло их читать.

Учетная запись ОС, которая разворачивает и владеет файлами релиза:

elixir_release_deploy_user: deploy

Группа ОС, которая разворачивает и владеет файлами релиза:

elixir_release_deploy_group: "{{ elixir_release_deploy_user }}"

Учетная запись ОС, под которой запускается приложение:

elixir_release_app_user: "{{ elixir_release_service_name }}"

Группа ОС, под которой работает приложение:

elixir_release_app_group: "{{ elixir_release_app_user }}"

Среда релиза приложения, т.е. установка MIX_ENV, используемая для поиска файла релиза в директории _build:

elixir_release_mix_env: prod

Префикс директории для файлов релиза:

elixir_release_base_dir: /srv

Основная директория для файлов развертывания:

elixir_release_deploy_dir: "{{ elixir_release_base_dir }}/{{ elixir_release_service_name }}"

Директории под директориями развертывания.

Где распаковываются tarball'ы релиза:

elixir_release_releases_dir: "{{ elixir_release_deploy_dir }}/releases"

В настоящее время работающий релиз (символическая ссылка):

elixir_release_current_dir: "{{ elixir_release_deploy_dir }}/current"

Расположение скриптов развертывания:

elixir_release_scripts_dir: "{{ elixir_release_deploy_dir }}/bin"

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

elixir_release_flags_dir: "{{ elixir_release_deploy_dir }}/flags"

Директории, в которых приложение хранит свои файлы, следуя systemd.

elixir_release_app_dirs:
  - configuration
  - runtime
  # - logs
  # - tmp
  # - state
  # - cache

Нужно ли использовать conform:

elixir_release_conform: false
elixir_release_conform_conf_path: "{{ elixir_release_configuration_dir }}/config.conform"

Как мы должны перезапустить приложение:

elixir_release_restart_method: systemctl
# elixir_release_restart_method: systemd_flag
# elixir_release_restart_method: touch

Варианты:

  • systemctl, что выполняет systemctl restart foo
  • systemd_flag, который создает файл {{ elixir_release_shutdown_flags_dir }}/restart.flag
  • touch, который создает файл {{ elixir_release_shutdown_flags_dir }}/restart.flag. Права директории 0770, позволяя управляемому процессу перезапускать себя.

Какие пользователи имеют право перезапускать приложение с помощью sudo /bin/systemctl restart, когда метод == systemctl.

elixir_release_restart_users:
    - "{{ elixir_release_deploy_user }}"

Установите [], чтобы никто не мог перезапустить, или добавьте дополнительные имена, например: - "{{ elixir_release_app_user }}".

systemd и скрипты

По умолчанию эта роль предполагает, что вы используете mix_systemd для генерации файла unit systemd и mix_deploy для генерации скриптов жизненного цикла.

elixir_release_systemd_source управляет источником файла unit systemd.

elixir_release_systemd_source: mix_systemd

С настройкой по умолчанию mix_systemd, роль копирует файлы unit systemd из директории _build/{{ elixir_release_mix_env }}/systemd. Установите значение self, и эта роль сгенерирует файл unit systemd из шаблона.

elixir_release_scripts_source управляет источником скриптов.

elixir_release_scripts_source: bin

С настройкой по умолчанию bin, роль копирует скрипты из директории bin проекта в /srv/foo/bin на целевой системе. Установите значение mix_deploy, если вы установили output_dir_per_env: true в конфигурации mix_deploy, сохраняя сгенерированные скрипты под директорией _build.

Следующие переменные используются при генерации файла unit systemd:

Порт, на котором приложение слушает HTTP соединения:

elixir_release_http_listen_port: 4000

Порт, на котором приложение слушает HTTPS соединения:

elixir_release_https_listen_port: 4001

Лимит открытых файлов:

elixir_release_limit_nofile: 65536

Секунды ожидания между перезапусками:

elixir_release_systemd_restart_sec: 5

Переменная окружения LANG:

elixir_release_lang: "en_US.UTF-8"

umask:

elixir_release_umask: "0027"

Целевая версия systemd, используемая для включения более продвинутых функций:

elixir_release_systemd_version: 219

Тип службы systemd: simple | exec | notify | forking Смотрите тип systemd Type

Команда релиза для запуска приложения. mix использует start для simple, daemon для forking. distillery использует foreground для simple, start для forking.

elixir_release_start_command: start

Файл PID при использовании типа службы forking:

elixir_release_pid_file: "{{ elixir_release_runtime_dir }}/{{ elixir_release_app_name}}.pid"

Список скриптов ExecStartPre в файле unit systemd:

elixir_release_exec_start_pre: []

Список переменных окружения для установки в файле unit systemd:

elixir_release_env_vars: []

Зависимости

Нет

Требования

Нет

Лицензия

MIT

Информация об авторе

Jake Morrison jake@cogini.com

О проекте

Deploy an Elixir app

Установить
ansible-galaxy install cogini/ansible-role-elixir-release
Лицензия
mit
Загрузки
95
Владелец
Product development services for ambitious innovators