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
ansible-galaxy install cogini/ansible-role-elixir-release