Replace gunicorn with uwsgi, use persistent db connections #90
@ -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()
|
@ -120,6 +120,7 @@ WSGI_APPLICATION = 'blender_extensions.wsgi.application'
|
||||
DATABASES = {
|
||||
'default': dj_database_url.config(default='sqlite:///{}'.format(BASE_DIR / 'db.sqlite3')),
|
||||
}
|
||||
DATABASES['default']['CONN_MAX_AGE'] = None
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
|
||||
|
@ -48,18 +48,7 @@
|
||||
tags:
|
||||
- dotenv
|
||||
|
||||
- name: Copying ASGI config files
|
||||
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/configure_uwsgi.yaml
|
||||
|
||||
- import_tasks: tasks/deploy.yaml
|
||||
|
||||
|
13
playbooks/tasks/configure_uwsgi.yaml
Normal file
13
playbooks/tasks/configure_uwsgi.yaml
Normal 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
|
@ -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
|
34
playbooks/templates/uwsgi/uwsgi.ini
Normal file
34
playbooks/templates/uwsgi/uwsgi.ini
Normal 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
|
23
playbooks/templates/uwsgi/uwsgi.service
Normal file
23
playbooks/templates/uwsgi/uwsgi.service
Normal 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
|
@ -3,9 +3,8 @@ project_name: Blender Extensions
|
||||
project_slug: blender-extensions
|
||||
service_name: "{{ project_slug }}-{{ env }}"
|
||||
background_service_name: '{{ service_name }}-background.service'
|
||||
|
||||
asgi_module: blender_extensions.asgi:application
|
||||
django_settings_module: blender_extensions.settings
|
||||
uwsgi_module: blender_extensions.wsgi:application
|
||||
max_requests: 1000
|
||||
max_requests_jitter: 50
|
||||
port: 8200
|
||||
@ -21,6 +20,7 @@ dir:
|
||||
errors: "/var/www/{{ service_name }}/html/errors"
|
||||
|
||||
env_file: "{{ dir.source }}/.env"
|
||||
uwsgi_pid: "{{ dir.source }}/{{ service_name }}.pid"
|
||||
|
||||
nginx:
|
||||
user: www-data
|
||||
|
@ -49,6 +49,5 @@ six==1.16.0
|
||||
sqlparse==0.4.2
|
||||
toml==0.10.2
|
||||
urllib3==1.26.11
|
||||
uvicorn==0.18.2
|
||||
webencodings==0.5.1
|
||||
yarl==1.7.2
|
||||
|
@ -1,3 +1,3 @@
|
||||
-r requirements.txt
|
||||
psycopg2==2.9.3
|
||||
gunicorn==20.1.0
|
||||
uwsgi==2.0.23
|
||||
|
Loading…
Reference in New Issue
Block a user