owl-installer/owl_installer.sh

242 lines
6.4 KiB
Bash

#!/usr/bin/env bash
########################################################################
#
# owl-installer (v0.4)
# Details at: https://owl.gch.icu/deploy/script/
# Home page: https://owl.gch.icu/
#
# LICENSE
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to <http://unlicense.org/>
#
#######################################################################
# Edit systemd service, socket and nginx vhost name here
OWL_SERVICE='/etc/systemd/system/owl.service'
OWL_SOCKET='/etc/systemd/system/owl.socket'
OWL_SOCK='/run/owl.sock' # literally socket file
OWL_VHOST='/etc/nginx/sites-available/owl.vhost'
# User who runs application. If it changed
#+don't forgot add www-data to your user's group!
# usermod -aG YOUR_USERNAME www-data
OWL_USER='www-data'
# Colors
R="\e[31m" # red
G="\e[32m" # green
Y="\e[33m" # yellow
B="\e[34m" # blue
N="\e[0m" # no color
PATTERN='Yes|yes|Y|y' # action confirmation words
owl_abort() {
echo -e "${R}Abort!${N}"
exit
}
echo -e "${B}owl installation script v0.4${N}"
cat <<EOF
, ,
/\\ /\\
((@v@))
((;;; (\\
\\ ;;; \\'
,V.V \`
\`\` \`\`
Home page: https://owl.gch.icu/
EOF
if [[ ! "$USER" == 'root' ]]; then
echo -e "${R}You must run this script as root.${N}"
owl_abort
fi
owl_get_domain() {
echo -n 'Enter your domain name: '
read OWL_DOMAIN
echo -en "This is correct domain?: ${Y}$OWL_DOMAIN${N} [y/N]: "
while read; do
if [[ "$REPLY" =~ $PATTERN ]]; then
echo -e "${G}Getting started...${N}"
break
else
owl_abort
fi
done
}
owl_install_requirements() {
echo -e "${G}Installing web-server and must have packages...${N}"
apt update
apt install -y git nginx python3-venv
}
owl_clone_repo() {
echo -e "${G}Cloning owl from repo...${N}"
git clone https://github.com/gechandesu/owl.git
}
owl_install_venv() {
echo -e "${G}Setting up Python virtual environment...${N}"
python3 -m venv $PWD/env
source $PWD/env/bin/activate
pip install -U pip
pip install -r $PWD/owl/requirements.txt
pip install gunicorn
deactivate
}
owl_create_service() {
echo -e "${G}Creating systemd service: $OWL_SERVICE...${N}"
if [[ ! -f "$OWL_SERVICE" ]]; then
cat > "$OWL_SERVICE" <<EOF
[Unit]
Description=gunicorn instance to serve owl knowledge base
Requires=$(basename $OWL_SOCKET)
After=network.target
[Service]
Type=notify
User=$OWL_USER
Group=$OWL_USER
# another option for an even more restricted service is
# DynamicUser=yes
# see http://0pointer.net/blog/dynamic-users-with-systemd.html
Environment="PATH=$PWD/env/bin"
WorkingDirectory=$PWD/owl
ExecStart=$PWD/env/bin/gunicorn owl:app
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
fi
}
owl_create_socket() {
echo -e "${G}Creating systemd socket: $OWL_SOCKET...${N}"
if [[ ! -f "$OWL_SOCKET" ]]; then
cat > "$OWL_SOCKET" <<EOF
[Unit]
Description=gunicorn socket for owl knowledge base
[Socket]
ListenStream=$OWL_SOCK
# Our service won't need permissions for the socket, since it
# inherits the file descriptor by socket activation
# only the nginx daemon will need access to the socket
User=www-data
# Optionally restrict the socket permissions even more.
# Mode=600
[Install]
WantedBy=sockets.target
EOF
fi
}
owl_enable_socket() {
SCK=$(basename $OWL_SOCKET)
systemctl enable --now $SCK && echo -e "${G}$SCK enabled.${N}"
}
owl_enable_service() {
SRV=$(basename $OWL_SERVICE)
systemctl start $SRV && echo -e "${G}$SRV started.${N}"
systemctl enable $SRV && echo -e "${G}$SRV enabled.${N}"
}
owl_create_nginx_vh() {
echo -e "${G}Creating nginx virtual host: $OWL_VHOST...${N}"
cat > "$OWL_VHOST" <<EOF
server {
listen 80;
#listen 443 ssl http2; # Uncomment if you have SSL certificate.
root $PWD/owl;
server_name $OWL_DOMAIN;
# Let's Encrypt SSL certifcate. Uncomment if you have SSL certificate.
#ssl_certificate /etc/letsencrypt/live/$OWL_DOMAIN/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/live/$OWL_DOMAIN/privkey.pem;
# Redirect to HTTPS. Uncomment if you have SSL certificate.
#if ($scheme != "https") {
# return 301 https://$host$request_uri;
#}
location / {
# Proxy to gunicorn
proxy_pass http://unix:$OWL_SOCK;
}
location ~* \.(css|js|jpg|jpeg|png|gif|woff|ttf)$ {
expires 1M;
add_header Cache-Control public;
}
}
EOF
}
owl_enable_site() {
echo -e "${G}Enabling site $OWL_VHOST...${N}"
ln -s "$OWL_VHOST" /etc/nginx/sites-enabled
nginx -t
service nginx reload
}
owl_done() {
echo -e "\e[32;1m@v@\nDone! ${N}"
echo -e "${G}Let's check it out in browser:${N} http://$OWL_DOMAIN/"
}
echo -en "Install owl into current directory?: ${Y}$PWD${N} [y/N]: "
while read; do
if [[ "$REPLY" =~ $PATTERN ]]; then
owl_get_domain
owl_install_requirements
owl_clone_repo
owl_install_venv
owl_create_socket
owl_create_service
owl_enable_socket
owl_enable_service
owl_create_nginx_vh
owl_enable_site
systemctl status "$(basename "$OWL_SERVICE")"
owl_done
break
else
owl_abort
fi
done