From e143b36c32f08793bd0908b611a8c252f14ce667 Mon Sep 17 00:00:00 2001 From: Thomas Sibley Date: Wed, 16 Jun 2021 16:44:28 -0700 Subject: [PATCH] Run our uWSGI apps as separate systemd services Simplifies our setup by ditching the Debian/Ubuntu-specific multi-app uWSGI framework and converging on systemd as our common service supervisor. One big upside is that now deploys only have to restart/reload the updated app instead of all apps. The individual uwsgi@*.service units for each app are still not enabled or started or otherwise managed by Ansible yet, as doing so requires bringing in a bit more of our deployment process first. However, this change helps ratchet towards that future. Deployment of this change will not change the status of any services. To switch from the single multi-app service to the individual app services, with a brief period of downtime for each, run: systemctl stop uwsgi systemctl disable uwsgi for app in api-{production,testing} husky-musher; do systemctl enable uwsgi@$app systemctl start uwsgi@$app done --- backoffice.yaml | 14 ++----- .../system/prometheus-uwsgi-exporter@.service | 4 +- files/etc/systemd/system/uwsgi@.service | 25 +++++++++++ .../uwsgi/apps-available/api-production.ini | 2 + .../etc/uwsgi/apps-available/api-testing.ini | 2 + .../etc/uwsgi/apps-available/husky-musher.ini | 2 + files/etc/uwsgi/base.ini | 22 ++++++++++ tasks/uwsgi.yaml | 42 ++++++------------- 8 files changed, 71 insertions(+), 42 deletions(-) create mode 100644 files/etc/systemd/system/uwsgi@.service create mode 100644 files/etc/uwsgi/apps-available/api-production.ini create mode 100644 files/etc/uwsgi/apps-available/api-testing.ini create mode 100644 files/etc/uwsgi/apps-available/husky-musher.ini create mode 100644 files/etc/uwsgi/base.ini diff --git a/backoffice.yaml b/backoffice.yaml index da9c744..0ea4a4a 100644 --- a/backoffice.yaml +++ b/backoffice.yaml @@ -5,6 +5,10 @@ become: true vars: app_user: ubuntu + uwsgi_apps: + - api-production + - api-testing + - husky-musher tasks: - import_tasks: tasks/apt-update.yaml @@ -29,16 +33,6 @@ name: prometheus state: reloaded - - name: uwsgi is restarted - service: - name: uwsgi - state: restarted - - - name: uwsgi is reloaded - service: - name: uwsgi - state: reloaded - - name: promtail is restarted service: name: promtail diff --git a/files/etc/systemd/system/prometheus-uwsgi-exporter@.service b/files/etc/systemd/system/prometheus-uwsgi-exporter@.service index 7aa3c12..edad77a 100644 --- a/files/etc/systemd/system/prometheus-uwsgi-exporter@.service +++ b/files/etc/systemd/system/prometheus-uwsgi-exporter@.service @@ -1,7 +1,7 @@ [Unit] Description=Prometheus uWSGI exporter for %i -After=uwsgi.service -BindsTo=uwsgi.service +After=uwsgi@%i.service +BindsTo=uwsgi@%i.service [Service] User=prometheus diff --git a/files/etc/systemd/system/uwsgi@.service b/files/etc/systemd/system/uwsgi@.service new file mode 100644 index 0000000..a379b57 --- /dev/null +++ b/files/etc/systemd/system/uwsgi@.service @@ -0,0 +1,25 @@ +[Unit] +Description=uWSGI server for %i app +Before=multi-user.target +Before=graphical.target +After=remote-fs.target +After=network-online.target +Wants=network-online.target +Wants=prometheus-uwsgi-exporter@%i.service + +[Service] +ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/base.ini --ini /etc/uwsgi/apps-available/%i.ini +ExecReload=/bin/kill -HUP $MAINPID +RuntimeDirectory=uwsgi/app/%i +# Newer versions of systemd export RUNTIME_DIRECTORY automatically, but not the +# version we have. +Environment=RUNTIME_DIRECTORY=%t/uwsgi/app/%i +User=www-data +Group=www-data +Restart=on-failure +KillSignal=SIGQUIT +Type=notify +NotifyAccess=all + +[Install] +WantedBy=default.target diff --git a/files/etc/uwsgi/apps-available/api-production.ini b/files/etc/uwsgi/apps-available/api-production.ini new file mode 100644 index 0000000..f874af6 --- /dev/null +++ b/files/etc/uwsgi/apps-available/api-production.ini @@ -0,0 +1,2 @@ +[uwsgi] +ini = /opt/backoffice/id3c-production/uwsgi.ini diff --git a/files/etc/uwsgi/apps-available/api-testing.ini b/files/etc/uwsgi/apps-available/api-testing.ini new file mode 100644 index 0000000..17b152d --- /dev/null +++ b/files/etc/uwsgi/apps-available/api-testing.ini @@ -0,0 +1,2 @@ +[uwsgi] +ini = /opt/backoffice/id3c-testing/uwsgi.ini diff --git a/files/etc/uwsgi/apps-available/husky-musher.ini b/files/etc/uwsgi/apps-available/husky-musher.ini new file mode 100644 index 0000000..a37a10f --- /dev/null +++ b/files/etc/uwsgi/apps-available/husky-musher.ini @@ -0,0 +1,2 @@ +[uwsgi] +ini = /opt/backoffice/husky-musher/uwsgi.ini diff --git a/files/etc/uwsgi/base.ini b/files/etc/uwsgi/base.ini new file mode 100644 index 0000000..c1d1b90 --- /dev/null +++ b/files/etc/uwsgi/base.ini @@ -0,0 +1,22 @@ +# Originally based on the Ubuntu defaults in /usr/share/uwsgi/conf/default.ini. +# Expects to be run under the systemd uwsgi@.service template. +[uwsgi] +# try to autoload appropriate plugin if "unknown" option has been specified +autoload = true + +# enable main process manager +master = true + +# start a couple worker/child processes by default +processes = 2 + +# automatically stop child procs when the main proc goes away +no-orphans = true + +# app and stats sockets +socket = $(RUNTIME_DIRECTORY)/socket +stats = $(RUNTIME_DIRECTORY)/stats +chmod-socket = 660 + +# place timestamps into log +log-date = true diff --git a/tasks/uwsgi.yaml b/tasks/uwsgi.yaml index 2a7aeac..993b22c 100644 --- a/tasks/uwsgi.yaml +++ b/tasks/uwsgi.yaml @@ -5,41 +5,23 @@ - uwsgi - uwsgi-plugin-python3 -- name: uwsgi is enabled - service: - name: uwsgi - enabled: yes - state: started - name: uwsgi base config exists copy: - remote_src: true - src: /usr/share/uwsgi/conf/default.ini + src: files/etc/uwsgi/base.ini dest: /etc/uwsgi/base.ini - force: no - backup: yes - -- name: uwsgi base config enables stats - community.general.ini_file: - path: /etc/uwsgi/base.ini - section: uwsgi - option: stats - # See the comments in /etc/uwsgi/base.ini (as copied from the original - # source above) for where these %(…) substitutions come from. - value: /run/uwsgi/%(deb-confnamespace)/%(deb-confname)/stats - backup: yes - notify: - - uwsgi is reloaded + owner: root + group: root + mode: ugo=r -- name: uwsgi default invocation is configured - lineinfile: - path: /etc/default/uwsgi - regexp: '^INHERITED_CONFIG=' - line: 'INHERITED_CONFIG=/etc/uwsgi/base.ini' - notify: - # Restart not reload since the actual options used to invoke uWSGI changed, - # not just the contents of its config files. - - uwsgi is restarted +- name: uwsgi app configs exists + loop: "{{ uwsgi_apps }}" + copy: + src: "files/etc/uwsgi/apps-available/{{ item }}.ini" + dest: /etc/uwsgi/apps-available/ + owner: root + group: root + mode: ugo=r - name: uwsgi app logs readable by adm group file: