92 lines
3 KiB
Python
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',
|
|
},
|
|
})
|