415 lines
17 KiB
Bash
Executable File
415 lines
17 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# ------------ Find the root folder where social is installed --------------
|
|
INSTALL_DIR="${PWD}"
|
|
while true; do
|
|
if [ ! -f "${INSTALL_DIR}/social.yaml" ]; then
|
|
INSTALL_DIR="$(dirname "${INSTALL_DIR}")"
|
|
elif [ "${INSTALL_DIR}" = '/' ]; then
|
|
echo "The current folder and it's parents don't seem to contain a valid GNU social installation, exiting"
|
|
exit 1
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
cd "${INSTALL_DIR}" || exit 1
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# ------------ Check whether the system has whiptail or dialog -------------
|
|
if command -v whiptail > /dev/null 2>&1; then
|
|
WHIPTAIL=whiptail
|
|
elif command -v dialog > /dev/null 2>&1; then
|
|
WHIPTAIL=dialog
|
|
else
|
|
echo "whiptail/dialog are not available, can't proceed"
|
|
exit 1
|
|
fi
|
|
|
|
# whiptail/dialog exits with 1 when cancelling through the UI, or 255 on ^C
|
|
validate_exit () {
|
|
case $1 in
|
|
1|255) printf "Canceling...\n" && exit 2 ;;
|
|
esac
|
|
}
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
# TODO Add suport for other webservers
|
|
# ------------ Pick which services to configure through docker-compose and which to configure externally --------------
|
|
SERVICES=$(${WHIPTAIL} --title 'GNU social' --clear --backtitle 'GNU social' \
|
|
--menu "\nWelcome to the GNU social configurator. This program will help configure your GNU social node.\n\n\
|
|
Choose whether you prefer social to handle all the services it needs though docker,\nor if you'd rather use and configure your own:" 0 0 0 \
|
|
docker 'Docker service configuration' \
|
|
mixed 'Mixed docker/external service configuration' \
|
|
external 'External service configuration' \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
case ${SERVICES} in
|
|
'docker') DOCKER='"nginx" "certbot" "php" "db" "redis"' ;; # TODO enable and configure "mail"
|
|
'mixed')
|
|
DOCKER=$(${WHIPTAIL} --title 'GNU social Docker services' --clear --backtitle 'GNU social' \
|
|
--checklist "\nPick which of the following services you'd like to add to docker-compose.\n* indicates a service that has extra configuration" 0 0 0 \
|
|
nginx 'Configure NGINX' on \
|
|
certbot "Configure CertBot (automatic certificate renewing)" on \
|
|
php 'Configure PHP' on \
|
|
db 'Configure a DBMS*' on \
|
|
redis 'Configure Redis (optional, recommended)' on \
|
|
mail 'Confugure a mail server*' on \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
;;
|
|
'external') DOCKER='' ;;
|
|
esac
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# ------------ If the user requested the use of docker services, ensure we have `docker` and `docker-compose` --------------
|
|
case ${SERVICES} in
|
|
'mixed'|'docker')
|
|
if ! (command -v docker > /dev/null 2>&1 && command -v docker-compose > /dev/null 2>&1); then
|
|
echo "docker/docker-compose are not available, can't proceed"
|
|
exit 1
|
|
fi
|
|
;;
|
|
esac
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# ------------ Regarless of whether using a docker container for the DBMS or not, we need to know which we're using, and it's settings --------------
|
|
DBMS=$(${WHIPTAIL} --title 'GNU social DBMS' --clear --backtitle 'GNU social' \
|
|
--radiolist "\nPick which DBMS you'd like to use" 0 0 0 \
|
|
postgres 'Use PostgreSQL' on \
|
|
mariadb 'Use MariaDB' off \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
|
|
while true; do
|
|
DB_NAME=$(${WHIPTAIL} --title 'GNU social DB name' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter a name for the database to be used by social" 0 0 "social" \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${DB_NAME}" ]; then break; fi
|
|
done
|
|
|
|
if [ "${DBMS}" = 'postgres' ]; then DB_USER="postgres"; else DB_USER="social"; fi
|
|
if echo "${DOCKER}" | grep -Fvq '"db"'; then
|
|
while true; do
|
|
DB_USER=$(${WHIPTAIL} --title 'GNU social DB user' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter a user name for social to connect to the database under" 0 0 "${DB_USER}" \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${DB_USER}" ]; then break; fi
|
|
done
|
|
fi
|
|
while true; do
|
|
DB_PASSWORD=$(${WHIPTAIL} --title 'GNU social DB password' --clear --backtitle 'GNU social' \
|
|
--passwordbox "\nEnter a password for social to connect to the database with" 0 0 \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${DB_PASSWORD}" ]; then break; fi
|
|
done
|
|
|
|
if [ "${DBMS}" = 'postgres' ]; then DB_DSN="postgresql://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}";
|
|
else DB_DSN="mysql://${DB_USER}:${DB_PASSWORD}@db:3306/${DB_NAME}"; fi
|
|
if echo "${DOCKER}" | grep -Fvq '"db"'; then
|
|
while true; do
|
|
DB_DSN=$(${WHIPTAIL} --title 'GNU social DB DSN' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter the DSN/URL for social to connect to the database with" 0 0 \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${DB_DSN}" ]; then break; fi
|
|
done
|
|
fi
|
|
|
|
if [ "${DBMS}" != 'postgres' ] && echo "${DOCKER}" | grep -Fq '"db"'; then
|
|
while true; do
|
|
DB_ROOT_PASSWORD=$(${WHIPTAIL} --title 'GNU social DB root user password' --clear --backtitle 'GNU social' \
|
|
--passwordbox "\nEnter a password for the database root user" 0 0 \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${DB_ROOT_PASSWORD}" ]; then break; fi
|
|
done
|
|
fi
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
# -------------------------------- PHP -------------------------------------
|
|
if echo "${DOCKER}" | grep -Fq '"php"'; then
|
|
${WHIPTAIL} --title "Build PHP container locally?" --clear --backtitle 'GNU social' \
|
|
--yesno "\nDo you want to use a compile the needed PHP extensions and build the container locally? (may provide better performance, needs more than 1GiB of RAM)" 0 0 \
|
|
3>&1 1>&2 2>&3
|
|
BUILD_PHP=$((1-$?)) # Invert output
|
|
fi
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
# ------------------------ Network configuration ----------------------------
|
|
while true; do
|
|
DOMAIN_ROOT=$(${WHIPTAIL} --title 'GNU social domain root' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter the root domain from where social will be served" 0 0 \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${DOMAIN_ROOT}" ]; then break; fi
|
|
done
|
|
|
|
# Subdomain is optional
|
|
SUBDOMAIN=$(${WHIPTAIL} --title 'GNU social subdomain' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter the subdomain from where social will be served, if any" 0 0 \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -z "${SUBDOMAIN}" ]; then
|
|
DOMAIN="${DOMAIN_ROOT}"
|
|
else
|
|
DOMAIN="${SUBDOMAIN}.${DOMAIN_ROOT}"
|
|
fi
|
|
|
|
${WHIPTAIL} --title "Use Let's Encrypt certificate?" --clear --backtitle 'GNU social' \
|
|
--yesno "\nDo you want to use a certificate signed by Let's Encrypt? A self signed certificate will be created, \
|
|
as one is required, but you may provide your own" 0 0 \
|
|
3>&1 1>&2 2>&3
|
|
LE_CERT=$((1-$?)) # Invert output
|
|
|
|
if [ $LE_CERT -ne 0 ]; then
|
|
while true; do
|
|
EMAIL=$(${WHIPTAIL} --title 'GNU social admin email' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter the email to register the admin user under" 0 0 \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${EMAIL}" ]; then break; fi
|
|
done
|
|
fi
|
|
|
|
while true; do
|
|
NODE_NAME=$(${WHIPTAIL} --title 'GNU social node name' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter the name for this GNU social node" 0 0 \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${NODE_NAME}" ]; then break; fi
|
|
done
|
|
|
|
while true; do
|
|
NGINX_HTTP_PORT=$(${WHIPTAIL} --title 'GNU social HTTP port' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nWhich port should NGINX use for HTTP traffic ('host:port' is also valid)" 0 0 "80" \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${NGINX_HTTP_PORT}" ]; then break; fi
|
|
done
|
|
|
|
while true; do
|
|
NGINX_HTTPS_PORT=$(${WHIPTAIL} --title 'GNU social HTTPS port' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nWhich port should NGINX use for HTTPS traffic ('host:port' is also valid)" 0 0 "443" \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${NGINX_HTTPS_PORT}" ]; then break; fi
|
|
done
|
|
|
|
PHP_PORT=9000
|
|
if echo "${DOCKER}" | grep -Fvq '"php"'; then
|
|
while true; do
|
|
PHP_PORT=$(${WHIPTAIL} --title 'GNU social PHP service port' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nWhich port should be used for PHP" 0 0 "9000" \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${PHP_PORT}" ]; then break; fi
|
|
done
|
|
fi
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
PROFILE=$(${WHIPTAIL} --title 'GNU social site profile' --clear --backtitle 'GNU social' \
|
|
--menu "\nPick one of the following node visibility presets:" 0 0 0 \
|
|
public 'Make this node publicly accessible, with open registration' \
|
|
community 'Make this node publicly accessible, but with invite-only registration' \
|
|
isolated 'Make this node publicly accessible, with open registration but do not federate' \
|
|
private 'Make this node publicly accessible, but with invite-only registration, only registered users can see timelines' \
|
|
single_user 'Like public, but only allows registering one user' \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
|
|
|
|
|
|
# ------------ Mail server --------------
|
|
MAILER_DSN='sendmail://localhost'
|
|
if false; then
|
|
if echo "${DOCKER}" | grep -Fvq '"mail"'; then
|
|
while true; do
|
|
MAILER_DSN=$(${WHIPTAIL} --title 'GNU social mail server DSN' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter a DSN/URL social will use to connect to the mail server" 0 0 "${MAILER_DSN}" \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${MAILER_DSN}" ]; then break; fi
|
|
done
|
|
while true; do
|
|
MAIL_DOMAIN=$(${WHIPTAIL} --title 'GNU social mail server domain' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter the domain social will use to serve mail" 0 0 "${DOMAIN_ROOT}" \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${MAIL_DOMAIN}" ]; then break; fi
|
|
done
|
|
fi
|
|
|
|
if echo "${DOCKER}" | grep -Fq '"mail"'; then
|
|
while true; do
|
|
MAIL_DOMAIN_ROOT=$(${WHIPTAIL} --title 'GNU social mail server domain' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter the root domain social will use to serve mail" 0 0 "${DOMAIN_ROOT}" \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${MAIL_DOMAIN_ROOT}" ]; then break; fi
|
|
done
|
|
|
|
MAIL_SUBDOMAIN=$(${WHIPTAIL} --title 'GNU social mail server subdomain' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter a subdomain social will send email from (optional, can be empty)" 0 0 \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
|
|
if [ -z "${MAIL_SUBDOMAIN}" ]; then
|
|
MAIL_DOMAIN="${MAIL_DOMAIN_ROOT}"
|
|
else
|
|
MAIL_DOMAIN="${MAIL_SUBDOMAIN}.${MAIL_DOMAIN_ROOT}"
|
|
fi
|
|
|
|
while true; do
|
|
MAIL_SENDER_USER=$(${WHIPTAIL} --title 'GNU social mail sender user' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter the user emails should be sent from (email without @domain)" 0 0 \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${MAIL_SENDER_USER}" ]; then break; fi
|
|
done
|
|
|
|
while true; do
|
|
MAIL_SENDER_NAME=$(${WHIPTAIL} --title 'GNU social mail sender name' --clear --backtitle 'GNU social' \
|
|
--inputbox "\nEnter the name emails should be sent from" 0 0 "${NODE_NAME}" \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${MAIL_SENDER_NAME}" ]; then break; fi
|
|
done
|
|
|
|
while true; do
|
|
MAIL_PASSWORD=$(${WHIPTAIL} --title 'GNU social mail password' --clear --backtitle 'GNU social' \
|
|
--passwordbox "\nEnter a password for the user in the mail server" 0 0 \
|
|
3>&1 1>&2 2>&3)
|
|
validate_exit $?
|
|
if [ -n "${MAIL_PASSWORD}" ]; then break; fi
|
|
done
|
|
fi
|
|
fi
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# --------------- Ensure we have the needed certificates -------------------
|
|
mkdir -p "${INSTALL_DIR}/docker/bootstrap"
|
|
cat > "${INSTALL_DIR}/docker/bootstrap/bootstrap.env" <<EOF
|
|
#!/bin/sh
|
|
DOMAIN_ROOT=${DOMAIN_ROOT}
|
|
WEB_DOMAIN=${DOMAIN}
|
|
MAIL_DOMAIN=${MAIL_DOMAIN}
|
|
SIGNED=${LE_CERT}
|
|
EOF
|
|
[ -n "${EMAIL}" ] && echo EMAIL="${EMAIL}" >> "${INSTALL_DIR}/docker/bootstrap/bootstrap.env"
|
|
|
|
chmod +x ./docker/bootstrap/bootstrap.env
|
|
docker-compose -f docker/bootstrap/bootstrap.yaml up
|
|
validate_exit $?
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# ------------ Configure parameters for the creation of docker containers --------------
|
|
mkdir -p "${INSTALL_DIR}/docker/db"
|
|
if [ "${DBMS}" = 'postgres' ]; then
|
|
cat > "${INSTALL_DIR}/docker/db/db.env" <<EOF
|
|
DBMS=${DBMS}
|
|
POSTGRES_USER=postgres
|
|
POSTGRES_PASSWORD=${DB_PASSWORD}
|
|
EOF
|
|
else
|
|
cat > "${INSTALL_DIR}/docker/db/db.env" <<EOF
|
|
DBMS=${DBMS}
|
|
MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
|
|
MYSQL_DATABASE=${DB_NAME}
|
|
MYSQL_USER=${DB_USER}
|
|
MYSQL_PASSWORD=${DB_PASSWORD}
|
|
EOF
|
|
fi
|
|
|
|
touch .env.local
|
|
sed -ri 's/DATABASE_URL=.*//' .env.local
|
|
echo "DATABASE_URL=${DB_DSN}" >> .env.local
|
|
sed -ri 's/MAILER_DSN=.*//' .env.local
|
|
echo "MAILER_DSN=${MAILER_DSN}" >> .env.local
|
|
|
|
mkdir -p "${INSTALL_DIR}/docker/social"
|
|
cat > "${INSTALL_DIR}/docker/social/social.env" <<EOF
|
|
SOCIAL_DBMS=${DBMS}
|
|
SOCIAL_DB=${DB_NAME}
|
|
SOCIAL_USER=${DB_USER}
|
|
SOCIAL_PASSWORD=${DB_PASSWORD}
|
|
SOCIAL_DOMAIN=${DOMAIN}
|
|
SOCIAL_NODE_NAME=${NODE_NAME}
|
|
SOCIAL_ADMIN_EMAIL=${EMAIL}
|
|
SOCIAL_SITE_PROFILE=${PROFILE}
|
|
MAILER_DSN=${MAILER_DSN}
|
|
EOF
|
|
# --------------------------------------------------------------------------
|
|
|
|
# TODO create admin user
|
|
#SOCIAL_ADMIN_NICK="${ADMIN_NICK}"
|
|
#SOCIAL_ADMIN_PASSWORD="${ADMIN_PASSWORD}"
|
|
|
|
|
|
|
|
# --------------- Write mail configuration, and setup ----------------------
|
|
mkdir -p "${INSTALL_DIR}/docker/mail"
|
|
|
|
HASHED_PASSWORD="{SHA512-CRYPT}"$(echo "${MAIL_PASSWORD}" | openssl passwd -6 -in -)
|
|
|
|
cat > "${INSTALL_DIR}/docker/mail/mail.env" <<EOF
|
|
MAIL_DOMAIN=${MAIL_DOMAIN}
|
|
MAIL_DOMAIN_ROOT=${MAIL_DOMAIN_ROOT}
|
|
MAIL_USER=${MAIL_SENDER_USER}
|
|
MAIL_NAME=${MAIL_SENDER_NAME}
|
|
MAIL_ADDRESS=${MAIL_SENDER_USER}@${MAIL_DOMAIN}
|
|
SSL_CERT=/etc/letsencrypt/live/${MAIL_DOMAIN}/fullchain.pem
|
|
SSL_KEY=/etc/letsencrypt/live/${MAIL_DOMAIN}/privkey.pem
|
|
HASHED_PASSWORD=${HASHED_PASSWORD}
|
|
EOF
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# ------------------- Write docker-compose config file ---------------------
|
|
cat > "${INSTALL_DIR}/docker-compose.yaml" <<EOF
|
|
version: '3'
|
|
|
|
services:
|
|
EOF
|
|
|
|
export DOCKER="${DOCKER}"
|
|
export NGINX_HTTP_PORT="${NGINX_HTTP_PORT}"
|
|
export NGINX_HTTPS_PORT="${NGINX_HTTPS_PORT}"
|
|
export PHP_PORT="${PHP_PORT}"
|
|
export DBMS="${DBMS}"
|
|
export BUILD_PHP="${BUILD_PHP}"
|
|
export LE_CERT="${LE_CERT}"
|
|
|
|
for SERV in ${DOCKER}; do
|
|
SERV=$(echo "${SERV}" | sed -r 's/"([^"]*)"/\1/')
|
|
sh "${INSTALL_DIR}/docker/${SERV}/docker-compose.fragment.sh" >> "${INSTALL_DIR}/docker-compose.yaml"
|
|
done
|
|
|
|
if echo "${DOCKER}" | grep -Fq '"db"'; then
|
|
cat >> "${INSTALL_DIR}/docker-compose.yaml" <<EOF
|
|
volumes:
|
|
database:
|
|
EOF
|
|
fi
|
|
# --------------------------------------------------------------------------
|
|
|
|
cd "${OLDPWD}" || exit 1
|