Skip to content

Instantly share code, notes, and snippets.

@wheresjames
Created January 12, 2021 19:40
Show Gist options
  • Save wheresjames/9b83d78ddedc0adf50e2909951bdcdeb to your computer and use it in GitHub Desktop.
Save wheresjames/9b83d78ddedc0adf50e2909951bdcdeb to your computer and use it in GitHub Desktop.
Deploy apache server to a Linode instance
#!/bin/bash
#--------------------------------------------------------------------------------------------------
#
# Examples
#
# Setup new instance
# $ ./linode-deploy.sh create-setup <username> newserver.example.com
#
# After you've added the IP address to your DNS, get a lets encrypt cert with
# $ ./linode-deploy.sh ssl <username> newserver.example.com
#
# Setup apache
# $ ./linode-deploy.sh apache <username> newserver.example.com
#
# Upload a file
# $ ./linode-deploy.sh upload <username> newserver.example.com /path/to/source /path/to/destination
#
# SSH
# $ ./linode-deploy.sh ssh <username> newserver.example.com
#
#--------------------------------------------------------------------------------------------------
USAGE="Usage: ./linode-deploy.sh <commands> <username> <domain>"
SCRIPT_NAME=$(basename $0)
SCRIPT_PATH=$(dirname "$(readlink -f "$0")")
WORKING_PATH=$(pwd)
COMMANDLIST=$1
if [ -z $COMMANDLIST ]; then
echo $USAGE
exit -1
fi
USERNAME=$2
if [ -z $USERNAME ]; then
echo $USAGE
exit -1
fi
DOMAINNAME=$3
if [ -z $DOMAINNAME ]; then
echo $USAGE
exit -1
fi
DOTNAME=(${DOMAINNAME//./ })
DOTNAME=${DOTNAME[0]}
SSHPORT=22
# SSHOPTS=-o "StrictHostKeyChecking no"
LINCLI="python3 -m linodecli"
SECRETS="./secrets"
CERTDIR="${SECRETS}/${DOMAINNAME}.certs"
SETUPSCRIPT="${SCRIPT_PATH}/linode-setup.sh"
#--------------------------------------------------------------------------------------------------
# Functions
showWarning()
{
if [[ 0 -lt ${#@} ]]; then
echo -e "[\e[1;33mWARN\e[1;0m] \e[1;33m${@}\e[1;0m"
fi
}
showInfo()
{
if [[ 0 -lt ${#@} ]]; then
echo -e "[\e[1;36mINFO\e[1;0m] \e[1;36m${@}\e[1;0m"
fi
}
exitWithError()
{
if [[ 0 -lt ${#@} ]]; then
echo
echo "--------------------------------------------------------------------"
echo -e "[\e[1;31mERROR\e[1;0m] \e[1;31m${@}\e[1;0m"
echo "--------------------------------------------------------------------"
echo
fi
exit -1
}
exitOnError()
{
if [[ 0 -eq $? ]]; then return 0; fi
exitWithError $@
}
warnOnError()
{
if [[ 0 -eq $? ]]; then return 0; fi
showWarning $@
return -1
}
isCmd()
{
# - separator
FOUND=$(echo "\-$COMMANDLIST-" | grep -o "\-${1}-")
if [[ ! -z $FOUND ]]; then return 0; fi
# , separator
FOUND=$(echo ",$COMMANDLIST," | grep -o ",${1},")
if [[ ! -z $FOUND ]]; then return 0; fi
return -1
}
findInStr()
{
FIND_LIST=$1
FIND_EXISTS=$(echo "$FIND_LIST" | grep -o "$2")
if [[ ! -z $FIND_EXISTS ]]; then return 0; fi
return -1
}
findIn()
{
findInStr "$($1 2>&1)" "$2"
return $?
}
waitWhile()
{
if ! findIn "$1" "$2"; then return 0; fi
echo "$3 "
while findIn "$1" "$2"; do
printf .
sleep 3
done
echo
echo "Done"
return -1
}
waitWhileNot()
{
if findIn "$1" "$2"; then return 0; fi
echo "$3 "
while ! findIn "$1" "$2"; do
printf .
sleep 3
done
echo
echo "Done"
return -1
}
waitWhileFailed()
{
echo $3
WWF_RETRY_COUNT=$1
while [ 0 -lt $WWF_RETRY_COUNT ]; do
$2
if [[ 0 -eq $? ]]; then
echo
echo "Done"
return 0;
fi
printf .
sleep 3
WWF_RETRY_COUNT=$((WWF_RETRY_COUNT-1))
done
exitWithError "FAILED: $3"
}
isCommand()
{
if ! findIn "which $1" "$1"; then return -1; fi
return 0
}
aptInstall()
{
if ! findIn "apt list --installed 2>/dev/null" $1; then
apt-get -y install $1
exitOnError "Unable to install $1"
fi
}
isAptRepo()
{
if ! findIn "egrep -v '^#|^ *$' /etc/apt/sources.list /etc/apt/sources.list.d/*" "$1"; then return -1; fi
return 0
}
addAptRepo()
{
if ! isAptRepo "$1"; then
apt-add-repository $1
if ! warnOnError "Unable to add repo $1"; then
apt-get -yq update
fi
fi
}
doIf()
{
findInStr "$($1 2>&1)" $2
if [[ 0 -ne $? ]]; then return 0; fi
if [[ ! -z $4 ]]; then $4 | $3; else $3; fi
}
doIfNot()
{
findInStr "$($1 2>&1)" $2
if [[ 0 -eq $? ]]; then return 0; fi
if [[ ! -z $4 ]]; then $4 | $3; else $3; fi
}
isOnline()
{
wget -q --tries=1 --timeout=8 --spider http://google.com
return $?
}
getPassword()
{
local -n RETVAL=$1
PWDNAME=$2
PWDLEN=$3
if [[ ! -d "$SECRETS" ]]; then
mkdir -p "$SECRETS"
fi
PWDFILE="${SECRETS}/$PWDNAME.pwd"
if [[ -f $PWDFILE ]]; then
NEWPWD=$(<${PWDFILE})
fi
if [[ -z $NEWPWD ]]; then
showInfo "Creating new password in : ${PWDFILE}"
NEWPWD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c ${PWDLEN})
echo "${NEWPWD}" >> "${PWDFILE}"
else
showInfo "${PWDNAME} password in : ${PWDFILE}"
fi
RETVAL=$NEWPWD
}
#--------------------------------------------------------------------------------------------------
# Los Geht's!
echo
echo "----------------------------------------------------------"
echo "- Commands : $COMMANDLIST"
echo "- User Name : $USERNAME"
echo "- Domain Name : $DOMAINNAME"
echo "- Dot Name : $DOTNAME"
echo "- Linode CLI : $LINCLI"
echo "- Secrets Dir : $SECRETS"
echo "- Certificates Dir : $CERTDIR"
echo "----------------------------------------------------------"
echo
#--------------------------------------------------------------------------------------------------
showInfo "Starting..."
# Online check
if ! isOnline; then
exitWithError "!!! OFFLINE !!!"
fi
# Ensure linode command line is installed
if ! findIn "$LINCLI --version" "linode"; then
exitWithError "linode cli not installed. Run: pip3 install linode-cli"
fi
# Check user
if isCmd "setuser"; then
$LINCLI set-user $USERNAME
fi
if ! findIn "$LINCLI show-users" "* $USERNAME"; then
$LINCLI show-users
exitWithError "Active user not set : $USERNAME -- Try: $LINCLI set-user $USERNAME"
fi
getPassword ROOTPWD ${DOMAINNAME} 32
#--------------------------------------------------------------------------------------------------
if isCmd "delete"; then
showInfo "Deleting Server..."
IID=$($LINCLI linodes list --text --no-headers --delimiter ' ' --format 'id,label' | grep -Eo ".*${DOMAINNAME}.*" | grep -Eo "([0-9])*" | head -1)
if [[ -z $IID ]]; then
exitWithError "ID not found for ${DOMAINNAME}"
fi
showInfo "Deleting $IID"
$LINCLI linodes delete $IID
if ! isCmd "create"; then
exit 0
fi
fi
#--------------------------------------------------------------------------------------------------
# python3 -m linodecli configure
#
# python3 -m linodecli linodes types
#
# python3 -m linodecli linodes create \
# --no-defaults --label "somelabel" --authorized_keys="user1,user2,..." \
# --root_pass "root-password" \
# --type g6-standard-1 --region eu-central \
# --image linode/debian10
#--------------------------------------------------------------------------------------------------
if isCmd "create"; then
showInfo "Creating Server..."
DELAYCMD=
if findIn "$LINCLI linodes list --text --no-headers" "${DOMAINNAME}"; then
showWarning "Already exists: ${DOMAINNAME}"
else
# Create the instance
$LINCLI linodes create \
--no-defaults --label "${DOMAINNAME}" \
--type g6-standard-1 --region eu-central \
--root_pass "${ROOTPWD}" \
--image linode/debian10
exitOnError "Failed to create linode instance"
# ADDDELAY="YES"
fi
waitWhile "$LINCLI linodes list --text --no-headers" "provisioning" "Waiting for node to provision"
waitWhile "$LINCLI linodes list --text --no-headers" "booting" "Waiting for node to boot"
if [[ ! -z $ADDDELAY ]]; then
showInfo "Waiting 30 seconds..."
sleep 30
fi
fi
#--------------------------------------------------------------------------------------------------
# Get IP Address
IPADDR=$($LINCLI linodes list --text --no-headers --delimiter ' ' --format 'ipv4,label' | grep -Eo ".*${DOMAINNAME}.*" | grep -Eo "([0-9\.])*" | head -1)
if [[ -z $IPADDR ]]; then
exitWithError "Missing ip address"
fi
showInfo "IP ADDRESS: $IPADDR"
# If we just created, wait for it to come online
# if isCmd "create"; then
# SSHCMD="sshpass -p \"$ROOTPWD\" ssh -p $SSHPORT root@${IPADDR} -o \"StrictHostKeyChecking no\" \"uname\""
# waitWhileFailed 10 "$SSHCMD" "Waiting for ssh to come online"
# fi
#--------------------------------------------------------------------------------------------------
if isCmd "upload"; then
SRC=$4
TGT=$5
showInfo "Uploading: $SRC -> ${IPADDR}@${TGT}"
if [[ -f $SRC ]]; then
sshpass -p "$ROOTPWD" rsync --info=progress2 -r -e "ssh -p $SSHPORT -o \"StrictHostKeyChecking no\"" $SRC root@${IPADDR}:$TGT
exitOnError "Failed to upload $SRC"
else
if [[ -d $SRC ]]; then
sshpass -p "$ROOTPWD" rsync --info=progress2 -r -e "ssh -p $SSHPORT -o \"StrictHostKeyChecking no\"" $SRC root@${IPADDR}:$TGT
exitOnError "Failed to upload $SRC"
else
exitWithError "Not found : $SRC"
fi
fi
fi
#--------------------------------------------------------------------------------------------------
if isCmd "download"; then
SRC=$4
TGT=$5
showInfo "Downloading: ${IPADDR}@$SRC -> ${TGT}"
sshpass -p "$ROOTPWD" rsync --info=progress2 -r -e "ssh -p $SSHPORT -o \"StrictHostKeyChecking no\"" root@${IPADDR}:$SRC $TGT
exitOnError "Failed to download $SRC"
fi
#--------------------------------------------------------------------------------------------------
if isCmd "ssh"; then
showInfo "SSH -> ${IPADDR}"
# Invoke ssh
sshpass -p "$ROOTPWD" ssh -p $SSHPORT root@${IPADDR} -o "StrictHostKeyChecking no"
fi
#--------------------------------------------------------------------------------------------------
if isCmd "setup"; then
showInfo "SETUP -> SSH -> ${IPADDR}"
# Install rsync
sshpass -p "$ROOTPWD" ssh -p $SSHPORT root@${IPADDR} -o "StrictHostKeyChecking no" "apt-get install -yq rsync"
# Invoke setup
sshpass -p "$ROOTPWD" ssh -p $SSHPORT root@${IPADDR} -o "StrictHostKeyChecking no" "bash -s ${COMMANDLIST}-setdomain-firewall ${DOMAINNAME}" < "$SETUPSCRIPT"
fi
#--------------------------------------------------------------------------------------------------
if isCmd "getcert"; then
showInfo "Download SSL certs <- $IPADDR"
sshpass -p "$ROOTPWD" rsync -L --info=progress2 -r -e "ssh -p $SSHPORT -o \"StrictHostKeyChecking no\"" "root@${IPADDR}:/etc/letsencrypt/live/${DOMAINNAME}" "$CERTDIR"
fi
#--------------------------------------------------------------------------------------------------
if isCmd "putcert"; then
showInfo "Upload SSL certs -> $IPADDR"
sshpass -p "$ROOTPWD" rsync --info=progress2 -r -e "ssh -p $SSHPORT -o \"StrictHostKeyChecking no\"" "$CERTDIR" "root@${IPADDR}:/etc/letsencrypt/live/${DOMAINNAME}"
fi
#--------------------------------------------------------------------------------------------------
showInfo "Success!"
echo
#!/bin/bash
#--------------------------------------------------------------------------------------------------
#
# ssh root@<ip-address> 'bash -s <commands> <domain>' < ./linode-setup.sh
#
# Linode
# https://github.com/linode/linode-cli
# https://www.mankier.com/1/linode-linode#Actions-Create
#
#--------------------------------------------------------------------------------------------------
USAGE="Usage: ./linode-setup.sh <commands> <domain>"
export DEBIAN_FRONTEND=noninteractive
COMMANDLIST=$1
if [ -z $COMMANDLIST ]; then
echo $USAGE
exit -1
fi
DOMAINNAME=$2
DOTNAME=(${DOMAINNAME//./ })
DOTNAME=${DOTNAME[0]}
SECRETS="./secrets"
#--------------------------------------------------------------------------------------------------
# Functions
showWarning()
{
if [[ 0 -lt ${#@} ]]; then
echo -e "[\e[1;33mWARNING\e[1;0m] \e[1;33m${@}\e[1;0m"
fi
}
showInfo()
{
if [[ 0 -lt ${#@} ]]; then
echo -e "[\e[1;36mINFO\e[1;0m] \e[1;36m${@}\e[1;0m"
fi
}
exitWithError()
{
if [[ 0 -lt ${#@} ]]; then
echo
echo "--------------------------------------------------------------------"
echo -e "[\e[1;31mERROR\e[1;0m] \e[1;31m${@}\e[1;0m"
echo "--------------------------------------------------------------------"
echo
fi
exit -1
}
exitOnError()
{
if [[ 0 -eq $? ]]; then return 0; fi
exitWithError $@
}
warnOnError()
{
if [[ 0 -eq $? ]]; then return 0; fi
showWarning $@
return -1
}
isCmd()
{
# - separator
FOUND=$(echo "\-$COMMANDLIST-" | grep -o "\-${1}-")
if [[ ! -z $FOUND ]]; then return 0; fi
# , separator
FOUND=$(echo ",$COMMANDLIST," | grep -o ",${1},")
if [[ ! -z $FOUND ]]; then return 0; fi
return -1
}
findInStr()
{
FIND_LIST=$1
FIND_EXISTS=$(echo "$FIND_LIST" | grep -o "$2")
if [[ ! -z $FIND_EXISTS ]]; then return 0; fi
return -1
}
findIn()
{
findInStr "$($1 2>&1)" "$2"
return $?
}
waitWhile()
{
if ! findIn "$1" "$2"; then return 0; fi
echo "$3 "
while findIn "$1" "$2"; do
printf .
sleep 3
done
echo
echo "Done"
return -1
}
isCommand()
{
if ! findIn "which $1" "$1"; then return -1; fi
return 0
}
aptInstall()
{
if ! findIn "apt list --installed" $1; then
apt-get -y install $1
exitOnError "Unable to install $1"
fi
}
isAptRepo()
{
if ! findIn "egrep -v '^#|^ *$' /etc/apt/sources.list /etc/apt/sources.list.d/*" "$1"; then return -1; fi
return 0
}
addAptRepo()
{
if ! isAptRepo "$1"; then
apt-add-repository $1
if ! warnOnError "Unable to add repo $1"; then
apt-get -yq update
fi
fi
}
doIf()
{
findInStr "$($1 2>&1)" $2
if [[ 0 -ne $? ]]; then return 0; fi
if [[ ! -z $4 ]]; then $4 | $3; else $3; fi
}
doIfNot()
{
findInStr "$($1 2>&1)" $2
if [[ 0 -eq $? ]]; then return 0; fi
if [[ ! -z $4 ]]; then $4 | $3; else $3; fi
}
isOnline()
{
wget -q --tries=1 --timeout=8 --spider http://google.com
return $?
}
exitOnErrorAndExec()
{
if [[ 0 -eq $? ]]; then return 0; fi
EXEC=$1
EMSG=$2
if [[ ! -z $EXEC ]]; then
# echo $($EXEC)
showWarning "Not executing : ${EXEC}"
fi
exitWithError $EMSG
}
getPassword()
{
local -n RETVAL=$1
PWDNAME=$2
PWDLEN=$3
if [[ ! -d "$SECRETS" ]]; then
mkdir -p "$SECRETS"
fi
PWDFILE="./${SECRETS}/$PWDNAME.pwd"
if [[ -f $PWDFILE ]]; then
NEWPWD=$(<${PWDFILE})
fi
if [[ -z $NEWPWD ]]; then
showInfo "Creating new password in : ${PWDFILE}"
NEWPWD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c ${PWDLEN})
echo "${NEWPWD}" >> "${PWDFILE}"
else
showInfo "${PWDNAME} password in : ${PWDFILE}"
fi
RETVAL=$NEWPWD
}
#--------------------------------------------------------------------------------------------------
# Los Geht's!
echo
echo "----------------------------------------------------------"
echo "- Commands : $COMMANDLIST"
echo "- Domain Name : $DOMAINNAME"
echo "- Dot Name : $DOTNAME"
echo "----------------------------------------------------------"
echo
export DOMAINNAME=$DOMAINNAME
#--------------------------------------------------------------------------------------------------
showInfo "Starting..."
# Online check
if ! isOnline; then
exitWithError "!!! OFFLINE !!!"
fi
#--------------------------------------------------------------------------------------------------
# Set / Check hostname
if isCmd "setdomain"; then
if [ -z $DOMAINNAME ]; then
exitWithError "Domain name not specified"
fi
CURDOMAIN=$(hostname)
CURDOMAINF=$(hostname -f)
if [[ "$CURDOMAIN" != "$DOMAINNAME" ]] || [[ "$CURDOMAINF" != "$DOMAINNAME" ]]; then
showInfo "Setting hostname..."
hostname -F $DOMAINNAME
hostnamectl set-hostname $DOMAINNAME
systemctl restart systemd-hostnamed
# Update hosts file
sed -i "s/127.0.0.1.*$DOMAINNAME.*//g" /etc/hosts
sed -i "s/127.0.0.1.*localhost.*/127.0.0.1 $DOMAINNAME\n127.0.0.1 localhost/g" /etc/hosts
fi
fi
#--------------------------------------------------------------------------------------------------
# Verify the domain name
CURDOMAIN=$(hostname)
if [[ "$CURDOMAIN" != "$DOMAINNAME" ]]; then
exitWithError "Domain does not match : '$DOMAINNAME' != '$CURDOMAIN' - use command 'setdomain' to set"
fi
CURDOMAINF=$(hostname -f)
echo $CURDOMAINF
if [[ "$CURDOMAINF" != "$DOMAINNAME" ]]; then
exitWithError "Domain -f does not match : '$DOMAINNAME' != '$CURDOMAINF' - use command 'setdomain' to set"
fi
#--------------------------------------------------------------------------------------------------
# Ensure root tools
apt-get -yqq update
#--------------------------------------------------------------------------------------------------
if isCmd "firewall"; then
showInfo "Setting up firewall (ufw)..."
aptInstall "ufw"
# Add rules
doIfNot "ufw show added" "22/tcp" "ufw allow 22/tcp"
# Ensure 22 is in there so we don't get locked out
if ! findIn "ufw show added" "22/tcp"; then
ufw show added
exitWithError "Failed to add ssh to firewall (ufw)"
fi
doIf "ufw status" "inactive" "ufw enable" "yes"
sed -i "0,/#& stop/s//& stop/" /etc/rsyslog.d/20-ufw.conf
systemctl restart rsyslog
fi
#--------------------------------------------------------------------------------------------------
if isCmd "ssl"; then
# See if we have cached credentials
if [[ ! -d "/etc/letsencrypt/live/${DOMAINNAME}" ]]; then
if [[ -f "/ssl/letsencrypt/live/${DOMAINNAME}/fullchain.pem" ]]; then
showInfo "Copying cached credentials for ${DOMAINNAME}..."
mkdir -p "/etc/letsencrypt/live"
cp -R "/ssl/letsencrypt/live/${DOMAINNAME}" "/etc/letsencrypt/live/${DOMAINNAME}"
fi
fi
# Get new credentials
if [[ ! -d "/etc/letsencrypt/live/${DOMAINNAME}" ]]; then
showInfo "Setting up SSL..."
# Get a cert
if [ $DOTNAME == "local" ]; then
showWarning "No SSL for local"
delCmd "ssl"
# CERTDIR="/etc/letsencrypt/live/${DOMAINNAME}"
# mkdir -p $CERTDIR
# openssl req -x509 -newkey rsa:4096 -nodes \
# -keyout "$CERTDIR/privkey.pem" \
# -out "$CERTDIR/fullchain.pem" \
# -days 365 \
# -subj "/C=US/ST=NY/L=NY/O=${COMPANY}/OU=Org/CN=${DOMAINNAME}"
# if [[ 0 -ne $? ]]; then
# rm -Rf "$CERTDIR"
# exitOnError "Error creating self-signed cert for localhost"
# fi
else
aptInstall "software-properties-common"
aptInstall "letsencrypt"
aptInstall "certbot"
STARTAPACHE2=
if findIn "ps cax" "apache2"; then
showWarning "Stopping apache, it will be restarted"
systemctl stop apache2
STARTAPACHE2="systemctl start apache2"
sleep 3
fi
CERTRETRY=1
while [ 0 -lt $CERTRETRY ]; do
# https://letsencrypt.org/docs/rate-limits/
# https://crt.sh
showInfo "Requesting a certificate using certbot..."
certbot certonly --standalone --preferred-challenges http-01 \
--agree-tos --no-eff-email -m cert@${DOMAINNAME} \
-d ${DOMAINNAME}
if [[ 0 -ne $? ]]; then
CERTRETRY=$((CERTRETRY-1))
if [ $CERTRETRY -le 0 ]; then
$STARTAPACHE2
exitWithError "certbot failed"
# delCmd "ssl"
# showWarning "certbot failed, disabling ssl"
else
showWarning "certbot failed, retrying in 30 seconds"
sleep 30
fi
else
CERTRETRY=0
showInfo "certbot succeeded"
# certbot renew --dry-run
fi
done
$STARTAPACHE2
fi
# warnOnError "certbot failed"
else
showInfo "Already have cert for ${DOMAINNAME}"
fi
fi
#--------------------------------------------------------------------------------------------------
if isCmd "apache"; then
showInfo "Installing apache"
systemctl stop apache2
doIfNot "ufw show added" "80/tcp" "ufw allow 80/tcp"
doIfNot "ufw show added" "443/tcp" "ufw allow 443/tcp"
apt-get install -yq apache2
exitOnError "Failed to install apache"
if [[ ! -d "/var/www/${DOMAINNAME}" ]]; then
mkdir -p "/var/www/${DOMAINNAME}"
fi
if [[ ! -f "/var/www/${DOMAINNAME}/index.html" ]]; then
echo "401 - ACCESS DENIED" > "/var/www/${DOMAINNAME}/index.html"
fi
CFG_BASE_SITE="\n
<VirtualHost *:80>\n
ServerName ${DOMAINNAME}\n
Redirect / https://${DOMAINNAME}\n
</VirtualHost>
\n
<VirtualHost _default_:443>\n
ServerName ${DOMAINNAME}\n
DocumentRoot /var/www/${DOMAINNAME}\n
SSLEngine On\n
SSLCertificateFile /etc/letsencrypt/live/${DOMAINNAME}/fullchain.pem\n
SSLCertificateKeyFile /etc/letsencrypt/live/${DOMAINNAME}/privkey.pem\n
ErrorLog \${APACHE_LOG_DIR}/${DOMAINNAME}_error.log\n
CustomLog \${APACHE_LOG_DIR}/${DOMAINNAME}_access.log combined\n
</VirtualHost>\n
"
echo -e ${CFG_BASE_SITE} > /etc/apache2/sites-available/${DOMAINNAME}.conf
a2enmod ssl
warnOnError "Failed to enable apache ssl"
a2dissite 000-default
a2ensite ${DOMAINNAME}
warnOnError "Failed to enable site ${DOMAINNAME}"
# systemctl reload apache2
systemctl start apache2
fi
#--------------------------------------------------------------------------------------------------
showInfo "Success!"
echo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment