apache/scripts/webapps/flask/install_flask_site.py
2023-12-02 01:31:04 +01:00

198 lines
6.6 KiB
Python

#!/usr/bin/python3 -u
import sys, os
import subprocess
import argparse
import platform
import shutil
import pathlib
import distro
import pwd
import getpass
import re
#import pymysql.cursors
#pymysql.install_as_MySQLdb
pyv=platform.python_version_tuple()
if pyv[0]!='3':
print('Need python 3 for execute this script')
sys.exit(1)
parser = argparse.ArgumentParser(description='Script for create a flask site.')
parser.add_argument('--domain', help='The domain where is the site', required=True)
parser.add_argument('--home_user', help='The name of the new user', required=True)
parser.add_argument('--git_url', help='Url for download the last tag of app, can be used for update app', required=True)
parser.add_argument('--user', help='The name of the domain user', required=True)
parser.add_argument('--dependencies', help='The dependencies of the flask app separated by commas', required=True)
parser.add_argument('--app_flask', help='The string type app:app for load in gunicorn', required=True)
#parser.add_argument('--port', help='The port of the gunicorn application', required=True)
parser.add_argument('--path', help='The path of the flask install')
args = parser.parse_args()
linux_distro=distro.id()
home_user=args.home_user
if home_user.find('/', -1)==-1:
print("Error: you need backslash in home_user option")
exit(1)
user=args.user
apache_cmd='apache2'
apachectl='apache2ctl'
if linux_distro!='debian' and linux_distro!='ubuntu':
apache_cmd='httpd'
apachectl='apachectl'
if linux_distro=='rocky' or linux_distro=='fedora':
apache_group='apache'
if linux_distro=='arch':
apache_group='http'
system_user=getpass.getuser()
if os.path.isdir(home_user):
print("Cleaning %s directory" % home_user)
if subprocess.call("sudo su %s -s /bin/bash -c 'rm -f -r %s'" % (user, home_user), shell=True) > 0:
print('Error: cannot clean directory {}'.format(home_user))
sys.exit(1)
"""
if linux_distro=='debian' or linux_distro=='ubuntu':
#libapache2-mod-wsgi-py3/
if subprocess.call("sudo apt-get update && sudo apt-get upgrade && sudo apt-get install libapache2-mod-wsgi-py3", shell=True) > 0:
print('Error: cannot install mod_wsgi for apache')
sys.exit(1)
"""
print("Creating virtualenv for the flask app...")
if subprocess.call("sudo su %s -s /bin/bash -c 'mkdir -p %s && python3 -m venv %s/venv'" % (user, home_user, home_user), shell=True) > 0:
print('Error: cannot install python virtualenv in {}'.format(home_user))
sys.exit(1)
dependencies=args.dependencies
if subprocess.call("sudo su %s -s /bin/bash -c '%s/venv/bin/pip install %s flask gunicorn'" % (user, home_user, dependencies.replace(',', ' ')), shell=True) > 0:
print('Error: cannot install python virtualenv dependencies in {}'.format(home_user))
sys.exit(1)
num_proc=str(os.cpu_count()*2+1)
name=os.path.basename(home_user[:-1]).strip()
#port=int(args.port)
if not re.match('\w+:\w+', args.app_flask):
print('Error: define the app_flask with app:app format')
sys.exit(1)
path='/'
if args.path:
if args.path.find('/', -1)==-1:
print("Error: you need backslash in path option")
exit(1)
path=args.path[:-1]
if path=='':
path='/'
print("Creating the service for flask app with gunicorn...")
with open('./%s-%s.service' % (args.domain, name), 'w') as f:
f.write("# Save it in /etc/systemd/system/%s-%s.service\n" % (args.domain, name))
f.write("[Unit]\n")
f.write("Description=App %s\n" % name)
f.write("After=syslog.target\n")
f.write("After=network.target\n")
f.write("[Service]\n")
f.write("Type=simple\n")
f.write("User=%s\n" % user)
f.write("Group=%s\n" % user)
f.write("WorkingDirectory=%s/app\n" % home_user)
f.write("ExecStart=%svenv/bin/gunicorn -w%s -b unix:%sgunicorn.sock --timeout 300 --error-logfile %s%s-error.log --access-logfile %s%s-access.log --reload %s\n" % (home_user, num_proc, home_user, home_user, name, home_user, name, args.app_flask))
f.write("Restart=always\n")
f.write("Environment=USER=%s HOME=/home/%s\n" % (user, user))
f.write("[Install]\n")
f.write("WantedBy=multi-user.target\n")
print("Downloading application using git...")
if subprocess.call('sudo cp ./%s-%s.service /etc/systemd/system' % (args.domain, name), shell=True) > 0:
print('Error: cannot install app service in systemd...')
sys.exit(1)
if subprocess.call("sudo su %s -s /bin/bash -c 'git clone %s %sapp && cd %sapp && export GTAG=$(git describe --tags `git rev-list --tags --max-count=1`) && git checkout $GTAG -b latest-$GTAG'" % (user, args.git_url, home_user, home_user), shell=True) > 0:
print('Error: cannot download git packages in {}app'.format(home_user))
sys.exit(1)
if path=='/':
base_name_file='{}-001-{}.conf'.format(args.domain, name)
else:
base_name_file='{}-000-{}.conf'.format(args.domain, name)
name_file='/home/{}/{}'.format(system_user, base_name_file)
with open(name_file, 'w') as f:
f.write("ProxyPreserveHost On")
f.write("ProxyRequests Off")
f.write("<Location %s>\n" % path[:1])
#ProxyPass unix:/home/root/flask_rest/flaskrest.sock|http://127.0.0.1/
f.write("ProxyPass unix:%sgunicorn.sock|http://127.0.0.1%s\n" % (home_user, path))
f.write("ProxyPassReverse unix:%sgunicorn.sock|http://127.0.0.1%s\n" % (home_user, path))
if path!='/':
f.write("RequestHeader set SCRIPT_NAME %s" % path[:1])
f.write("RequestHeader set X-Forwarded-Proto http")
f.write("RequestHeader set X-Forwarded-Prefix %s" % path[:1])
f.write("</Location>\n")
if path=='/':
f.write("<Location /.well-known/acme-challenge/>\n")
f.write("ProxyPass !\n")
f.write("</Location>\n")
print('Updating apache configuration for wordpress outside of htdocs...')
if subprocess.call('sudo mv {} /etc/{}/vhosts.d/extra && sudo chown root:root /etc/{}/vhosts.d/extra/{}'.format(name_file, apache_cmd, apache_cmd, base_name_file), shell=True) > 0:
print('Error')
sys.exit(1)
print("Preparing apache for use gunicorn...")
if linux_distro=='debian' or linux_distro=='ubuntu':
if subprocess.call('sudo a2enmod proxy_http', shell=True) > 0:
print("Error: cannot enable proxy_http in apache in debian/ubuntu distro")
sys.exit(1)
service=args.domain+'-'+name
if subprocess.call("sudo systemctl enable %s && sudo systemctl start %s && sudo systemctl restart %s" % (service, service, apache_cmd), shell=True) > 0:
print("Error: cannot update and restart apache")
sys.exit(1)
print("Flask app install successfully!")