cogini.elixir-release
elixir-release
Ce rôle Ansible déploie des versions d'Elixir/Phoenix.
Il utilise les "versions" d'Erlang avec systemd pour la supervision des processus, comme décrit dans "Déployer des applications Elixir avec Ansible" et "Meilleures pratiques pour déployer des applications Elixir".
Structure du répertoire
Il utilise une structure similaire à Capistrano pour gérer les fichiers de version. Le répertoire de base est nommé pour l'application, par exemple /srv/foo
, avec un répertoire releases
en dessous. Lorsque le rôle déploie une version, il crée un répertoire nommé par un timestamp, par exemple /srv/foo/releases/20190603T072116
. Il décompresse les fichiers à l'intérieur, crée un lien symbolique de /srv/foo/current
vers le nouveau répertoire.
Redémarrage
Après avoir déployé la version, il redémarre l'application pour la mettre en ligne.
Par défaut, lorsque elixir_release_restart_method: systemctl
, cela se fait en exécutant :
sudo /bin/systemctl restart foo
Le compte utilisateur déployé doit avoir des permissions suffisantes pour redémarrer l'application. Au lieu de donner tous les droits sudo au compte de déploiement, un fichier de configuration sudo spécifique à l'utilisateur précise quelles commandes il peut exécuter, par exemple /etc/sudoers.d/deploy-foo
:
deploy ALL=(ALL) NOPASSWD: /bin/systemctl start foo, /bin/systemctl stop foo, /bin/systemctl restart foo
Il est préférable de ne pas nécessiter de permissions sudo du tout. Une option est de tirer parti de systemd pour redémarrer l'application.
Définissez elixir_release_restart_method: systemd_flag
, le processus de déploiement touche un fichier /srv/foo/flags/restart.flag
sur le disque après avoir déployé le code. Systemd le remarque et le redémarre avec le nouveau code.
Voir mix-deploy-example pour un exemple complet.
Exemple de Playbook
Un playbook minimal, pour une application appelée foo
:
- hosts: '*'
become: true
vars:
elixir_release_app_name: foo
roles:
- cogini.elixir-release
Mettez ceci dans ansible/playbooks/deploy-app.yml
.
Tout d'abord, configurez la machine cible, par exemple en installant des paquets et en créant des répertoires. Exécutez ceci depuis votre machine de développement, en spécifiant un utilisateur avec des permissions sudo :
ansible-playbook -u $USER -v -l web_servers playbooks/deploy-app.yml --skip-tags deploy -D
Ensuite, déployez le code. Exécutez ceci depuis le serveur de construction, à partir d'un compte utilisateur ayant un accès ssh au compte de déploiement sur la machine cible :
ansible-playbook -u deploy -v -l web_servers playbooks/deploy-app.yml --tags deploy --extra-vars ansible_become=false -D
Un playbook plus personnalisé :
- 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_release_name: "{{ elixir_release_mix_env }}"
# elixir_release_release_system: distillery
# elixir_release_start_command: foreground
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 }}"
# Emplacement de l'application source, en supposant que les scripts de déploiement sont dans un dépôt séparé dans un répertoire parallèle
elixir_release_src_dir: "{{ playbook_dir }}/../../../foo"
roles:
- cogini.elixir-release
Variables du rôle
Système utilisé pour construire des versions, soit "mix" soit "distillery".
elixir_release_release_system: "mix"
Emplacement de l'application pour obtenir les fichiers de version. Par défaut, il suppose que vous avez un répertoire ansible
dans votre source d'application.
elixir_release_app_dir: "{{ role_path }}/../../.."
Nom Erlang de l'application, utilisé par Distillery pour nommer les répertoires et les scripts.
elixir_release_app_name: my_app
Nom de la version, par défaut app_name
, mais souvent MIX_ENV.
elixir_release_release_name: "{{ elixir_release_app_name }}"
Nom externe de l'application, utilisé pour nommer le service systemd et les répertoires. Par défaut, il convertit les underscores en tirets :
elixir_release_service_name: "{{ elixir_release_app_name | replace('_', '-') }}"
Nom de l'application Elixir. Par défaut, c'est la version CamelCase du nom de l'application :
elixir_release_app_module: "{{ elixir_release_service_name.title().replace('_', '') }}"
Version de l'application à publier. Si non spécifié, il lira à partir du fichier start_erl.data
dans le répertoire de version.
elixir_release_version: "0.1.0"
Pour la sécurité, nous utilisons des comptes séparés pour déployer l'application et pour l'exécuter. Le compte de déploiement possède le code et les fichiers de configuration, et a le droit de redémarrer l'application. Nous utilisons normalement un compte séparé appelé deploy
. L'application s'exécute sous un compte séparé avec les permissions minimales dont elle a besoin. Nous créons normalement un nom correspondant à l'application, par exemple foo
, ou utilisons un nom générique comme app
.
Les fichiers de version sont la propriété de deploy:app
avec le mode 0644 afin que l'application puisse les lire.
Compte OS qui déploie et possède les fichiers de version :
elixir_release_deploy_user: deploy
Groupe OS qui déploie et possède les fichiers de version :
elixir_release_deploy_group: "{{ elixir_release_deploy_user }}"
Compte OS sous lequel l'application s'exécute :
elixir_release_app_user: "{{ elixir_release_service_name }}"
Groupe OS sous lequel l'application s'exécute :
elixir_release_app_group: "{{ elixir_release_app_user }}"
Environnement de version de l'application, c'est-à-dire le paramètre de MIX_ENV
, utilisé pour trouver le fichier de version sous le répertoire _build
:
elixir_release_mix_env: prod
Préfixe du répertoire pour les fichiers de version :
elixir_release_base_dir: /srv
Répertoire de base pour les fichiers de déploiement :
elixir_release_deploy_dir: "{{ elixir_release_base_dir }}/{{ elixir_release_service_name }}"
Répertoires sous le répertoire de déploiement.
Emplacement où les archives de version sont décompressées :
elixir_release_releases_dir: "{{ elixir_release_deploy_dir }}/releases"
Version actuellement en cours d'exécution (lien symbolique) :
elixir_release_current_dir: "{{ elixir_release_deploy_dir }}/current"
Emplacement des scripts de déploiement :
elixir_release_scripts_dir: "{{ elixir_release_deploy_dir }}/bin"
Répertoire du fichier de signalisation, utilisé pour signaler un redémarrage :
elixir_release_flags_dir: "{{ elixir_release_deploy_dir }}/flags"
Répertoires où l'application conserve ses fichiers, suivant systemd.
elixir_release_app_dirs:
- configuration
- runtime
# - logs
# - tmp
# - state
# - cache
Utiliser conform :
elixir_release_conform: false
elixir_release_conform_conf_path: "{{ elixir_release_configuration_dir }}/config.conform"
Comment redémarrer l'application :
elixir_release_restart_method: systemctl
# elixir_release_restart_method: systemd_flag
# elixir_release_restart_method: touch
Les options sont :
systemctl
, qui exécutesystemctl restart foo
systemd_flag
, qui touche le fichier{{ elixir_release_shutdown_flags_dir }}/restart.flag
touch
, qui touche le fichier{{ elixir_release_shutdown_flags_dir }}/restart.flag
. Les permissions du répertoire sont de 0770, permettant au processus géré de redémarrer lui-même.
Quels utilisateurs sont autorisés à redémarrer l'application en utilisant sudo /bin/systemctl restart
lorsque la méthode == systemctl
.
elixir_release_restart_users:
- "{{ elixir_release_deploy_user }}"
Définissez sur []
et personne ne pourra redémarrer, ou ajoutez d'autres noms, par exemple - "{{ elixir_release_app_user }}"
.
systemd et scripts
Par défaut, ce rôle suppose que vous utilisez mix_systemd pour générer le fichier unitaire systemd et mix_deploy pour générer les scripts de cycle de vie.
elixir_release_systemd_source
contrôle la source du fichier unitaire systemd.
elixir_release_systemd_source: mix_systemd
Avec la valeur par défaut de mix_systemd
, le rôle copie les fichiers unitaires systemd du
répertoire _build/{{ elixir_release_mix_env }}/systemd
. Réglez-le sur self
, et
ce rôle générera un fichier unitaire systemd à partir d'un modèle.
elixir_release_scripts_source
contrôle la source des scripts.
elixir_release_scripts_source: bin
Avec la valeur par défaut de bin
, le rôle copie des scripts du répertoire bin
du projet
vers /srv/foo/bin
sur le système cible. Réglez-le sur mix_deploy
si vous avez défini
output_dir_per_env: true
dans la configuration mix_deploy
, stockant les scripts générés sous _build
.
Les variables suivantes sont utilisées lors de la génération du fichier unitaire systemd :
Port sur lequel l'application écoute les connexions HTTP :
elixir_release_http_listen_port: 4000
Port sur lequel l'application écoute les connexions HTTPS :
elixir_release_https_listen_port: 4001
Limite de fichiers ouverts :
elixir_release_limit_nofile: 65536
Secondes à attendre entre les redémarrages :
elixir_release_systemd_restart_sec: 5
Variable d'environnement LANG
:
elixir_release_lang: "en_US.UTF-8"
umask :
elixir_release_umask: "0027"
Version cible de systemd, utilisée pour activer des fonctionnalités plus avancées :
elixir_release_systemd_version: 219
Type de service systemd : simple | exec | notify | forking Voir systemd Type
Commande de version à exécuter pour démarrer l'application. mix utilise start pour simple, daemon pour forking. distillery utilise foreground pour simple, start pour forking.
elixir_release_start_command: start
Fichier PID lors de l'utilisation du type de service forking :
elixir_release_pid_file: "{{ elixir_release_runtime_dir }}/{{ elixir_release_app_name}}.pid"
Liste des scripts ExecStartPre dans le fichier unitaire systemd :
elixir_release_exec_start_pre: []
Liste des variables d'environnement à définir dans le fichier unitaire systemd :
elixir_release_env_vars: []
Dépendances
Aucune
Exigences
Aucune
Licence
MIT
Informations sur l'auteur
Jake Morrison jake@cogini.com
ansible-galaxy install cogini.elixir-release