123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417 |
- #!/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" "worker"' ;; # 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 \
- worker 'Confugure container with worker queues' 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 compile the needed PHP extensions and build the container locally? (May provide better performance but requires more than 1GiB of RAM)" 0 0 \
- --defaultno \
- 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 feeds' \
- 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
|