symposion_app/fabfile.py

92 lines
3 KiB
Python

"""Automated deployment with Fabric.
To deploy to production:
python3 -m pip install --user vps-deploy
export FABRIC_HOSTS=user@hostname
fab deploy
"""
import os
from fabric import task # type: ignore
from invoke.collection import Collection # type: ignore
from patchwork.files import exists
from vps_deploy import django_fabric2 as df2 # type: ignore
hosts = os.environ['FABRIC_HOSTS'].split(',')
def install_essentials(c):
# ImageMagick (convert) and Inkscape required for generating badges.
c.run('sudo apt-get install -yy git python3-dev python3-venv python3-wheel build-essential python3-cairocffi python3-psycopg2 postgresql uwsgi-emperor uwsgi-plugin-python3 memcached netcat nginx certbot libmemcached-dev xmlsec1 imagemagick inkscape')
@task(hosts=hosts)
def deploy(c):
install_essentials(c)
df2.transfer_files_git(c)
df2.init(c)
if not exists(c, c.env.virtualenv):
c.sudo(f'mkdir -p $(dirname {c.env.virtualenv})')
c.sudo(f'chown {c.user} $(dirname {c.env.virtualenv})')
c.run('{env.python} -m venv --system-site-packages {env.virtualenv}'.format(env=c.env))
with c.cd(c.env.project_dir):
c.run('{env.virtualenv}/bin/python -m pip install -c constraints.txt -r requirements.txt'.format(env=c.env))
# Fixes "AttributeError: install_layout". See:
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1003252
# https://github.com/pypa/setuptools/issues/3278
c.run('SETUPTOOLS_USE_DISTUTILS=stdlib {env.virtualenv}/bin/python -m pip install -c constraints.txt -r vendored_requirements.txt'.format(env=c.env))
df2.prepare_django(c, fail_level='ERROR')
df2.fix_permissions(
c,
read=['pinaxcon', 'vendor', 'static'],
read_write=[],
)
df2.reload_uwsgi(c)
df2.flush_memcached(c)
df2.update_nginx(c)
df2.install_scheduled_jobs(
c,
periodic_jobs=[
'deploy/cron/cron.daily',
],
)
df2.check_site_online(c)
# The "ns" appears to be a magic name.
ns = Collection(
deploy,
task(df2.download_postgres_db, hosts=hosts),
task(df2.mirror_postgres_db, hosts=hosts),
task(df2.mirror_media, hosts=hosts),
task(df2.django_shell, hosts=hosts),
task(df2.bash, hosts=hosts),
)
ns.configure({
# Built-in Fabric config.
'run': {
'echo': True,
# Needed so local commands work. Can also use FABRIC_RUN_REPLACE_ENV.
'replace_env': False,
},
# Our custom project config.
'env': {
'branch': 'fossy2023',
'app_user': 'www-data',
'db_name': 'symposion',
'project_dir': '/srv/symposion_app',
'media_dir': 'media',
'virtualenv': '/srv/venvs/symposion-django-py39',
'site_name': 'symposion',
'requirements': 'requirements.txt',
'settings': 'pinaxcon.settings',
'uwsgi_conf': 'deploy/uwsgi.ini',
'nginx_conf': 'deploy/nginx.conf',
'python': '/usr/bin/python3.9',
'url': 'https://2023.fossy.us/',
'domain': '2023.fossy.us',
},
})