cogini.elixir-release

elixir-release

Ta rola Ansible wdrażania wydania Elixir/Phoenix.

Używa "wydania" Erlang z systemd do nadzorowania procesów, jak opisano w "Wdrażanie aplikacji Elixir za pomocą Ansible" i "Najlepsze praktyki wdrażania aplikacji Elixir".

Struktura katalogów

Wykorzystuje strukturę podobną do Capistrano do zarządzania plikami wydania. Główny katalog nosi nazwę aplikacji, np. /srv/foo, z podkatalogiem releases. Gdy rola wdraża wydanie, tworzy katalog nazwany znakiem czasu, np. /srv/foo/releases/20190603T072116. Rozpakowuje pliki w nim, tworząc dowiązanie symboliczne z /srv/foo/current do nowego katalogu.

Restartowanie

Po wdrożeniu wydania, uruchamia ponownie aplikację, aby stała się aktywna.

Domyślnie, gdy elixir_release_restart_method: systemctl, robi to, wykonując:

sudo /bin/systemctl restart foo

Konto użytkownika wdrażającego musi mieć wystarczające uprawnienia do ponownego uruchomienia aplikacji. Zamiast dawać konto wdrożeniowe pełne uprawnienia sudo, plik konfiguracyjny sudo dla użytkownika określa, jakie polecenia może wykonywać, np. /etc/sudoers.d/deploy-foo:

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

Lepiej, gdybyśmy w ogóle nie wymagali uprawnień sudo. Jedną z opcji jest wykorzystanie systemd do ponownego uruchomienia aplikacji.

Ustaw elixir_release_restart_method: systemd_flag, proces wdrożenia dodaje plik /srv/foo/flags/restart.flag na dysku po wdrożeniu kodu. Systemd to zauważa i ponownie uruchamia aplikację z nowym kodem.

Zobacz mix-deploy-example dla pełnego przykładu.

Przykład playbooka

Minimalny playbook dla aplikacji o nazwie foo:

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

Umieść to w ansible/playbooks/deploy-app.yml.

Najpierw skonfiguruj maszynę docelową, np. instalując pakiety i tworząc katalogi. Uruchom to z komputera dewelopera, określając użytkownika z uprawnieniami sudo:

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

Następnie wdroż kod. Uruchom to z serwera budującego, z konta użytkownika z dostępem ssh do konta wdrożeniowego na maszynie docelowej:

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

Bardziej zaawansowany 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

Zmienne roli

System użyty do tworzenia wydań, "mix" lub "distillery".

elixir_release_release_system: "mix"

Lokalizacja aplikacji, z której zostaną pozyskane pliki wydania. Domyślnie zakłada, że masz katalog ansible w źródle aplikacji.

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

Erlangowa nazwa aplikacji, używana przez Distillery do nadawania nazw katalogom i skryptom.

elixir_release_app_name: my_app

Nazwa wydania, domyślnie app_name, ale często MIX_ENV.

elixir_release_release_name: "{{ elixir_release_app_name }}"

Zewnętrzna nazwa aplikacji, używana do nazwania usługi systemd i katalogów. Domyślnie zamienia znaki podkreślenia na myślniki:

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

Nazwa aplikacji Elixir. Domyślnie jest to wersja CamelCase nazwy aplikacji:

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

Wersja aplikacji do wydania. Jeśli nie jest podana, odczytana zostanie z pliku start_erl.data w katalogu wydania.

elixir_release_version: "0.1.0"

Ważne jest, aby używać oddzielnych kont do wdrażania aplikacji i do jej uruchamiania. Konto wdrożeniowe posiada kod i pliki konfiguracyjne oraz ma prawa do ponownego uruchomienia aplikacji. Zwykle używamy oddzielnego konta o nazwie deploy. Aplikacja działa pod oddzielnym kontem z minimalnymi potrzebnymi uprawnieniami. Zwykle tworzymy nazwę odpowiadającą aplikacji, np. foo lub używamy ogólnej nazwy jak app.

Pliki wydania są własnością deploy:app z prawami 0644, aby aplikacja mogła je odczytać.

Konto OS, które wdraża i posiada pliki wydania:

elixir_release_deploy_user: deploy

Grupa OS, która wdraża i posiada pliki wydania:

elixir_release_deploy_group: "{{ elixir_release_deploy_user }}"

Konto OS, pod którym działa aplikacja:

elixir_release_app_user: "{{ elixir_release_service_name }}"

Grupa OS, pod którą działa aplikacja:

elixir_release_app_group: "{{ elixir_release_app_user }}"

Środowisko wydania aplikacji, czyli ustawienie MIX_ENV, używane do znajdowania pliku wydania w katalogu _build:

elixir_release_mix_env: prod

Prefiks katalogu dla plików wydania:

elixir_release_base_dir: /srv

Katalog główny dla plików wdrożeniowych:

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

Katalogi pod katalogiem wdrożeniowym.

Gdzie pliki tar z wydaniami są rozpakowywane:

elixir_release_releases_dir: "{{ elixir_release_deploy_dir }}/releases"

Aktualnie działające wydanie (dowiązanie symboliczne):

elixir_release_current_dir: "{{ elixir_release_deploy_dir }}/current"

Lokalizacja skryptów wdrożeniowych:

elixir_release_scripts_dir: "{{ elixir_release_deploy_dir }}/bin"

Katalog plików flagowych, używany do sygnalizacji ponownego uruchomienia:

elixir_release_flags_dir: "{{ elixir_release_deploy_dir }}/flags"

Katalogi, w których aplikacja przechowuje swoje pliki, zgodnie z systemd.

elixir_release_app_dirs:
  - configuration
  - runtime

Czy używać conform:

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

Jak powinniśmy ponownie uruchomić aplikację:

elixir_release_restart_method: systemctl

Opcje to:

  • systemctl, które uruchamia systemctl restart foo
  • systemd_flag, które dotyka pliku {{ elixir_release_shutdown_flags_dir }}/restart.flag
  • touch, który dotyka pliku {{ elixir_release_shutdown_flags_dir }}/restart.flag. Uprawnienia katalogu to 0770, co pozwala zarządzanemu procesowi na samodzielne ponowne uruchomienie.

Którzy użytkownicy mogą ponownie uruchomić aplikację za pomocą sudo /bin/systemctl restart, gdy metoda == systemctl.

elixir_release_restart_users:
    - "{{ elixir_release_deploy_user }}"

Ustaw na [], aby nikt nie mógł uruchomić ponownie, lub dodaj dodatkowe nazwy, np. - "{{ elixir_release_app_user }}".

systemd i skrypty

Domyślnie ta rola zakłada, że korzystasz z mix_systemd do generowania pliku jednostki systemd oraz mix_deploy do generowania skryptów cyklu życia.

elixir_release_systemd_source określa źródło pliku jednostki systemd.

elixir_release_systemd_source: mix_systemd

Z domyślną wartością mix_systemd rola kopiuje pliki jednostki systemd z katalogu _build/{{ elixir_release_mix_env }}/systemd. Ustaw to na self, a ta rola wygeneruje plik jednostki systemd z szablonu.

elixir_release_scripts_source kontroluje źródło skryptów.

elixir_release_scripts_source: bin

Z domyślną wartością bin rola kopiuje skrypty z katalogu projektu bin do /srv/foo/bin na systemie docelowym. Ustaw to na mix_deploy, jeśli ustawiłeś output_dir_per_env: true w konfiguracji mix_deploy, przechowując wygenerowane skrypty pod _build.

Poniższe zmienne są używane podczas generowania pliku jednostki systemd:

Port, na którym aplikacja nasłuchuje połączeń HTTP:

elixir_release_http_listen_port: 4000

Port, na którym aplikacja nasłuchuje połączeń HTTPS:

elixir_release_https_listen_port: 4001

Limit otwartych plików:

elixir_release_limit_nofile: 65536

Sekundy do oczekiwania między restartami:

elixir_release_systemd_restart_sec: 5

Zmienna środowiskowa LANG:

elixir_release_lang: "en_US.UTF-8"

umask:

elixir_release_umask: "0027"

Docelowa wersja systemd, używana do włączania bardziej zaawansowanych funkcji:

elixir_release_systemd_version: 219

Typ usługi systemd: simple | exec | notify | forking Zobacz Typ

Polecenie do uruchomienia aplikacji. mix używa start dla simple, daemon dla forking. distillery używa foreground dla simple, start dla forking.

elixir_release_start_command: start

Plik PID, gdy używasz typu usługi forking:

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

Lista skryptów ExecStartPre w pliku jednostki systemd:

elixir_release_exec_start_pre: []

Lista zmiennych środowiskowych do ustawienia w pliku jednostki systemd:

elixir_release_env_vars: []

Zależności

Brak

Wymagania

Brak

Licencja

MIT

Informacje o autorze

Jake Morrison jake@cogini.com

O projekcie

Deploy an Elixir app

Zainstaluj
ansible-galaxy install cogini.elixir-release
Licencja
mit
Pobrania
108
Właściciel
Product development services for ambitious innovators