From 0e9737ee39a5e9b818dded2169d990240016b8d0 Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Sat, 20 Mar 2021 23:09:50 +0000 Subject: [PATCH] [TOOLS][DOCKER] Rewrite the configuration script to use whiptail/dialog, and refactor --- .gitignore | 4 +- bin/bootstrap_certificates | 37 -- bin/configure | 717 +++++++++++----------- docker/bootstrap/bootstrap.sh | 72 +-- docker/certbot/docker-compose.fragment.sh | 27 + docker/db/docker-compose.fragment.sh | 31 + docker/mail/Dockerfile | 16 +- docker/mail/docker-compose.fragment.sh | 21 + docker/nginx/docker-compose.fragment.sh | 52 ++ docker/nginx/domain.sh | 3 +- docker/nginx/nginx.conf | 4 +- docker/php/docker-compose.fragment.sh | 34 + docker/redis/docker-compose.fragment.sh | 11 + docker/social/db | 14 - docker/social/mail | 18 - docker/social/nginx | 29 - docker/social/php | 21 - docker/social/redis | 8 - 18 files changed, 594 insertions(+), 525 deletions(-) delete mode 100755 bin/bootstrap_certificates create mode 100644 docker/certbot/docker-compose.fragment.sh create mode 100644 docker/db/docker-compose.fragment.sh create mode 100644 docker/mail/docker-compose.fragment.sh create mode 100644 docker/nginx/docker-compose.fragment.sh create mode 100644 docker/php/docker-compose.fragment.sh create mode 100644 docker/redis/docker-compose.fragment.sh delete mode 100755 docker/social/db delete mode 100755 docker/social/mail delete mode 100755 docker/social/nginx delete mode 100755 docker/social/php delete mode 100755 docker/social/redis diff --git a/.gitignore b/.gitignore index 3f1a83bac5..bfe57bf63d 100644 --- a/.gitignore +++ b/.gitignore @@ -29,8 +29,10 @@ DOCUMENTATION/database/* !DOCUMENTATION/database/database.pdf -docker/certbot +docker/certbot/* +!docker/certbot/docker-compose.fragment.sh docker/*/*.env +docker/mail/config/* docker-compose.yaml composer.local.json diff --git a/bin/bootstrap_certificates b/bin/bootstrap_certificates deleted file mode 100755 index 605ee99609..0000000000 --- a/bin/bootstrap_certificates +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -printf "Domain root: " -read -r domain_root -printf "Subdomain (can be empty): " -read -r sub_domain -printf "Use certificate signed by Let's Encrypt (Y/n): " -read -r signed - -[ "${signed}" = "${signed#[Yy]}" ] -signed=$? - -if [ $signed -ne 0 ]; then - printf "Email: " - read -r email -fi - -if [ -z "$sub_domain" ] -then - domain="${domain_root}" -else - domain="${sub_domain}.${domain_root}" -fi - -mkdir -p ./docker/bootstrap - -cat > ./docker/bootstrap/bootstrap.env <&1 -domain_root=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "Domain root:" $HEIGHT $WIDTH \ - 2>&1 1>&3) -check_retval $? -exec 3>&- -check_input $domain_root +# ------------ 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 +# -------------------------------------------------------------------------- -exec 3>&1 -sub_domain=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "Subdomain (can be empty):" $HEIGHT $WIDTH \ - 2>&1 1>&3) -check_retval $? -exec 3>&- -exec 3>&1 -signed=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --menu "Use certificate signed by Let's Encrypt?" $HEIGHT $WIDTH 2 \ - "Y" "" \ - "n" "" \ - 2>&1 1>&3) -check_retval $? -exec 3>&- - -[ "${signed}" = "${signed#[Yy]}" ] -signed=$? - - -if [ $signed -ne 0 ]; then - exec 3>&1 - email=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "Email:" $HEIGHT $WIDTH \ - 2>&1 1>&3) - check_retval $? - exec 3>&- - check_input $email -fi - -if [ -z "$sub_domain" ] -then - domain="${domain_root}" +# ------------ 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 - domain="${sub_domain}.${domain_root}" + echo "whiptail/dialog are not available, can't proceed" + exit 1 fi -mkdir -p $ROOT/docker/bootstrap +# 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 +} +# -------------------------------------------------------------------------- -cat > $ROOT/docker/bootstrap/bootstrap.env <&1 1>&2 2>&3) +validate_exit $? +case ${SERVICES} in + 'docker') DOCKER='"nginx" "certbot" "php" "db" "redis" "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 +# -------------------------------------------------------------------------- -chmod +x ./docker/bootstrap/bootstrap.env -docker-compose -f docker/bootstrap/bootstrap.yaml up -git_dir=$PWD -while [ ! -d .git ]; do - git_dir=$(dirname "${git_dir}") +# ------------ 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 -cd "${git_dir}" || exit +if [ "${DBMS}" = 'postgres' ]; then DB_USER="postgres"; else DB_USER="social"; fi +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 -if [ ! -f ./docker/bootstrap/bootstrap.env ]; then - printf "bootstrap.env missing! Please run the bootstrap_certificates script.\n" - exit 1 +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 -. ./docker/bootstrap/bootstrap.env - -exec 3>&1 -dbms=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --menu "Select DBMS:" $HEIGHT $WIDTH 2 \ - "postgres" "" \ - "mariadb" "" \ - 2>&1 1>&3) -check_retval $? -exec 3>&- - -exec 3>&1 -db=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "GNU social database name:" $HEIGHT $WIDTH \ - 2>&1 1>&3) -check_retval $? -exec 3>&- - -if [ "${dbms}" = 'mariadb' ] -then - exec 3>&1 - user=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "Database user:" $HEIGHT $WIDTH \ - 2>&1 1>&3) - check_retval $? - exec 3>&- - check_input $user +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 +# -------------------------------------------------------------------------- -exec 3>&1 -password=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "Database password:" $HEIGHT $WIDTH \ - 2>&1 1>&3) -check_retval $? -exec 3>&- -check_input $password -exec 3>&1 -sitename=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "Sitename:" $HEIGHT $WIDTH \ - 2>&1 1>&3) -check_retval $? -exec 3>&- -check_input $sitename - -exec 3>&1 -admin_nick=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "Admin nickname:" $HEIGHT $WIDTH \ - 2>&1 1>&3) -check_retval $? -exec 3>&- -check_input $admin_nick - -exec 3>&1 -admin_password=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "Admin password:" $HEIGHT $WIDTH \ - 2>&1 1>&3) -check_retval $? -exec 3>&- -check_input $admin_password - -exec 3>&1 -profile=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --menu "Site profile:" $HEIGHT $WIDTH 4 \ - "public" "" \ - "private" "" \ - "community" "" \ - "single_user" "" \ - 2>&1 1>&3) -check_retval $? -exec 3>&- - -exec 3>&1 -mailer_dsn=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "Mailer dsn:" $HEIGHT $WIDTH \ - 2>&1 1>&3) -check_retval $? -exec 3>&- -check_input $mailer_dsn - -mkdir -p $ROOT/docker/db - -if [ "${dbms}" = 'mariadb' ]; then - exec 3>&1 - db_root_password=$(dialog \ - --title "Configure" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "DB root password" $HEIGHT $WIDTH \ - 2>&1 1>&3) - check_retval $? - exec 3>&- - check_input $db_root_password - - cat > $ROOT/docker/db/db.env <&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 - cat > $ROOT/docker/db/db.env <> .env.local +${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 -mkdir -p $ROOT/docker/social +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 -cat > $ROOT/docker/social/social.env <&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 -------------- +if echo "${DOCKER}" | grep -Fq '"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 'sendmail://localhost' \ + 3>&1 1>&2 2>&3) + validate_exit $? + if [ -n "${MAILER_DSN}" ]; then break; fi + done +fi + +if echo "${DOCKER}" | grep -Fvq '"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 $? + + 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" 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 (name without @domain)" 0 0 \ + 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 +# -------------------------------------------------------------------------- + + + +# --------------- Ensure we have the needed certificates ------------------- +mkdir -p "${INSTALL_DIR}/docker/bootstrap" +cat > "${INSTALL_DIR}/docker/bootstrap/bootstrap.env" <> "${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" < "${INSTALL_DIR}/docker/db/db.env" <> .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" < "${INSTALL_DIR}/docker/mail/mail.env" <&1 -docker_compose=$(dialog \ - --title "Services" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --checklist "Services to include in docker-compose:" $HEIGHT $WIDTH 6 \ - "nginx" "" on \ - "certbot" "" on \ - "php" "" on \ - "db" "" on \ - "redis" "" on \ - "mail" "" on \ - 2>&1 1>&3) -check_retval $? -exec 3>&- +# Config postfix +sed -ri \ + -e "s/^\s*myhostname\s*=.*/myhostname = ${MAILNAME}/" \ + -e "s/^\s*mydomain\s*=.*/mydomain = ${DOMAINNAME}/" \ + -e "s/^\s*smtpd_tls_cert_file\s*=.*/smtpd_tls_cert_file = ${SSL_CERT}/" \ + -e "s/^\s*smtpd_tls_key_file\s*=.*/smtpd_tls_key_file = ${SSL_KEY}/" \ + "${INSTALL_DIR}/docker/mail/config/postfix/main.cf" -echo "version: '3.3'" > docker-compose.yaml -echo "\nservices:" >> docker-compose.yaml +# Config dovecot +sed -ri \ + -e "s/^\s*ssl_cert\s*=.*/ssl_cert = <${SSL_CERT}/" \ + -e "s/^\s*ssl_key\s*=.*/ssl_key = <${SSL_KEY}/" \ + -e "s/^\s*postmaster_address\s*=.*/postmaster_address = postmaster@${DOMAINNAME}/" \ + "${INSTALL_DIR}/docker/mail/config/dovecot/dovecot.conf" -case $docker_compose in *"nginx"*) - $ROOT/docker/social/nginx -esac +# Config dkim +sed -i -e "s/^.*#HOSTNAME/${MAILNAME}#HOSTNAME/" "${INSTALL_DIR}/docker/mail/config/opendkim/TrustedHosts" -case $docker_compose in *"certbot"*) - $ROOT/docker/social/certbot -esac +# Prepare mail user +echo "${MAIL_DOMAIN_ROOT} #OK" > "${INSTALL_DIR}/docker/mail/config/domains" +echo "${MAIL_USER} ${MAIL_USER}" > "${INSTALL_DIR}/docker/mail/config/aliases" +echo "${MAIL_USER} ${MAIL_DOMAIN_ROOT}/${MAIL_USER}/" > "${INSTALL_DIR}/docker/mail/config/mailboxes" +echo "${MAIL_USER}:${HASHED_PASSWORD}" > "${INSTALL_DIR}/docker/mail/config/passwd" +# -------------------------------------------------------------------------- -case $docker_compose in *"php"*) - $ROOT/docker/social/php -esac -case $docker_compose in *"db"*) - $ROOT/docker/social/db -esac -case $docker_compose in *"redis"*) - $ROOT/docker/social/redis -esac +# ------------------- Write docker-compose config file --------------------- +cat > "${INSTALL_DIR}/docker-compose.yaml" <&1 - mail_domain_root=$(dialog \ - --title "Configure Mail" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "E-mail domain root:" $HEIGHT $WIDTH \ - 2>&1 1>&3) - check_retval $? - exec 3>&- - check_input $mail_domain_root - - exec 3>&1 - mail_subdomain=$(dialog \ - --title "Configure Mail" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "E-mail subdomain (can be empty):" $HEIGHT $WIDTH \ - 2>&1 1>&3) - check_retval $? - exec 3>&- - - exec 3>&1 - mail_user=$(dialog \ - --title "Configure Mail" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "E-mail user (name without @domain): " $HEIGHT $WIDTH \ - 2>&1 1>&3) - check_retval $? - exec 3>&- - check_input $mail_user - - exec 3>&1 - mail_pass=$(dialog \ - --title "Configure Mail" \ - --clear \ - --ok-label "Ok" \ - --cancel-label "Exit" \ - --inputbox "E-mail user password: " $HEIGHT $WIDTH \ - 2>&1 1>&3) - check_retval $? - exec 3>&- - check_input $mail_pass - - mkdir -p $ROOT/docker/mail - - cat > $ROOT/docker/mail/mail.env <> docker-compose.yaml - +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}" +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" <"$lets_path/options-ssl-nginx.conf" + curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem >"$lets_path/ssl-dhparams.pem" - curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf >"$lets_path/options-ssl-nginx.conf" - curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem >"$lets_path/ssl-dhparams.pem" + if [ ${SIGNED} -eq 0 ]; then + echo "### Creating self signed certificate for ${DOMAIN} ..." + openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 365 \ + -keyout "${lets_path}/live/${DOMAIN}/privkey.pem" \ + -out "${lets_path}/live/${DOMAIN}/fullchain.pem" -subj "/CN=${DOMAIN}" + else + echo "### Creating dummy certificate for ${DOMAIN} ..." + openssl req -x509 -nodes -newkey rsa:1024 -days 1 \ + -keyout "${lets_path}/live/${DOMAIN}/privkey.pem" \ + -out "${lets_path}/live/${DOMAIN}/fullchain.pem" -subj '/CN=localhost' - if [ ${signed} -eq 0 ] - then - echo "### Creating self signed certificate for ${domain_root} ..." - openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 365 \ - -keyout "${lets_path}/live/${domain_root}/privkey.pem" \ - -out "${lets_path}/live/${domain_root}/fullchain.pem" -subj "/CN=${domain_root}" + nginx -s reload - else - echo "### Creating dummy certificate for ${domain_root} ..." - openssl req -x509 -nodes -newkey rsa:1024 -days 1 \ - -keyout "${lets_path}/live/${domain_root}/privkey.pem" \ - -out "${lets_path}/live/${domain_root}/fullchain.pem" -subj '/CN=localhost' + rm -Rf "${lets_path}/live/${DOMAIN}" + rm -Rf "${lets_path}/archive/${DOMAIN}" + rm -Rf "${lets_path}/renewal/${DOMAIN}.conf" - nginx -s reload + echo "### Requesting Let's Encrypt certificate for ${DOMAIN} ..." + # Format domain_args with the cartesian product of `domain_root` and `subdomains` - rm -Rf "${lets_path}/live/${domain_root}" - rm -Rf "${lets_path}/archive/${domain_root}" - rm -Rf "${lets_path}/renewal/${domain_root}.conf" - - echo "### Requesting Let's Encrypt certificate for ${domain_root} ..." - # Format domain_args with the cartesian product of `domain_root` and `subdomains` - - if [ "${domain_root}" = "${domain}" ]; then domain_arg="-d ${domain_root}"; else domain_arg="-d ${domain_root} -d ${domain}"; fi - - # Ask Let's Encrypt to create certificates, if challenge passed - certbot certonly --webroot -w "${certbot_path}" \ - --email "${email}" \ - ${domain_arg} \ - --non-interactive \ - --rsa-key-size "${rsa_key_size}" \ - --agree-tos \ - --force-renewal - fi + # if [ "${DOMAIN_ROOT}" = "${DOMAIN}" ]; then domain_arg="-d ${DOMAIN_ROOT}"; else domain_arg="-d ${DOMAIN_ROOT} -d ${DOMAIN}"; fi + # ${domain_arg} \ + # Ask Let's Encrypt to create certificates, if challenge passed + certbot certonly --webroot -w "${certbot_path}" \ + --email "${EMAIL}" \ + -d "${DOMAIN}" \ + --non-interactive \ + --rsa-key-size "${rsa_key_size}" \ + --agree-tos \ + --force-renewal + fi else - echo "Certificate related files exists, exiting" + echo "Certificate related files exists, exiting" fi diff --git a/docker/certbot/docker-compose.fragment.sh b/docker/certbot/docker-compose.fragment.sh new file mode 100644 index 0000000000..8b8664499b --- /dev/null +++ b/docker/certbot/docker-compose.fragment.sh @@ -0,0 +1,27 @@ +#!/usr/bin/sh + +cat < /dev/null; + sleep 12h & wait \$\${!}; + done' + volumes: + - ./docker/certbot/www:/var/www/certbot + - ./docker/certbot/.files:/etc/letsencrypt + +EOF diff --git a/docker/db/docker-compose.fragment.sh b/docker/db/docker-compose.fragment.sh new file mode 100644 index 0000000000..09ce6d5a09 --- /dev/null +++ b/docker/db/docker-compose.fragment.sh @@ -0,0 +1,31 @@ +#!/usr/bin/sh + +if [ "${DBMS}" = 'postgres' ]; then + cat < \ + sed -r "s/%hostname%/${DOMAIN}/g;" > \ /etc/nginx/conf.d/social.conf diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf index ce3d263ac4..d6b3a610b7 100644 --- a/docker/nginx/nginx.conf +++ b/docker/nginx/nginx.conf @@ -14,8 +14,8 @@ server { listen [::]:443 ssl http2; listen 443 ssl http2; - ssl_certificate /etc/letsencrypt/live/%hostname_root%/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/%hostname_root%/privkey.pem; + ssl_certificate /etc/letsencrypt/live/%hostname%/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/%hostname%/privkey.pem; # Let's Encrypt best practices include /etc/letsencrypt/options-ssl-nginx.conf; diff --git a/docker/php/docker-compose.fragment.sh b/docker/php/docker-compose.fragment.sh new file mode 100644 index 0000000000..c4e162c9c5 --- /dev/null +++ b/docker/php/docker-compose.fragment.sh @@ -0,0 +1,34 @@ +#!/usr/bin/sh + +cat <> docker-compose.yaml \ No newline at end of file diff --git a/docker/social/mail b/docker/social/mail deleted file mode 100755 index 0fdbe7c815..0000000000 --- a/docker/social/mail +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -echo " mail: - build: docker/mail - env_file: - - ./docker/mail/mail.env - ports: - - 25:25 - - 110:110 - - 143:143 - - 587:587 - - 993:993 - volumes: - - ./docker/mail/mail:/var/mail - - ./docker/mail/config:/etc/mail - # Certbot - - ./docker/certbot/www:/var/www/certbot - - ./docker/certbot/.files:/etc/letsencrypt\n" >> docker-compose.yaml diff --git a/docker/social/nginx b/docker/social/nginx deleted file mode 100755 index c4bc68409e..0000000000 --- a/docker/social/nginx +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -echo " nginx: - image: nginx:alpine - depends_on: - - php - restart: always - tty: false - ports: - - 80:80 - - 443:443 - volumes: - # Nginx - - ./docker/nginx/nginx.conf:/var/nginx/social.conf - - ./docker/nginx/domain.sh:/var/nginx/domain.sh - # Certbot - - ./docker/certbot/www:/var/www/certbot - - ./docker/certbot/.files:/etc/letsencrypt - # Social - - ./public:/var/www/social/public - env_file: - - ./docker/bootstrap/bootstrap.env - - ./docker/db/db.env - command: /bin/sh -c '/var/nginx/domain.sh; - while :; do - sleep 6h & wait \$\${!}; - nginx -s reload; - done & - nginx -g \"daemon off;\"'\n" >> docker-compose.yaml diff --git a/docker/social/php b/docker/social/php deleted file mode 100755 index 1c3beece05..0000000000 --- a/docker/social/php +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -echo " php: - build: docker/php - depends_on: - - db - restart: always - tty: true - ports: - - 9000:9000 - volumes: - # Entrypoint - - ./docker/php/entrypoint.sh:/entrypoint.sh - - ./docker/db/wait_for_db.sh:/wait_for_db.sh - - ./docker/social/install.sh:/var/entrypoint.d/social_install.sh - # Main files - - .:/var/www/social - env_file: - - ./docker/social/social.env - - ./docker/db/db.env - command: /entrypoint.sh\n" >> docker-compose.yaml \ No newline at end of file diff --git a/docker/social/redis b/docker/social/redis deleted file mode 100755 index 7e22d5f73e..0000000000 --- a/docker/social/redis +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -echo " redis: - image: redis:alpine - restart: always - tty: false - ports: - - 6379:6379\n" >> docker-compose.yaml \ No newline at end of file