cogini.elixir-release

elixir-release

Diese Ansible-Rolle installiert Elixir/Phoenix Releases.

Sie verwendet Erlang "Releases" mit systemd zur Prozessüberwachung, wie in "Elixir-Apps mit Ansible bereitstellen" und "Best Practices für die Bereitstellung von Elixir-Apps" beschrieben.

Verzeichnisstruktur

Es verwendet eine Struktur ähnlich wie Capistrano zur Verwaltung der Release-Dateien. Das Basisverzeichnis trägt den Namen der Anwendung, z. B. /srv/foo, mit einem darunter liegenden releases-Verzeichnis. Wenn die Rolle ein Release bereitstellt, erstellt sie ein Verzeichnis mit einem Zeitstempel, z. B. /srv/foo/releases/20190603T072116. Die Dateien werden entpackt und ein Symlink von /srv/foo/current wird auf das neue Verzeichnis gesetzt.

Neustart

Nach der Bereitstellung des Releases wird die App neu gestartet, damit sie live wird.

Standardmäßig, wenn elixir_release_restart_method: systemctl, geschieht dies durch die Ausführung:

sudo /bin/systemctl restart foo

Das Bereitstellungsbenutzerkonto benötigt ausreichende Berechtigungen, um die App neu zu starten. Anstatt dem Bereitstellungskonto volle sudo-Rechte zu geben, wird eine benutzerspezifische sudo-Konfigurationsdatei angegeben, die festlegt, welche Befehle ausgeführt werden können, z. B. /etc/sudoers.d/deploy-foo:

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

Es wäre besser, wenn wir überhaupt keine sudo-Rechte benötigen würden. Eine Option ist es, systemd zu verwenden, um die App neu zu starten.

Setzen Sie elixir_release_restart_method: systemd_flag, der Bereitstellungsprozess erstellt eine /srv/foo/flags/restart.flag-Datei auf der Festplatte, nachdem der Code bereitgestellt wurde. Systemd bemerkt dies und startet die App mit dem neuen Code neu.

Siehe mix-deploy-example für ein vollständiges Beispiel.

Beispiel-Playbook

Ein minimales Playbook für eine App namens foo:

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

Legen Sie dies in ansible/playbooks/deploy-app.yml ab.

Zuerst richten Sie die Zielmaschine ein, z. B. durch Installation von Paketen und Erstellen von Verzeichnissen. Führen Sie dies von Ihrem Entwicklungsrechner aus aus und geben Sie einen Benutzer mit sudo-Rechten an:

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

Nächster Schritt: den Code bereitstellen. Führen Sie dies vom Build-Server aus aus, von einem Benutzerkonto mit ssh-Zugriff auf das Bereitstellungskonto auf der Zielmaschine:

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

Ein stärker angepasstes Playbook:

- 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

Rollenvariablen

System zum Erstellen von Releases, entweder "mix" oder "distillery".

elixir_release_release_system: "mix"

Standort der App zur Abrufung der Release-Dateien. Standardmäßig wird davon ausgegangen, dass Sie ein ansible-Verzeichnis in Ihrem Quellcode haben.

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

Erlang-Name der Anwendung, der von Distillery verwendet wird, um Verzeichnisse und Skripte zu benennen.

elixir_release_app_name: my_app

Name des Releases, standardmäßig app_name, oft aber auch MIX_ENV.

elixir_release_release_name: "{{ elixir_release_app_name }}"

Externer Name der App, der zum Benennen des systemd-Dienstes und der Verzeichnisse verwendet wird. Standardmäßig werden Unterstriche in Bindestriche umgewandelt:

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

Elixir-Anwendungsname. Standardmäßig ist es die CamelCase-Version des Anwendungsnamens:

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

Version der App, die bereitgestellt werden soll. Wenn nicht angegeben, wird sie aus der Datei start_erl.data im Release-Verzeichnis gelesen.

elixir_release_version: "0.1.0"

Aus Sicherheitsgründen verwenden wir separate Konten für die Bereitstellung und Ausführung der App. Das Bereitstellungskonto besitzt den Code und die Konfigurationsdateien und hat das Recht, die App neu zu starten. Normalerweise verwenden wir ein separates Konto namens deploy. Die App läuft unter einem separaten Konto mit den minimal erforderlichen Berechtigungen. Wir erstellen normalerweise einen Namen, der mit der App übereinstimmt, z. B. foo oder verwenden einen generischen Namen wie app.

Die Release-Dateien gehören deploy:app mit Modus 0644, damit die App sie lesen kann.

OS-Konto, das die Release-Dateien bereitstellt und besitzt:

elixir_release_deploy_user: deploy

OS-Gruppe, die die Release-Dateien bereitstellt und besitzt:

elixir_release_deploy_group: "{{ elixir_release_deploy_user }}"

OS-Konto, unter dem die App läuft:

elixir_release_app_user: "{{ elixir_release_service_name }}"

OS-Gruppe, unter der die App läuft:

elixir_release_app_group: "{{ elixir_release_app_user }}"

Umgebungsvariable der Anwendungsbereitstellung, d. h. die Einstellung von MIX_ENV, verwendet, um die Release-Datei im _build-Verzeichnis zu finden:

elixir_release_mix_env: prod

Verzeichnisprefix für Release-Dateien:

elixir_release_base_dir: /srv

Basisverzeichnis für Bereitstellungsverzeichnisse:

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

Verzeichnisse unter dem Bereitstellungsverzeichnis.

Wo Release-Tarballs entpackt werden:

elixir_release_releases_dir: "{{ elixir_release_deploy_dir }}/releases"

Derzeitig laufendes Release (Symlink):

elixir_release_current_dir: "{{ elixir_release_deploy_dir }}/current"

Standort der Bereitstellungsskripte:

elixir_release_scripts_dir: "{{ elixir_release_deploy_dir }}/bin"

Verzeichnis für Flag-Dateien, das verwendet wird, um den Neustart zu signalisieren:

elixir_release_flags_dir: "{{ elixir_release_deploy_dir }}/flags"

Verzeichnisse, in denen die App ihre Dateien aufbewahrt, gemäß systemd.

elixir_release_app_dirs:
  - configuration
  - runtime

Ob conform verwendet werden soll:

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

Wie wir die App neu starten sollen:

elixir_release_restart_method: systemctl
# elixir_release_restart_method: systemd_flag
# elixir_release_restart_method: touch

Mögliche Optionen sind:

  • systemctl, das systemctl restart foo ausführt
  • systemd_flag, das die Datei {{ elixir_release_shutdown_flags_dir }}/restart.flag berührt
  • touch, das die Datei {{ elixir_release_shutdown_flags_dir }}/restart.flag berührt. Verzeichnisberechtigungen sind 0770, sodass der verwaltete Prozess sich selbst neu starten kann.

Welche Benutzer dürfen die App mit sudo /bin/systemctl restart neu starten, wenn die Methode == systemctl ist.

elixir_release_restart_users:
    - "{{ elixir_release_deploy_user }}"

Setzen Sie auf [], sodass niemand neu starten kann, oder fügen Sie zusätzliche Namen hinzu, z. B. - "{{ elixir_release_app_user }}".

systemd und Skripte

Standardmäßig geht diese Rolle davon aus, dass Sie mix_systemd zur Generierung der systemd-Einheitendatei und mix_deploy zur Generierung von Lebenszyklus-Skripten verwenden.

elixir_release_systemd_source steuert die Quelle der systemd-Einheitendatei.

elixir_release_systemd_source: mix_systemd

Mit dem Standardwert mix_systemd kopiert die Rolle die systemd-Einheitendateien aus dem _build/{{ elixir_release_mix_env }}/systemd-Verzeichnis. Stellen Sie es auf self ein, und diese Rolle generiert eine systemd-Einheitendatei aus einer Vorlage.

elixir_release_scripts_source steuert die Quelle der Skripte.

elixir_release_scripts_source: bin

Mit dem Standardwert bin kopiert die Rolle Skripte aus dem bin-Verzeichnis des Projekts nach /srv/foo/bin auf dem Zielsystem. Stellen Sie es auf mix_deploy ein, wenn Sie output_dir_per_env: true in der mix_deploy-Konfiguration gesetzt haben, wobei die generierten Skripte unter _build gespeichert werden.

Die folgenden Variablen werden bei der Erstellung der systemd-Einheitendatei verwendet:

Port, auf dem die App auf HTTP-Verbindungen hört:

elixir_release_http_listen_port: 4000

Port, auf dem die App auf HTTPS-Verbindungen hört:

elixir_release_https_listen_port: 4001

Limit für offene Dateien:

elixir_release_limit_nofile: 65536

Sekunden warten zwischen Neustarts:

elixir_release_systemd_restart_sec: 5

LANG-Umgebungsvariable:

elixir_release_lang: "en_US.UTF-8"

umask:

elixir_release_umask: "0027"

Zielversion von systemd, die verwendet wird, um fortgeschrittenere Funktionen zu aktivieren:

elixir_release_systemd_version: 219

Typ des systemd-Dienstes: simple | exec | notify | forking Siehe systemd Type

Befehlszeile, um die App zu starten. mix nutzt start für simple, daemon für forking. distillery nutzt foreground für simple, start für forking.

elixir_release_start_command: start

PID-Datei bei Verwendung des forsierenden Diensttyps:

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

Liste von ExecStartPre-Skripten in der systemd-Einheitendatei:

elixir_release_exec_start_pre: []

Liste von Umgebungsvariablen, die in der systemd-Einheitendatei gesetzt werden sollen:

elixir_release_env_vars: []

Abhängigkeiten

Keine

Anforderungen

Keine

Lizenz

MIT

Autoreninformationen

Jake Morrison jake@cogini.com

Über das Projekt

Deploy an Elixir app

Installieren
ansible-galaxy install cogini.elixir-release
Lizenz
mit
Downloads
108
Besitzer
Product development services for ambitious innovators