aboutsummaryrefslogtreecommitdiffstats
path: root/.debianinstall
diff options
context:
space:
mode:
Diffstat (limited to '.debianinstall')
-rw-r--r--.debianinstall/README.md158
-rw-r--r--.debianinstall/config.txt.template111
-rw-r--r--.debianinstall/debian-setup.sh527
3 files changed, 796 insertions, 0 deletions
diff --git a/.debianinstall/README.md b/.debianinstall/README.md
new file mode 100644
index 000000000..46e0e0858
--- /dev/null
+++ b/.debianinstall/README.md
@@ -0,0 +1,158 @@
+
+# How to use
+
+## Disclaimers
+
+- **This script does work with a fresh install of Debian 12 only**.
+- Do not use if you have already installed and configured a webserver or sql server that was not installed by this script.
+
+### Keep it Simple and Stupid
+
+The script keeps everything as simple as possible (KISS):
+
+- Apache as webserver (there is no choice to use another webserver like nginx)
+- default PHP version of Debian
+- one single Hubzilla intance only
+- re-running the script does no harm
+
+### When to use other Scripts
+
+Use the scripts under [homeinstall](https://framagit.org/hubzilla/core/-/tree/master/.homeinstall)
+if you look for more choices. The main differences are:
+
+- Apache or nginx as webserver
+- install multiple instances (domains) that run side by side on the server
+- adds apache vhosts (instead of using the standard doc root /var/www/html)
+- install PHP from https://packages.sury.org/php/ (instead of using the Debian repository)
+- graphical installer whiptail
+- The script stops (fails) if it finds results of a previous installation. (The [debian-setup.sh](https://framagit.org/ojrandom/core/-/tree/dev/.debianinstall) will just jump over it.)
+- If something fails the script tries to clean up everything that was installed up to the point of failure. (That might cause trouble if certbot registered a certificate already.)
+- The script under [homeinstall](https://framagit.org/hubzilla/core/-/tree/master/.homeinstall) seems to be an older version of the scripts used for Streams
+ + [autoinstall](https://codeberg.org/streams/streams/src/branch/dev/contrib/autoinstall)
+ + [easyinstall](https://codeberg.org/streams/streams/src/branch/dev/contrib/easyinstall)
+
+## Preconditions
+
+Hardware
+
++ internet connection and router at home
++ computer connected to your router (a Raspberry 3 will do for very small Hubs)
+
+Software
+
++ fresh installation of Debian 12 (bookworm)
++ router with open ports 80 and 443 for your web server
+
+You can of course run the script on a VPS or any distant server as long as the above sotfware requirements are satisfied.
+
+## How to run the script
+
++ Register your own domain (for example at selfHOST) or a free subdomain (for example at freeDNS)
++ Log on to your fresh Debian
+ - apt-get install git
+ - mkdir -p /var/www
+ - cd /var/www
+ - git clone https://framagit.org/hubzilla/core.git html
+ - cd html/.debianinstall
+ - cp config.txt.template config.txt
+ - nano config.txt
+ - read the comments carefully
+ - enter your values: db pass, domain
+ - (optionally) Enter your values for dyn DNS
+ - ./debian-setup.sh as root
+ - ... wait, wait, wait until the script is finished
++ Open your domain with a browser and step throught the initial configuration of your hubzilla instance.
+ - default database name = hubzilla
+ - default dababase user = hubzilla
+
+## Optional - Switch verification of email on/off
+
+Do this just before you register the first user without email verification.
+
+In a terminal
+
+ su -
+ cd /var/www/html
+
+Check the current setting
+
+ util/config system verify_email
+
+Switch the verification off
+
+ util/config system verify_email 0
+
+## What the script will do for you...
+
++ install everything required by your hubzilla instance, basically a web server (Apache), PHP, a database (MySQL), certbot,...
++ create a database
++ run certbot to have everything for a secure connection (httpS)
++ create a script for daily maintenance
+ - renew certfificate (letsencrypt)
+ - update of your hubzilla instance for core and addons (git)
+ - update of Debian
+ - restart
++ create cron jobs for
+ - DynDNS (selfHOST.de or freedns.afraid.org) every 5 minutes
+ - Master.php for your hubzilla instance every 10 minutes
+ - daily maintenance script every day at 05:30
+
+The script is known to work without adjustments with
+
++ Hardware
+ - standard PC with Debian 12 (bookworm)
+ - Raspberry 4 with Raspbian, Debian 12 (TODO: needs confirmation after swich to Debian12)
+ - for tesing purposes: under localhost inside a virtual machine, [KVM](https://wiki.debian.org/KVM)
++ DynDNS
+ - selfHOST.de
+ - freedns.afraid.org
+
+# Step-by-Step - some Details
+
+## Preparations
+
+## Configure your Router
+
+Your webserver has to be visible in the internet.
+
+Open the ports 80 and 443 on your router for your Debian. Make sure your web server is marked as "exposed host".
+
+## Preparations Dynamic IP Address
+
+Follow the instructions in .debianinstall/config.txt.
+
+In short...
+
+Your Hubzilla server must be reachable by a domain that you can type in your browser
+
+ cooldomain.org
+
+You can use subdomains as well
+
+ my.cooldomain.org
+
+There are two ways to get a domain...
+
+### Method 1: Buy a Domain
+
+...for example buy at selfHOST.de
+
+The cost is 1,50 € per month (2019).
+
+### Method 2: Register a free subdomain
+
+...for example register at freedns.afraid.org
+
+## Note on Rasperry
+
+It is recommended to run the Raspi without graphical frontend (X-Server). Use...
+
+ sudo raspi-config
+
+to boot the Rapsi to the client console.
+
+DO NOT FORGET TO CHANGE THE DEFAULT PASSWORD FOR USER PI!
+
+## Reminder for Different Web Wervers
+
+For those of you who feel adventurous enough to use a different web server (i.e. Lighttpd...), don't forget that this script will install Apache or Nginx and that you can only have one web server listening to ports 80 & 443. Also, don't forget to tweak your daily shell script in /var/www/ accordingly.
diff --git a/.debianinstall/config.txt.template b/.debianinstall/config.txt.template
new file mode 100644
index 000000000..1737b52ad
--- /dev/null
+++ b/.debianinstall/config.txt.template
@@ -0,0 +1,111 @@
+
+###############################################
+### MANDATORY - database password #############
+#
+# Please give your database password
+# It is better to not use blanks inside the password.
+# Example: db_pass=pass_word_with_no_blanks_in_it
+db_pass=
+
+###############################################
+### MANDATORY - let's encrypt #################
+#
+# Zot requires encrypted communication via secure HTTP (HTTPS).
+# This script automates installation of an SSL certificate from
+# Let's Encrypt (https://letsencrypt.org)
+#
+# Please give the domain name of your hub/instance
+#
+# Example: my.cooldomain.org
+# Example: cooldomain.org
+#
+# You might use "localhost" for a LOCAL TEST installation.
+# This is usefull if you want to debug the server inside a VM.
+#
+# Example: localhost
+#
+# Email is optional if you use "localhost".
+#
+#
+le_domain=
+le_email=
+
+
+###############################################
+### OPTIONAL - selfHOST - dynamic IP address ##
+#
+# 1. Register a domain at selfhost.de
+# - choose offer "DOMAIN dynamisch" 1,50€/mon at 04/2019
+# 2. Get your configuration for dynamic IP update
+# - Log in at selfhost.de
+# - go to "DynDNS Accounte"
+# - klick "Details" of your (freshly) registered domain
+# - You will find the configuration there
+# - Benutzername (user name) > use this for "selfhost_user="
+# - Passwort (pass word) > use this for "selfhost_pass="
+#
+#
+selfhost_user=
+selfhost_pass=
+
+###############################################
+### OPTIONAL - FreeDNS - dynamic IP address ###
+#
+# Please give the alpha-numeric-key of freedns
+#
+# Get a free subdomain from freedns and use it for your dynamic ip address
+# Documentation under http://www.techjawab.com/2013/06/setup-dynamic-dns-dyndns-for-free-on.html
+#
+# - Register for a Free domain at http://freedns.afraid.org/signup/
+# - WATCH THIS: Make sure you choose a domain with as less subdomains as
+# possible. Why? Let's encrpyt issues a limited count of certificates each
+# day. Possible other users of this domain will try to issue a certificate
+# at the same day.
+# - Logon to FreeDNS (where you just registered)
+# - Goto http://freedns.afraid.org/dynamic/
+# - Right click on "Direct Link" and copy the URL and paste it somewhere.
+# - You should notice a large and unique alpha-numeric key in the URL
+#
+# http://freedns.afraid.org/dynamic/update.php?alpha-numeric-key
+#
+# Provided your url from freedns is
+#
+# http://freedns.afraid.org/dynamic/update.php?U1Z6aGt2R0NzMFNPNWRjbWxxZGpsd093OjE1Mzg5NDE5
+#
+# Then you have to provide
+#
+# freedns_key=U1Z6aGt2R0NzMFNPNWRjbWxxZGpsd093OjE1Mzg5NDE5
+#
+#
+freedns_key=
+
+
+###############################################
+### OPTIONAL - do not mess with things below ##
+# (...if you are not certain)
+#
+# Usually you are done here
+# Everything below is OPTIONAL
+#
+###############################################
+#
+# Database for your hub/instance
+# If left empty, both your database and user will be named after your zot instance (hubzilla, zap or misty)
+# Use custom name, at least fo the database, if you plan to run more than one hub/instance on the same server
+#
+zotserver_db_name=
+zotserver_db_user=
+zotserver_db_pass=$db_pass
+#
+#
+# Password for package mysql-server
+# Example: mysqlpass=aberhallo
+# Example: mysqlpass="aber hallo has blanks in it"
+#
+mysqlpass=$db_pass
+
+# Password for package phpmyadmin
+# Example: phpmyadminpass=aberhallo
+# Example: phpmyadminpass="aber hallo has blanks in it"
+phpmyadminpass=$db_pass
+
diff --git a/.debianinstall/debian-setup.sh b/.debianinstall/debian-setup.sh
new file mode 100644
index 000000000..9e9b3fc1a
--- /dev/null
+++ b/.debianinstall/debian-setup.sh
@@ -0,0 +1,527 @@
+#!/bin/bash
+#
+# How to use
+# ----------
+#
+# This file automates the installation of hubzilla: https://framagit.org/hubzilla/core
+# under Debian Linux "bookworm"
+#
+# 1) Copy the file "config.txt.template" to "config.txt"
+# Follow the instuctions there
+#
+# 2) Switch to user "root" by typing "su -"
+#
+# 3) Run with "./debian-setup.sh"
+# If this fails check if you can execute the script.
+# - To make it executable type "chmod +x debian-setup.sh"
+# - or run "bash debian-setup.sh"
+#
+#
+# What does this script do basically?
+# -----------------------------------
+#
+# This file automates the installation of a Hubzilla instance under Debian Linux
+# - install
+# * apache webserver,
+# * php,
+# * mariadb,
+# * adminer,
+# * addons
+# - configure cron
+# * "Master.php" for regular background processes of your hubzilla instance
+# * "apt-get update" and "apt-get dist-upgrade" and "apt-get autoremove" to keep linux up-to-date
+# * run command to keep the IP up-to-date > DynDNS provided by selfHOST.de or freedns.afraid.org
+# - run letsencrypt to create, register and use a certifacte for https
+#
+#
+# Credits
+# -------
+#
+# The script is derived from the easyinstall script of the Streams repository, which is based on
+# - Tom Wiedenhöfts (OJ Random) script homeinstall (for Hubzilla, ZAP,...) that was based on
+# - Thomas Willinghams script "debian-setup.sh" which he used to install the red#matrix.
+
+function check_sanity {
+ # Do some sanity checking.
+ print_info "Sanity check..."
+ if [ $(/usr/bin/id -u) != "0" ]
+ then
+ die 'Must be run by root user'
+ fi
+
+ if [ -f /etc/lsb-release ]
+ then
+ die "Distribution is not supported"
+ fi
+ if [ ! -f /etc/debian_version ]
+ then
+ die "Debian is supported only"
+ fi
+ if ! grep -q 'Linux 12' /etc/issue
+ then
+ die "Linux 12 (bookworm) is supported only"x
+ fi
+}
+
+function check_config {
+ print_info "config check..."
+ # Check for required parameters
+ if [ -z "$db_pass" ]
+ then
+ die "db_pass not set in $configfile"
+ fi
+ if [ -z "$le_domain" ]
+ then
+ die "le_domain not set in $configfile"
+ fi
+}
+
+function die {
+ echo "ERROR: $1" > /dev/null 1>&2
+ exit 1
+}
+
+
+function update_upgrade {
+ print_info "updated and upgrade..."
+ # Run through the apt-get update/upgrade first. This should be done before
+ # we try to install any package
+ apt-get -q -y update && apt-get -q -y dist-upgrade && apt-get -q -y autoremove
+ print_info "updated and upgraded linux"
+}
+
+function nocheck_install {
+ # export DEBIAN_FRONTEND=noninteractive ... answers from the package configuration database
+ # - q ... without progress information
+ # - y ... answer interactive questions with "yes"
+ # DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -q -y install $2
+ # DEBIAN_FRONTEND=noninteractive apt-get --install-suggests -q -y install $1
+ DEBIAN_FRONTEND=noninteractive apt-get -q -y install $1
+ print_info "installed $1"
+}
+
+
+function print_info {
+ echo -n -e '\e[1;34m'
+ echo -n $1
+ echo -e '\e[0m'
+}
+
+function print_warn {
+ echo -n -e '\e[1;31m'
+ echo -n $1
+ echo -e '\e[0m'
+}
+
+function stop_zotserver {
+ print_info "stopping apache..."
+ systemctl stop apache2
+ print_info "stopping mysql db..."
+ systemctl stop mariadb
+}
+
+function install_apache {
+ print_info "installing apache..."
+ nocheck_install "apache2 apache2-utils"
+ a2enmod rewrite
+ systemctl restart apache2
+}
+
+function install_imagemagick {
+ print_info "installing imagemagick..."
+ nocheck_install "imagemagick"
+}
+
+function install_curl {
+ print_info "installing curl..."
+ nocheck_install "curl"
+}
+
+function install_wget {
+ print_info "installing wget..."
+ nocheck_install "wget"
+}
+
+function install_sendmail {
+ print_info "installing sendmail..."
+ nocheck_install "sendmail sendmail-bin"
+}
+
+function install_php {
+ # openssl and mbstring are included in libapache2-mod-php
+ print_info "installing php..."
+ nocheck_install "libapache2-mod-php php php-pear php-curl php-gd php-mbstring php-xml php-zip"
+ phpversion=$(php -v|grep --only-matching --perl-regexp "(PHP )\d+\.\\d+\.\\d+"|cut -c 5-7)
+ sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 100M/g" /etc/php/$phpversion/apache2/php.ini
+ sed -i "s/^post_max_size =.*/post_max_size = 100M/g" /etc/php/$phpversion/apache2/php.ini
+}
+
+function install_composer {
+ print_info "We check if Composer is already downloaded"
+ if [ ! -f /usr/local/bin/composer ]
+ then
+ EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')"
+ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
+ ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
+ if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]
+ then
+ >&2 echo 'ERROR: Invalid installer checksum'
+ rm composer-setup.php
+ die 'ERROR: Invalid installer checksum'
+ fi
+ php composer-setup.php --quiet
+ RESULT=$?
+ rm composer-setup.php
+ # exit $RESULT
+ # We install Composer globally
+ mv composer.phar /usr/local/bin/composer
+ print_info "Composer was successfully downloaded."
+ else
+ print_info "Composer is already downloaded on this system."
+ fi
+ cd $install_path
+ export COMPOSER_ALLOW_SUPERUSER=1;
+ /usr/local/bin/composer install --no-dev
+ /usr/local/bin/composer show
+ export COMPOSER_ALLOW_SUPERUSER=0;
+}
+
+
+function install_mysql {
+ print_info "installing mysql..."
+ if [ -z "$mysqlpass" ]
+ then
+ die "mysqlpass not set in $configfile"
+ fi
+ if type mysql ; then
+ echo "Yes, mysql is installed"
+ else
+ echo "mariadb-server"
+ nocheck_install "mariadb-server"
+ systemctl status mariadb
+ systemctl start mariadb
+ mysql --user=root <<_EOF_
+UPDATE mysql.user SET Password=PASSWORD('${mysqlpass}') WHERE User='root';
+DELETE FROM mysql.user WHERE User='';
+DROP DATABASE IF EXISTS test;
+DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
+FLUSH PRIVILEGES;
+_EOF_
+ fi
+}
+
+function install_adminer {
+ print_info "installing adminer..."
+ nocheck_install "adminer"
+ if [ ! -f /etc/adminer/adminer.conf ]
+ then
+ echo "Alias /adminer /usr/share/adminer/adminer" > /etc/adminer/adminer.conf
+ ln -s /etc/adminer/adminer.conf /etc/apache2/conf-available/adminer.conf
+ else
+ print_info "file /etc/adminer/adminer.conf exists already"
+ fi
+
+ a2enmod rewrite
+
+ if [ ! -f /etc/apache2/apache2.conf ]
+ then
+ die "could not find file /etc/apache2/apache2.conf"
+ fi
+ sed -i \
+ "s/AllowOverride None/AllowOverride all/" \
+ /etc/apache2/apache2.conf
+
+ a2enconf adminer
+ systemctl restart mariadb
+ systemctl reload apache2
+}
+
+function create_zotserver_db {
+ print_info "creating zotserver database..."
+ if [ -z "$db_name" ]
+ then
+ die "db_name not set in $configfile"
+ fi
+ if [ -z "$db_user" ]
+ then
+ die "db_user not set in $configfile"
+ fi
+ if [ -z "$db_pass" ]
+ then
+ die "db_pass not set in $configfile"
+ fi
+ systemctl restart mariadb
+ # Make sure we don't write over an already existing database if we install more than one Zot hub/instance
+ if [ -z $(mysql -h localhost -u root -p$mysqlpass -e "SHOW DATABASES;" | grep $db_name) ]
+ then
+ Q1="CREATE DATABASE IF NOT EXISTS $db_name;"
+ Q2="GRANT USAGE ON *.* TO $db_user@localhost IDENTIFIED BY '$db_pass';"
+ Q3="GRANT ALL PRIVILEGES ON $name.* to $db_user@localhost identified by '$db_pass';"
+ Q4="FLUSH PRIVILEGES;"
+ SQL="${Q1}${Q2}${Q3}${Q4}"
+ mysql -uroot -p$mysqlpass -e "$SQL"
+ else
+ echo "database $db_name does exist already"
+ fi
+}
+
+function run_freedns {
+ print_info "run freedns (dynamic IP)..."
+ if [ -z "$freedns_key" ]
+ then
+ print_info "freedns was not started because 'freedns_key' is empty in $configfile"
+ else
+ if [ -n "$selfhost_user" ]
+ then
+ die "You can not use freeDNS AND selfHOST for dynamic IP updates ('freedns_key' AND 'selfhost_user' set in $configfile)"
+ fi
+ wget --no-check-certificate -O - http://freedns.afraid.org/dynamic/update.php?$freedns_key
+ fi
+}
+
+function install_run_selfhost {
+ print_info "install and start selfhost (dynamic IP)..."
+ if [ -z "$selfhost_user" ]
+ then
+ print_info "selfHOST was not started because 'selfhost_user' is empty in $configfile"
+ else
+ if [ -n "$freedns_key" ]
+ then
+ die "You can not use freeDNS AND selfHOST for dynamic IP updates ('freedns_key' AND 'selfhost_user' set in $configfile)"
+ fi
+ if [ -z "$selfhost_pass" ]
+ then
+ die "selfHOST was not started because 'selfhost_pass' is empty in $configfile"
+ fi
+ if [ ! -d $selfhostdir ]
+ then
+ mkdir $selfhostdir
+ fi
+ # the old way
+ # https://carol.selfhost.de/update?username=123456&password=supersafe
+ #
+ # the prefered way
+ wget --output-document=$selfhostdir/$selfhostscript http://jonaspasche.de/selfhost-updater
+ echo "router" > $selfhostdir/device
+ echo "$selfhost_user" > $selfhostdir/user
+ echo "$selfhost_pass" > $selfhostdir/pass
+ bash $selfhostdir/$selfhostscript update
+ fi
+}
+
+function ping_domain {
+ print_info "ping domain $domain..."
+ # Is the domain resolved? Try to ping 6 times à 10 seconds
+ COUNTER=0
+ for i in {1..6}
+ do
+ print_info "loop $i for ping -c 1 $domain ..."
+ if ping -c 4 -W 1 $le_domain
+ then
+ print_info "$le_domain resolved"
+ break
+ else
+ if [ $i -gt 5 ]
+ then
+ die "Failed to: ping -c 1 $domain not resolved"
+ fi
+ fi
+ sleep 10
+ done
+ sleep 5
+}
+
+function configure_cron_freedns {
+ print_info "configure cron for freedns..."
+ if [ -z "$freedns_key" ]
+ then
+ print_info "freedns is not configured because freedns_key is empty in $configfile"
+ else
+ # Use cron for dynamich ip update
+ # - at reboot
+ # - every 30 minutes
+ if [ -z "`grep 'freedns.afraid.org' /etc/crontab`" ]
+ then
+ echo "@reboot root http://freedns.afraid.org/dynamic/update.php?$freedns_key > /dev/null 2>&1" >> /etc/crontab
+ echo "*/30 * * * * root wget --no-check-certificate -O - http://freedns.afraid.org/dynamic/update.php?$freedns_key > /dev/null 2>&1" >> /etc/crontab
+ else
+ print_info "cron for freedns was configured already"
+ fi
+ fi
+}
+
+function configure_cron_selfhost {
+ print_info "configure cron for selfhost..."
+ if [ -z "$selfhost_user" ]
+ then
+ print_info "selfhost is not configured because selfhost_key is empty in $configfile"
+ else
+ # Use cron for dynamich ip update
+ # - at reboot
+ # - every 5 minutes
+ if [ -z "`grep 'selfhost-updater.sh' /etc/crontab`" ]
+ then
+ echo "@reboot root bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab
+ echo "*/5 * * * * root /bin/bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab
+ else
+ print_info "cron for selfhost was configured already"
+ fi
+ fi
+}
+
+function install_letsencrypt {
+ print_info "installing let's encrypt ..."
+ # check if user gave domain
+ if [ -z "$le_domain" ]
+ then
+ die "Failed to install let's encrypt: 'le_domain' is empty in $configfile"
+ fi
+ if [ -z "$le_email" ]
+ then
+ die "Failed to install let's encrypt: 'le_email' is empty in $configfile"
+ fi
+ nocheck_install "certbot python-certbot-apache"
+ print_info "run certbot ..."
+ certbot --apache -w $install_path -d $le_domain -m $le_email --agree-tos --non-interactive --redirect --hsts --uir
+ service apache2 restart
+}
+
+function check_https {
+ print_info "checking httpS > testing ..."
+ url_https=https://$le_domain
+ wget_output=$(wget -nv --spider --max-redirect 0 $url_https)
+ if [ $? -ne 0 ]
+ then
+ print_warn "check not ok"
+ else
+ print_info "check ok"
+ fi
+}
+
+function install_zotserver {
+ print_info "installing addons..."
+ cd $install_path
+ util/add_addon_repo https://framagit.org/hubzilla/addons hzaddons
+ mkdir -p "store/[data]/smarty3"
+ # chmod -R 777 store
+ touch .htconfig.php
+ # The next run of $cron_job (daily-update script) will correct the permissions of the next line
+ chmod ou+w .htconfig.php
+ cd /var/www/
+ chown -R www-data:www-data $install_path
+ chown root:www-data $install_path/
+ chown root:www-data $install_path/.htaccess
+ chmod 0644 $install_path/.htaccess
+ print_info "installed addons"
+}
+
+function configure_cron_daily {
+ print_info "configuring cron..."
+ # every 10 min for poller.php
+ if [ -z "`grep 'php Zotlabs/Daemon/Master.php' /etc/crontab`" ]
+ then
+ echo "*/10 * * * * www-data cd $install_path; php Zotlabs/Daemon/Master.php Cron >> /dev/null 2>&1" >> /etc/crontab
+ fi
+ # Run external script daily at 05:30
+ # - stop apache/nginx and mysql-server
+ # - renew the certificate of letsencrypt
+ # - update repository core and addon
+ # - update and upgrade linux
+ # - reboot is done by "shutdown -h now" because "reboot" hangs sometimes depending on the system
+ echo "#!/bin/sh" > /var/www/$cron_job
+ echo "#" >> /var/www/$cron_job
+ echo "echo \" \"" >> /var/www/$cron_job
+ echo "echo \"+++ \$(date) +++\"" >> /var/www/$cron_job
+ echo "echo \" \"" >> /var/www/$cron_job
+ echo "echo \"\$(date) - stopping apache and mysql...\"" >> /var/www/$cron_job
+ echo "service apache2 stop" >> /var/www/$cron_job
+ echo "/etc/init.d/mysql stop # to avoid inconsistencies" >> /var/www/$cron_job
+ echo "#" >> /var/www/$cron_job
+ echo "echo \"\$(date) - renew certificate...\"" >> /var/www/$cron_job
+ echo "certbot renew --noninteractive" >> /var/www/$cron_job
+ echo "#" >> /var/www/$cron_job
+ echo "echo \"\$(date) - db size...\"" >> /var/www/$cron_job
+ echo "du -h /var/lib/mysql/ | grep mysql/" >> /var/www/$cron_job
+ echo "#" >> /var/www/$cron_job
+ echo "# update of $le_domain Zot hub/instance" >> /var/www/$cron_job
+ echo "echo \"\$(date) - updating core and addons...\"" >> /var/www/$cron_job
+ echo "echo \"reaching git repository for $le_domain $zotserver hub/instance...\"" >> /var/www/$cron_job
+ echo "(cd $install_path ; util/udall)" >> /var/www/$cron_job
+ echo "chown -R www-data:www-data $install_path # make all accessible for the webserver" >> /var/www/$cron_job
+ echo "chown root:www-data $install_path/.htaccess" >> /var/www/$cron_job
+ echo "chmod 0644 $install_path/.htaccess # www-data can read but not write it" >> /var/www/$cron_job
+ echo "echo \"\$(date) - updating linux...\"" >> /var/www/$cron_job
+ echo "apt-get -q -y update && apt-get -q -y dist-upgrade && apt-get -q -y autoremove # update linux and upgrade" >> /var/www/$cron_job
+ echo "echo \"\$(date) - Update finished. Rebooting...\"" >> /var/www/$cron_job
+ echo "#" >> /var/www/$cron_job
+ echo "shutdown -r now" >> /var/www/$cron_job
+
+ chmod a+x /var/www/$cron_job
+
+ # If global cron job does not exist we add it to /etc/crontab
+ if grep -q $cron_job /etc/crontab
+ then
+ echo "cron job already in /etc/crontab"
+ else
+ echo "30 05 * * * root /bin/bash /var/www/$cron_job >> /var/www/daily-updates.log 2>&1" >> /etc/crontab
+ echo "0 0 1 * * root rm /var/www/daily-updates.log" >> /etc/crontab
+ fi
+
+ # This is active after either "reboot" or cron reload"
+ systemctl restart cron
+ print_info "configured cron for updates/upgrades"
+}
+
+########################################################################
+# START OF PROGRAM
+########################################################################
+export PATH=/bin:/usr/bin:/sbin:/usr/sbin
+check_sanity
+
+print_info "We're installing a $zotserver instance"
+install_path="$(dirname "$(pwd)")"
+
+# Read config file edited by user
+configfile=config.txt
+source $configfile
+
+selfhostdir=/etc/selfhost
+selfhostscript=selfhost-updater.sh
+cron_job="cron_job.sh"
+
+#set -x # activate debugging from here
+
+zotserver=hubzilla
+check_config
+stop_zotserver
+update_upgrade
+install_curl
+install_wget
+install_sendmail
+install_apache
+install_imagemagick
+install_php
+install_composer
+install_mysql
+install_adminer
+create_zotserver_db
+run_freedns
+install_run_selfhost
+ping_domain
+configure_cron_freedns
+configure_cron_selfhost
+
+if [ "$le_domain" != "localhost" ]
+then
+ install_letsencrypt
+ check_https
+else
+ print_info "is localhost - skipped installation of letsencrypt and configuration of apache for https"
+fi
+
+install_zotserver
+
+configure_cron_daily
+
+
+#set +x # stop debugging from here