Replace gunicorn with uwsgi, use persistent db connections #90

Merged
Oleg-Komarov merged 3 commits from asgi-to-wsgi into main 2024-04-25 15:11:09 +02:00
10 changed files with 75 additions and 56 deletions

View File

@ -1,16 +0,0 @@
"""
ASGI config for blender_extensions project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'blender_extensions.settings')
application = get_asgi_application()

View File

@ -120,6 +120,7 @@ WSGI_APPLICATION = 'blender_extensions.wsgi.application'
DATABASES = { DATABASES = {
'default': dj_database_url.config(default='sqlite:///{}'.format(BASE_DIR / 'db.sqlite3')), 'default': dj_database_url.config(default='sqlite:///{}'.format(BASE_DIR / 'db.sqlite3')),
} }
DATABASES['default']['CONN_MAX_AGE'] = None
# Password validation # Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators

View File

@ -48,18 +48,7 @@
tags: tags:
- dotenv - dotenv
- name: Copying ASGI config files - import_tasks: tasks/configure_uwsgi.yaml
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: 0644
loop:
- { src: templates/asgi/asgi.service, dest: "/etc/systemd/system/{{ service_name }}.service" }
notify:
- restart service
tags:
- asgi
- gunicorn
- import_tasks: tasks/deploy.yaml - import_tasks: tasks/deploy.yaml

View File

@ -0,0 +1,13 @@
---
- name: Copying uWSGI config files
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: 0644
loop:
- { src: templates/uwsgi/uwsgi.ini, dest: "/etc/uwsgi/{{ service_name }}.ini" }
- { src: templates/uwsgi/uwsgi.service, dest: "/etc/systemd/system/{{ service_name }}.service" }
notify:
- restart service
tags:
- uwsgi

View File

@ -1,24 +0,0 @@
[Unit]
Description={{ project_name }} {{ env|capitalize }}
After=syslog.target network.target
[Service]
User={{ user }}
Group={{ group }}
EnvironmentFile={{ env_file }}
ExecStart={{ dir.source }}/.venv/bin/gunicorn {{ asgi_module }} -b 127.0.0.1:{{ port }} --max-requests {{ max_requests }} --max-requests-jitter {{ max_requests_jitter }} --workers {{ workers }} -k uvicorn.workers.UvicornWorker
ExecReload=/bin/kill -s HUP $MAINPID
Restart=always
KillMode=mixed
Type=notify
SyslogIdentifier={{ service_name }}
NotifyAccess=all
WorkingDirectory={{ dir.source }}
PrivateTmp=true
ProtectHome=true
ProtectSystem=full
CapabilityBoundingSet=~CAP_SYS_ADMIN
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,34 @@
[uwsgi]
uid = {{ user }}
gid = {{ group }}
pidfile = {{ uwsgi_pid }}
env = DJANGO_SETTINGS_MODULE={{ django_settings_module }}
env = LANG=en_US.UTF-8
# Django-related settings
# the base directory (full path)
chdir = {{ dir.source }}
# Django's wsgi file
module = {{ uwsgi_module }}
# the virtualenv (full path)
virtualenv = {{ dir.source }}/.venv/
buffer-size = 32768
max-requests = 5000
# process-related settings
master = true
# maximum number of worker processes
processes = 4
# listen on HTTP port, use Keep-Alive
http11-socket = 127.0.0.1:{{ port }}
http-keepalive = 1
# clear environment on exit
vacuum = true
# silence "OSError: write error" generated by timing out clients
disable-write-exception = true
# running behind a proxy_pass, X-FORWARDED-FOR is the "real" IP address that should be logged
log-x-forwarded-for = true
# disable request logging: web server in front of uWSGI does this job better
disable-logging = true

View File

@ -0,0 +1,23 @@
[Unit]
Description={{ project_name }} {{ env|capitalize }} service.
After=syslog.target
[Service]
User={{ user }}
Group={{ group }}
EnvironmentFile={{ env_file }}
ExecStart={{ dir.source }}/.venv/bin/uwsgi --ini /etc/uwsgi/{{ service_name }}.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
SyslogIdentifier={{ service_name }}
NotifyAccess=all
WorkingDirectory={{ dir.source }}
PrivateTmp=true
ProtectHome=true
ProtectSystem=full
CapabilityBoundingSet=~CAP_SYS_ADMIN
[Install]
WantedBy=multi-user.target

View File

@ -3,9 +3,8 @@ project_name: Blender Extensions
project_slug: blender-extensions project_slug: blender-extensions
service_name: "{{ project_slug }}-{{ env }}" service_name: "{{ project_slug }}-{{ env }}"
background_service_name: '{{ service_name }}-background.service' background_service_name: '{{ service_name }}-background.service'
asgi_module: blender_extensions.asgi:application
django_settings_module: blender_extensions.settings django_settings_module: blender_extensions.settings
uwsgi_module: blender_extensions.wsgi:application
max_requests: 1000 max_requests: 1000
max_requests_jitter: 50 max_requests_jitter: 50
port: 8200 port: 8200
@ -21,6 +20,7 @@ dir:
errors: "/var/www/{{ service_name }}/html/errors" errors: "/var/www/{{ service_name }}/html/errors"
env_file: "{{ dir.source }}/.env" env_file: "{{ dir.source }}/.env"
uwsgi_pid: "{{ dir.source }}/{{ service_name }}.pid"
nginx: nginx:
user: www-data user: www-data

View File

@ -49,6 +49,5 @@ six==1.16.0
sqlparse==0.4.2 sqlparse==0.4.2
toml==0.10.2 toml==0.10.2
urllib3==1.26.11 urllib3==1.26.11
uvicorn==0.18.2
webencodings==0.5.1 webencodings==0.5.1
yarl==1.7.2 yarl==1.7.2

View File

@ -1,3 +1,3 @@
-r requirements.txt -r requirements.txt
psycopg2==2.9.3 psycopg2==2.9.3
gunicorn==20.1.0 uwsgi==2.0.23