Merge pull request 'Local install + files & functions rearranged' (#55) from dragondaddy/streams:autoinstall into dev

Reviewed-on: https://codeberg.org/streams/streams/pulls/55
This commit is contained in:
(streams) 2023-03-04 01:27:40 +00:00
commit 4ef14f8d08
12 changed files with 613 additions and 347 deletions

View file

@ -43,3 +43,11 @@ On a freshly installed Debian server, there are only four mandatory settings you
Open your domain with a browser and step throught the initial configuration of your website. You will need to re-enter a few settings (database name, user and password, admin e-mail…). You will then create your first user, starting with the admin is a great idea.
And thats it, you can now log in your website and start adding content to it!
## Local install
It is possible to install your website locally (i.e. for testing purposes). You just have to add an option when lauching the command:
./autoinstall --local
There will be no https or ddns stuff in the dialogs. If you don't use "localhost" but want a custom local domain, don't forget to add it in /etc/hosts.

View file

@ -47,6 +47,10 @@ It is recommended to run the Raspi without graphical frontend. Use the following
*Dont forget to change the default password for user pi!*
## Local install
It is possible to install a website locally (i.e. to access it using http://localhost/ or any local domain you please), see README.md for details.
## Help wanted
Using Nginx as the webserver is not the best choice if you plan to clone or import a channel currently hosted on another website. The Nginx and/or PHP configuration files probably need some tweaking to have this feature correctly working. If you feel you could help solve this, feel free to contribute.

View file

@ -0,0 +1,31 @@
# TODO LIST
Here is the list of the improvements we need to work on. Any contribution will be greatly appreciated.
## Most important bugs
### Channel import/cloning when Nginx is the webserver
We need to find out what's wrong with Nginx and the channel import/cloning. Right now we have a 504 Timeout error whenever we try. There's probably something to do with php.ini and the website's Nginx conf file.
## Important improvements
### php.ini custom settings
For the moment, php.ini settings are global both with Apache & Nginx (respectively in /etc/php/8.2/apache2/php.ini and nano /etc/php/8.2/fpm/php.ini). There should be a way to have a it configured for each website individually.
Also, if php gets an update while the global php.ini was "manually" modified (i.e. with our setup script), it interrupts the daily-update script. Not cool.
## More improvement ideas
### Handling errors during the install
This autoinstall folder is mainly intended for people that are not used to managing their own server. If we could have error messages as explicit as possible, it would be very cool. Also, it would be nice to make sure that in case the install fails, we can easily rerun the script without having to manually clean things up or to reinstall the server.
### Using script on other distros that use *.deb packages (not only Debian)
We should probably be able to modify the check_sanity function and make it possible to use the script with Debian derivatives such as Ubuntu it an its flavors or Linux Mint (as long as requirements such as php 8.* available.
### Using script on other distros that use other packages (*.rpm for instance)
If we created a scripts/rpm.sh file, where we'd just have to create functions such as update_upgrade, check_install, nocheck_install and php_version usable with *.rpm packages, we could veryh easily support RedHat its derivative distros.

View file

@ -80,7 +80,8 @@ function check_sanity {
then
die "You can only run this script on a Debian GNU/Linux 11 server"
else
system=debian
pkgsys=deb
os=debian
print_info "Running the autoinstall script on a Debian GNU/Linux 11 server"
fi
}
@ -135,43 +136,9 @@ function die {
exit 1
}
function check_install {
if [ -z "`which "$1" 2>/dev/null`" ]
then
# 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 -q -y install $2
print_info "installed $2 installed for $1"
else
print_warn "$2 already installed"
fi
}
function nocheck_install {
declare DRYRUN=$(DEBIAN_FRONTEND=noninteractive apt-get install --dry-run $1 | grep Remv | sed 's/Remv /- /g')
if [ -z "$DRYRUN" ]
then
# 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"
else
print_info "Did not install $1 as it would require removing the following:"
print_info "$DRYRUN"
die "It seems you are not running this script on a fresh Debian GNU/Linux install. Please consider another installation method."
fi
}
function print_info {
echo -n -e '\e[1;34m'
echo -n $1
echo -n -e $1
echo -e '\e[0m'
}
@ -181,81 +148,6 @@ function print_warn {
echo -e '\e[0m'
}
function add_nginx_conf {
print_info "adding nginx conf files"
sed "s|SERVER_NAME|${domain_name}|g;s|INSTALL_PATH|${install_path}|g;s|SERVER_LOG|${domain_name}.log|;s|DOMAIN_CERT|${cert}|;s|CERT_KEY|${cert_key}|;" nginx-server.conf.template >> /etc/nginx/sites-available/${domain_name}.conf
ln -s /etc/nginx/sites-available/${domain_name}.conf /etc/nginx/sites-enabled/
nginx_conf=yes
systemctl restart nginx
}
function install_imagemagick {
if [[ -z "$(which convert)" ]]
then
print_info "installing imagemagick..."
nocheck_install "imagemagick"
fi
}
function php_version {
# We check that we can install the required version (8.2),
print_info "checking that we can install the required PHP version (8.2)..."
check_php=$(apt-cache show php8.2 | grep 'No packages found')
if [ -z "$check_php" ]
then
print_info "We're good!"
else
die "something went wrong, we can't install php8.2."
fi
}
function install_php {
if [[ -z "$(which php-fpm8.2)" ]]
then
print_info "installing php8.2..."
if [[ $webserver == "nginx" ]]
then
nocheck_install "php8.2-fpm php8.2 php8.2-mysql php-pear php8.2-curl php8.2-gd php8.2-mbstring php8.2-xml php8.2-zip"
sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 100M/g" /etc/php/8.2/fpm/php.ini
sed -i "s/^post_max_size =.*/post_max_size = 100M/g" /etc/php/8.2/fpm/php.ini
systemctl restart php8.2-fpm
print_info "php8.2 was installed."
elif [[ $webserver == "apache" ]]
then
nocheck_install "libapache2-mod-php php php-mysql 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
print_info "php ${phpversion} was installed"
fi
fi
}
function install_composer {
print_info "We check if Composer is already installed"
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 installed."
else
print_info "Composer is already installed on this system."
fi
}
function create_website_db {
print_info "creating website's database..."
if [ -z "$website_db_name" ]
@ -288,6 +180,13 @@ function create_website_db {
else
die "database named \"$website_db_name\" already exists..."
fi
# We check that the database and its user were successfully created
if [[ ! -z $(mysql -h localhost -u $website_db_user -p$website_db_pass -e "SHOW DATABASES;" | grep -w "$website_db_name") ]]
then
print_info "The website's database and database user were successfully created"
else
die "Something went wrong, the website's database and database user do no seem to exist"
fi
}
function ping_domain {
@ -315,12 +214,13 @@ function ping_domain {
function check_https {
print_info "checking httpS > testing ..."
url_https=https://$domain_name
wget_output=$(wget -nv --spider --max-redirect 0 $url_https)
curl_output=$(curl -s -o /dev/null -I -w "%{http_code}" $url_https)
if [ $? -ne 0 ]
then
print_warn "check not ok"
print_warn "It seems that your website is not reachable through a secured https connection, you should investigate this"
else
print_info "check ok"
print_info "Check OK"
final_message
fi
}
@ -423,7 +323,7 @@ function configure_cron_daily {
echo "#" >> /var/www/$cron_job
echo "cd /var/www" >> /var/www/$cron_job
echo "for f in *-daily.sh; do \"./\${f}\"; done" >> /var/www/$cron_job
if [[ $system == "debian" ]]
if [[ $os == "debian" ]]
then
echo "echo \"\$(date) - updating Debian GNU/Linux...\"" >> /var/www/$cron_job
echo "apt-get -q -y update && apt-get -q -y dist-upgrade && apt-get -q -y autoremove # update Debian GNU/Linux and upgrade" >> /var/www/$cron_job
@ -453,10 +353,6 @@ function configure_cron_daily {
# START OF PROGRAM
########################################################################
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
check_sanity
repo_name
print_info "We're installing a website using the $repository repository"
install_path="$(dirname $(dirname "$(pwd)"))"
if [ "$install_path" == "/var/www/html" ]
@ -465,37 +361,76 @@ then
fi
install_folder="$(basename $install_path)"
domain_regex="^([a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.)+[a-zA-Z]{2,}$"
for arg in "$@" ; do
shift
case "$arg" in
--local) local_install=yes
print "We're doing a local install, option is $local_install"
;;
*) die "\"$arg\" is not a valid argument or option, \"--local\" is the only option you can use with autoinstall.sh"
;;
esac
done
check_sanity
repo_name
print_info "We're installing a website using the $repository repository"
print_info "Now using scripts/dialogs.sh to obtain all necessary settings for the install"
source scripts/dialogs.sh
#set -x # activate debugging from here
if [[ $system == "debian" ]]
if [[ $pkgsys == "deb" ]]
then
source scripts/debian.sh
source scripts/deb.sh
# Scripts for other Debian based distros could be added later
# elif [[ $system == "other_distro" ]]
# elif [[ $pkgsys == "other_distro" ]]
# then
# source scripts/other_distro.sh
fi
source scripts/common_install.sh
source scripts/common_conf.sh
# We need to install some basics on a freshly installed system
update_upgrade
install_curl
install_wget
install_sendmail
install_imagemagick
# DNS stuff
if [ -z $local_install ]
then
install_run_ddns
ping_domain
configure_cron_ddns
fi
# Web server
install_webserver
# PHP
php_version
install_php
# Let's Encrypt
if [ -z $local_install ]
then
install_letsencrypt
fi
# Webserver configuration
webserver_conf
# We install our MariaDB server
install_mysql
# Composer
install_composer
# Now we the website install
create_website_db
install_website
# Daily maintenance
daily_update="${domain_name}-daily.sh"
cron_job="cron_job.sh"
configure_daily_update
configure_cron_daily
check_https
# Put a nice message here no confirm the website was successfully installed
# Final https check
if [ -z $local_install ]
then
check_https
fi
#set +x # stop debugging from here

View file

@ -0,0 +1,70 @@
#!/bin/bash
function add_vhost {
print_info "adding apache vhost"
echo "<VirtualHost *:80>" >> "/etc/apache2/sites-available/${domain_name}.conf"
echo "ServerName ${domain_name}" >> "/etc/apache2/sites-available/${domain_name}.conf"
echo "DocumentRoot $install_path" >> "/etc/apache2/sites-available/${domain_name}.conf"
echo " <Directory $install_path>" >> "/etc/apache2/sites-available/${domain_name}.conf"
echo " AllowOverride All" >> "/etc/apache2/sites-available/${domain_name}.conf"
echo " </Directory>" >> "/etc/apache2/sites-available/${domain_name}.conf"
echo "</VirtualHost>" >> "/etc/apache2/sites-available/${domain_name}.conf"
a2ensite $domain_name
vhost_added=yes
}
function vhost_le {
print_info "run certbot ..."
certbot --apache -w $install_path -d $domain_name -m $le_email --agree-tos --non-interactive --redirect --hsts --uir
service apache2 restart
if [ "$(systemctl is-active apache2)" == "failed" ]
then
die "Something went wrong with the Apache configuration of your website"
fi
vhost_le_configured=yes
}
function nginx_conf_le {
print_info "run certbot..."
certbot certonly --nginx -d $domain_name -m $le_email --agree-tos --non-interactive
cert="/etc/letsencrypt/live/$domain_name/fullchain.pem"
cert_key="/etc/letsencrypt/live/$domain_name/privkey.pem"
}
function add_nginx_conf {
print_info "adding nginx conf files"
if [ -z $local_install ]
then
nginx_template="templates/nginx-server.conf.template"
else
nginx_template="templates/nginx-server.localhost.conf.template"
fi
sed "s|SERVER_NAME|${domain_name}|g;s|INSTALL_PATH|${install_path}|g;s|SERVER_LOG|${domain_name}.log|;s|DOMAIN_CERT|${cert}|;s|CERT_KEY|${cert_key}|;" $nginx_template >> /etc/nginx/sites-available/${domain_name}.conf
ln -s /etc/nginx/sites-available/${domain_name}.conf /etc/nginx/sites-enabled/
systemctl restart nginx
if [ "$(systemctl is-active nginx)" == "failed" ]
then
die "Something went wrong with the Nginx configuration of your website"
fi
nginx_conf=yes
}
function webserver_conf {
# We configure our webserver for our website
if [[ $webserver = "nginx" ]]
then
if [ -z $local_install ]
then
nginx_conf_le
fi
add_nginx_conf
elif [[ $webserver = "apache" ]]
then
add_vhost
if [ -z $local_install ]
then
vhost_le
fi
fi
}

View file

@ -0,0 +1,173 @@
#!/bin/bash
function install_curl {
if [[ -z "$(which curl)" ]]
then
print_info "installing curl..."
nocheck_install "curl"
fi
}
function install_wget {
if [[ -z "$(which wget)" ]]
then
print_info "installing wget..."
nocheck_install "wget"
fi
}
function install_sendmail {
if [[ -z "$(which sendmail)" ]]
then
print_info "installing sendmail..."
nocheck_install "sendmail sendmail-bin"
fi
}
function install_apache {
if [[ -z "$(which apache2)" ]] && [[ -z "$(which nginx)" ]]
then
print_info "installing apache..."
nocheck_install "apache2 apache2-utils"
a2enmod rewrite
systemctl restart apache2
fi
if [ "$(systemctl is-active apache2)" == "failed" ]
then
die "Something went wrong with the installation of Apache"
fi
}
function install_nginx {
if [[ -z "$(which nginx)" ]] && [[ -z "$(which apache2)" ]]
then
print_info "installing nginx..."
nocheck_install "nginx"
systemctl restart nginx
fi
if [ "$(systemctl is-active nginx)" == "failed" ]
then
die "Something went wrong with the installation of Nginx"
fi
}
function install_letsencrypt {
if [[ -z "$(which certbot)" ]]
then
print_info "installing let's encrypt ..."
# installing certbot via snapd is the preferred method (10/2022) https://certbot.eff.org/instructions
nocheck_install "snapd"
print_info "ensure that version of snapd is up to date..."
snap install core
snap refresh core
print_info "install certbot via snap..."
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot
fi
}
function install_webserver {
if [[ $webserver = "nginx" ]]
then
install_nginx
elif [[ $webserver = "apache" ]]
then
install_apache
fi
}
function install_php {
if [[ -z "$(which php-fpm8.2)" ]]
then
print_info "installing php8.2..."
if [[ $webserver == "nginx" ]]
then
nocheck_install "php8.2-fpm php8.2 php8.2-mysql php-pear php8.2-curl php8.2-gd php8.2-mbstring php8.2-xml php8.2-zip"
sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 100M/g" /etc/php/8.2/fpm/php.ini
sed -i "s/^post_max_size =.*/post_max_size = 100M/g" /etc/php/8.2/fpm/php.ini
systemctl restart php8.2-fpm
print_info "php8.2 was installed."
elif [[ $webserver == "apache" ]]
then
nocheck_install "libapache2-mod-php php php-mysql 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
print_info "php ${phpversion} was installed"
fi
fi
}
function install_composer {
print_info "We check if Composer is already installed"
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 installed."
else
print_info "Composer is already installed on this system."
fi
}
function install_mysql {
if [ ! -z $(which mysql) ]
then
print_info "MariaDB (or MySQL) is already installed"
else
print_info "we install mariadb-server"
nocheck_install "mariadb-server"
systemctl is-active --quiet mariadb && echo "MariaDB is running"
fi
}
function install_imagemagick {
if [[ -z "$(which convert)" ]]
then
print_info "installing imagemagick..."
nocheck_install "imagemagick"
fi
}
function install_run_ddns {
if [ ! -z $ddns_provider ]
then
source scripts/ddns/$ddns_provider.sh
if [ ! -f dns_cache_fail ]
then
nocheck_install "dnsutils"
install_run_$ddns_provider
fi
if [ -z $(dig -4 $domain_name +short | grep $(curl ip4.me/ip/)) ]
then
touch dns_cache_fail
die "There seems to be a DNS cache issue here, you need to wait a few minutes before running the script again"
else
if [ -f dns_cache_fail ]
then
rm -f dns_cache_fail
fi
fi
fi
}
function configure_cron_ddns {
if [ ! -z $ddns_provider ]
then
scripts source ddns/$ddns_provider.sh
configure_cron_$ddns_provider
fi
}

View file

@ -0,0 +1,73 @@
#!/bin/bash
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
print_info "updated and upgraded linux"
}
function check_install {
if [ -z "`which "$1" 2>/dev/null`" ]
then
# 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 -q -y install $2
print_info "installed $2 installed for $1"
else
print_warn "$2 already installed"
fi
}
function nocheck_install {
declare DRYRUN=$(DEBIAN_FRONTEND=noninteractive apt-get install --dry-run $1 | grep Remv | sed 's/Remv /- /g')
if [ -z "$DRYRUN" ]
then
# 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"
else
print_info "Did not install $1 as it would require removing the following:"
print_info "$DRYRUN"
die "It seems you are not running this script on a fresh Debian GNU/Linux install. Please consider another installation method."
fi
}
function install_sury_repo {
# With Debian 11 (bullseye) we need an extra repo to install php 8.*
if [[ -z $(grep -R "deb https://packages.sury.org/php/" /etc/apt/) ]]
then
print_info "installing sury-php repository..."
apt-get -y install apt-transport-https
curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg
sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/sury-php.list'
apt-get update -y
else
print_info "sury-php repository is already installed."
fi
}
function php_version {
# We check that we can install the required version (8.2),
print_info "checking that we can install the required PHP version (8.2)..."
check_php=$(apt-cache show php8.2 | grep 'No packages found')
if [ -z "$check_php" ]
then
print_info "We're good!"
else
die "something went wrong, we can't install php8.2."
fi
}
if [[ $os == "debian" ]]
then
install_sury_repo
fi

View file

@ -1,179 +0,0 @@
#!/bin/bash
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
print_info "updated and upgraded linux"
}
function install_curl {
if [[ -z "$(which curl)" ]]
then
print_info "installing curl..."
nocheck_install "curl"
fi
}
function install_wget {
if [[ -z "$(which wget)" ]]
then
print_info "installing wget..."
nocheck_install "wget"
fi
}
function install_sendmail {
if [[ -z "$(which sendmail)" ]]
then
print_info "installing sendmail..."
nocheck_install "sendmail sendmail-bin"
fi
}
function install_sury_repo {
# With Debian 11 (bullseye) we need an extra repo to install php 8.*
if [[ -z $(grep -R "deb https://packages.sury.org/php/" /etc/apt/) ]]
then
print_info "installing sury-php repository..."
apt-get -y install apt-transport-https
curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg
sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/sury-php.list'
apt-get update -y
else
print_info "sury-php repository is already installed."
fi
}
function install_apache {
if [[ -z "$(which apache2)" ]]
then
print_info "installing apache..."
nocheck_install "apache2 apache2-utils"
a2enmod rewrite
systemctl restart apache2
fi
}
function install_nginx {
if [[ -z "$(which nginx)" ]]
then
print_info "installing nginx..."
nocheck_install "nginx"
systemctl restart nginx
fi
}
function add_vhost {
print_info "adding apache vhost"
echo "<VirtualHost *:80>" >> "/etc/apache2/sites-available/${domain_name}.conf"
echo "ServerName ${domain_name}" >> "/etc/apache2/sites-available/${domain_name}.conf"
echo "DocumentRoot $install_path" >> "/etc/apache2/sites-available/${domain_name}.conf"
echo " <Directory $install_path>" >> "/etc/apache2/sites-available/${domain_name}.conf"
echo " AllowOverride All" >> "/etc/apache2/sites-available/${domain_name}.conf"
echo " </Directory>" >> "/etc/apache2/sites-available/${domain_name}.conf"
echo "</VirtualHost>" >> "/etc/apache2/sites-available/${domain_name}.conf"
a2ensite $domain_name
vhost_added=yes
}
function install_letsencrypt {
if [[ -z "$(which certbot)" ]]
then
print_info "installing let's encrypt ..."
# installing certbot via snapd is the preferred method (10/2022) https://certbot.eff.org/instructions
nocheck_install "snapd"
print_info "ensure that version of snapd is up to date..."
snap install core
snap refresh core
print_info "install certbot via snap..."
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot
fi
}
function nginx_conf_le {
print_info "run certbot..."
certbot certonly --nginx -d $domain_name -m $le_email --agree-tos --non-interactive
cert="/etc/letsencrypt/live/$domain_name/fullchain.pem"
cert_key="/etc/letsencrypt/live/$domain_name/privkey.pem"
}
function vhost_le {
print_info "run certbot ..."
certbot --apache -w $install_path -d $domain_name -m $le_email --agree-tos --non-interactive --redirect --hsts --uir
service apache2 restart
vhost_le_configured=yes
}
function install_mysql {
if [ ! -z $(which mysql) ]
then
print_info "MariaDB (or MySQL) is already installed"
else
print_info "we install mariadb-server"
nocheck_install "mariadb-server"
systemctl is-active --quiet mariadb && echo "MariaDB is running"
fi
}
# We need to install basic stuff on a fresh install
update_upgrade
install_curl
install_wget
install_sendmail
if [ ! -z $ddns_provider ]
then
source scripts/ddns/$ddns_provider.sh
if [ ! -f dns_cache_fail ]
then
nocheck_install "dnsutils"
install_run_$ddns_provider
fi
if [ -z $(dig -4 $domain_name +short | grep $(curl ip4.me/ip/)) ]
then
touch dns_cache_fail
die "There seems to be a DNS cache issue here, you need to wait a few minutes before running the script again"
fi
fi
ping_domain
# add something here to remove dns_cache_fail ?
if [ ! -z $ddns_provider ]
then
scripts source ddns/$ddns_provider.sh
configure_cron_$ddns_provider
fi
# We install our webserver
if [[ $webserver = "nginx" ]]
then
install_nginx
elif [[ $webserver = "apache" ]]
then
install_apache
fi
# We install the required PHP version
install_sury_repo
php_version
install_php
install_letsencrypt
# We configure our webserver for our website
if [[ $webserver = "nginx" ]]
then
nginx_conf_le
add_nginx_conf
elif [[ $webserver = "apache" ]]
then
add_vhost
vhost_le
fi
# We install our MariaDB server
install_mysql

View file

@ -1,7 +1,7 @@
#!/bin/bash
function script_debut {
# First we check if we're running the script on a freshly installed Debian 11 server
if [[ $system == "debian" ]]
if [[ $os == "debian" ]]
then
if [[ ! -z "$(which php)" ]] || [[ ! -z "$(which mysql)" ]] || [[ ! -z "$(which apache)" ]] || [[ ! -z "$(which nginx)" ]]
then
@ -41,7 +41,12 @@ function enter_domain {
# This is where the domain name is choosed
if [ -z "$inputbox_domain" ]
then
inputbox_domain="Please enter your website's address/domain name\n(i.e. \"mywebsite.example.com\", \"example.com\")"
if [ -z $local_install ]
then
inputbox_domain="Please enter your website's address/domain name\n(i.e. \"mywebsite.example.com\", \"example.com\")"
else
inputbox_domain="Please enter a local domain for testing\n(i.e. \"localhost\", \"testing\"...)"
fi
fi
domain_name=$(whiptail \
--title "Domain name" \
@ -56,13 +61,26 @@ function enter_domain {
inputbox_domain="You need to put something here otherwise you won't be able to configure a website.\nPlease enter the domain name you plan to use for your website:"
enter_domain
else
# Validate domain name (we check if the input looks like a FQDN of a domain name not that it is an actual one)
if [[ "$domain_name" =~ $domain_regex ]]
source scripts/more_dialogs.sh
if [ -z $local_install ]
then
source scripts/dialogs_debian.sh
# Validate domain name (we check if the input looks like a FQDN of a domain name not that it is an actual one)
if [[ "$domain_name" =~ $domain_regex ]]
then
enter_email
else
inputbox_domain="\"$domain_name\" is not a valid address/domain name for your website. Please enter something that looks like \"example.com\" or \"subdomain.example.com\":"
enter_domain
fi
else
inputbox_domain="\"$domain_name\" is not a valid address/domain name for your website. Please enter something that looks like \"example.com\" or \"subdomain.example.com\":"
enter_domain
if [[ "$domain_name" =~ $local_regex ]]
then
webserver_check
else
# We change the message in the dialog box if there's no valid input
inputbox_domain="\"$domain_name\" is not a valid local domain for your test install. Please enter one now:"
enter_domain
fi
fi
fi
else
@ -214,12 +232,16 @@ function db_user_check {
}
function summary {
summary_domain="Website address : https://$domain_name/\n\n"
if [ -z $local_install ]
then
summary_domain="Website address : https://$domain_name/\n\n"
else
summary_domain="Website address : http://$domain_name/\n\n"
fi
summary_db_pass="Website database password : $website_db_pass\n"
summary_db_name="Website database name : $website_db_name\n"
summary_db_user="Website database user : $website_db_user\n"
# This will be used to display the settings for our install
summary_display="$summary_domain$summary_db_name$summary_db_user$summary_db_pass"
summary_display="$summary_domain$summary_email$summary_webserver$summary_ddns_provider$summary_ddns_key$summary_ddns_id$summary_ddns_password$summary_db_pass$summary_db_name$summary_db_user"
# We display all settings
if (whiptail \
@ -233,7 +255,7 @@ function summary {
# Reset all settings before sarting over. We keep domain name, email address for Let's Encrypt
# and mysql root, which will most likely remain the same
unset webserver summary_webserver
unset ddns_provider ddns_provider_name
unset ddns_provider ddns_provider_name summary_ddns_provider
unset ddns_key_type ddns_key summary_ddns_key
unset ddns_id ddns_password summary_ddns_id summary_ddns_password
unset website_db_pass website_db_name website_db_user
@ -256,6 +278,19 @@ function launch_install {
fi
}
function final_message {
final_summary=$summary_domain$summary_db_user$summary_db_pass$summary_db_name
whiptail \
--title "Website successfully installed" \
--msgbox "Your website was successfully installed. You must now visit https://$domain_name with your web browser to finish the setup. You will need the following:\n\n$final_summary" \
15 80
print_info "Website successfully installed"
print_info "$final_summary"
}
#set -x
domain_regex="^([a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.)+[a-zA-Z]{2,}$"
local_regex="^([a-zA-Z0-9]){2,25}$"
# set -x
script_debut

View file

@ -98,28 +98,34 @@ function select_webserver {
}
function ddns_choice {
# We can automatically configure Dynamic DNS (DDNS) with a few providers
# This is of course to be used only with a FQDN of domain name
provider=$(whiptail \
--title "Optional - Dynamic DNS configuration" \
--menu "If you plan to use a Dynamic DNS (DDNS) provider, you may choose one here. Currently supported providers are FreeDNS, Gandi and selHOST.de. You must already have an account with the selected provider and own a domain/subdomain. Please choose one of the following options:"\
18 80 4 \
"1" "None, I won't be using a DDNS provider"\
"2" "FreeDNS (offers free of charge subdomains)"\
"3" "Gandi (French domain name registrar with a nice API)"\
"4" "selfHOST.de (German language provider & registrar)" 3>&1 1>&2 2>&3)
### "5" "Sorry, what now?" 3>&1 1>&2 2>&3) ### Maybe an explanation short text about DDNS could be useful
exitstatus=$?
if [ $exitstatus = 0 ]
# Only useful if we're not doing a local install
if [ ! -z $local_install ]
then
case "$provider" in
# If no Dynamic DNS provider is used
1) enter_root_db_pass ;;
2|3|4) ddns_config ;;
### 5) ddns_ELIF ;; ### Could link to a short explanation text
esac
enter_root_db_pass
else
die "Lost your way? Feel free to try again!"
# We can automatically configure Dynamic DNS (DDNS) with a few providers
# This is of course to be used only with a FQDN of domain name
provider=$(whiptail \
--title "Optional - Dynamic DNS configuration" \
--menu "If you plan to use a Dynamic DNS (DDNS) provider, you may choose one here. Currently supported providers are FreeDNS, Gandi and selHOST.de. You must already have an account with the selected provider and own a domain/subdomain. Please choose one of the following options:"\
18 80 4 \
"1" "None, I won't be using a DDNS provider"\
"2" "FreeDNS (offers free of charge subdomains)"\
"3" "Gandi (French domain name registrar with a nice API)"\
"4" "selfHOST.de (German language provider & registrar)" 3>&1 1>&2 2>&3)
### "5" "Sorry, what now?" 3>&1 1>&2 2>&3) ### Maybe an explanation short text about DDNS could be useful
exitstatus=$?
if [ $exitstatus = 0 ]
then
case "$provider" in
# If no Dynamic DNS provider is used
1) enter_root_db_pass ;;
2|3|4) ddns_config ;;
### 5) ddns_ELIF ;; ### Could link to a short explanation text
esac
else
die "Lost your way? Feel free to try again!"
fi
fi
}
@ -194,10 +200,7 @@ function ddns_config {
fi
else
# The following part is for FreeDNS and Gandi which both only need a single key
if [ -z "$inputbox_ddns_key" ]
then
inputbox_ddns_key="Please provide your $ddns_provider_name $ddns_key_type :"
fi
inputbox_ddns_key="Please provide your $ddns_provider_name $ddns_key_type :"
ddns_key=$(whiptail \
--title "$ddns_provider_name $ddns_key_type" \
--inputbox "$inputbox_ddns_key" \
@ -259,4 +262,3 @@ function enter_root_db_pass {
fi
}
enter_email

View file

@ -0,0 +1,114 @@
##
# Nginx block configuration template
# based on the example created by Olaf Conradi
#
# The files generated with this template will be added to
# /etc/nginx/sites-available & /etc/nginx/sites-enabled (symlink)
##
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
#
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
##
##
# This configuration assumes
# You filled the zotserver-config.txt file
# Your use a local domain
# You have PHP FastCGI Process Manager (php-fpm) running on localhost
##
server {
listen 80;
listen [::]:80;
server_name SERVER_NAME;
charset utf-8;
root INSTALL_PATH;
index index.php;
access_log /var/log/nginx/SERVER_LOG;
#Uncomment the following line to include a standard configuration file
#Note that the most specific rule wins and your standard configuration
#will therefore *add* to this file, but not override it.
#include standard.conf
# allow uploads up to 20MB in size
client_max_body_size 20m;
client_body_buffer_size 128k;
include mime.types;
# rewrite to front controller as default rule
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?req=$1;
}
}
# make sure webfinger and other well known services aren't blocked
# by denying dot files and rewrite request to the front controller
location ^~ /.well-known/ {
allow all;
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?req=$1;
}
}
# statically serve these file types when possible
# otherwise fall back to front controller
# allow browser to cache them
# added .htm for advanced source code editor library
# location ~* \.(jpg|jpeg|gif|png|ico|css|js|htm|html|map|ttf|woff|woff2|svg)$ {
# expires 30d;
# try_files $uri /index.php?req=$uri&$args;
# }
# SHOULD WE UNCOMMENT THE ABOVE LINES ?
# block these file types
location ~* \.(tpl|md|tgz|log|out)$ {
deny all;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
# or a unix socket
location ~* \.php$ {
# IS THE FOLLOWING STILL RELEVANT AS OF AUGUST 2020?
# Zero-day exploit defense.
# http://forum.nginx.org/read.php?2,88845,page=3
# Won't work properly (404 error) if the file is not stored on this
# server, which is entirely possible with php-fpm/php-fcgi.
# Comment the 'try_files' line out if you set up php-fpm/php-fcgi on
# another machine. And then cross your fingers that you won't get hacked.
try_files $uri =404;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# With php5-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# With php-fpm:
fastcgi_pass unix:/var/run/php/php-fpm.sock;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# deny access to all dot files
location ~ /\. {
deny all;
}
#deny access to store
location ~ /store {
deny all;
}
}