feat: Improve Linux installation experience (#4713)

* feat: improve linux install script

* feat: setup logging and reduce verboseness

- redirect output/error to logfile
- reduce verboseness in main script exection
- trap non-zero exit

* chore: remove debug logging

* feat: fix exit handler

* improve legibility

* Apply suggestions from code review

Co-authored-by: Pranav Raj S <pranav@chatwoot.com>

* chore: improve formatting

Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
Vishnu Narayanan 2022-05-25 12:30:00 +05:30 committed by GitHub
parent baa3efaf0e
commit 22d22cf4c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,32 +1,48 @@
#!/usr/bin/env bash
# Description: Chatwoot installation script
# OS: Ubuntu 20.04 LTS / Ubuntu 20.10
# Script Version: 0.8
# OS: Ubuntu 20.04 LTS
# Script Version: 1.0
# Run this script as root
read -p 'Would you like to configure a domain and SSL for Chatwoot?(yes or no): ' configure_webserver
set -eu -o pipefail
trap exit_handler EXIT
if [ $configure_webserver == "yes" ]
then
read -p 'Enter your sub-domain to be used for Chatwoot (chatwoot.domain.com for example) : ' domain_name
echo -e "\nThis script will try to generate SSL certificates via LetsEncrypt and serve chatwoot at
"https://$domain_name". Proceed further once you have pointed your DNS to the IP of the instance.\n"
read -p 'Enter the email LetsEncrypt can use to send reminders when your SSL certificate is up for renewal: ' le_email
read -p 'Do you wish to proceed? (yes or no): ' exit_true
if [ $exit_true == "no" ]
function exit_handler() {
if [ "$?" -ne 0 ]; then
echo -en "\nSome error has occured. Check '/var/log/chatwoot-setup.log' for details.\n"
exit 1
fi
}
if [ "$(id -u)" -ne 0 ]; then
echo 'This script should be run as root.' >&2
exit 1
fi
if [[ -z "$1" ]]; then
BRANCH="master"
else
BRANCH="$1"
fi
function get_domain_info() {
read -rp 'Enter the domain/subdomain for Chatwoot (e.g., chatwoot.domain.com) :' domain_name
read -rp 'Enter an email address for LetsEncrypt to send reminders when your SSL certificate is up for renewal :' le_email
cat << EOF
This script will generate SSL certificates via LetsEncrypt and serve Chatwoot at
https://$domain_name. Proceed further once you have pointed your DNS to the IP of the instance.
EOF
read -rp 'Do you wish to proceed? (yes or no): ' exit_true
if [ "$exit_true" == "no" ]
then
exit 1
fi
fi
read -p 'Would you like to install postgres and redis?(Answer no if you plan to use external services): ' install_pg_redis
if [ $install_pg_redis == "no" ]
then
echo "***** Skipping pg and redis installation. ****"
fi
}
function install_dependencies() {
apt update && apt upgrade -y
apt install -y curl
curl -sL https://deb.nodesource.com/setup_12.x | bash -
@ -41,26 +57,26 @@ apt install -y \
postgresql-client redis-tools \
nodejs yarn patch ruby-dev zlib1g-dev liblzma-dev \
libgmp-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev sudo
}
if [ $install_pg_redis != "no" ]
then
function install_databases() {
apt install -y postgresql postgresql-contrib redis-server
fi
}
if [ $configure_webserver == "yes" ]
then
function install_webserver() {
apt install -y nginx nginx-full certbot python3-certbot-nginx
fi
}
function configure_rvm() {
adduser --disabled-login --gecos "" chatwoot
gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
gpg2 --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
curl -sSL https://get.rvm.io | bash -s stable
adduser chatwoot rvm
}
if [ $install_pg_redis != "no" ]
then
function configure_db() {
pg_pass=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 15 ; echo '')
sudo -i -u postgres psql << EOF
\set pass `echo $pg_pass`
@ -77,8 +93,10 @@ EOF
systemctl enable redis-server.service
systemctl enable postgresql
fi
}
function setup_chatwoot() {
secret=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 63 ; echo '')
RAILS_ENV=production
@ -90,11 +108,7 @@ rvm use 3.0.2 --default
git clone https://github.com/chatwoot/chatwoot.git
cd chatwoot
if [[ -z "$1" ]]; then
git checkout master;
else
git checkout $1;
fi
git checkout "$BRANCH"
bundle
yarn
@ -110,36 +124,37 @@ echo -en "\nINSTALLATION_ENV=linux_script" >> ".env"
rake assets:precompile RAILS_ENV=production
EOF
if [ $install_pg_redis != "no" ]
then
}
function run_db_migrations(){
sudo -i -u chatwoot << EOF
cd chatwoot
RAILS_ENV=production bundle exec rake db:create
RAILS_ENV=production bundle exec rake db:reset
EOF
fi
}
function configure_systemd_services() {
cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service
cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service
cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/chatwoot.target
systemctl enable chatwoot.target
systemctl start chatwoot.target
}
public_ip=$(curl http://checkip.amazonaws.com -s)
if [ $configure_webserver != "yes" ]
then
echo -en "\n\n***************************************************************************\n"
echo "Woot! Woot!! Chatwoot server installation is complete"
echo "The server will be accessible at http://$public_ip:3000"
echo "To configure a domain and SSL certificate, follow the guide at https://www.chatwoot.com/docs/deployment/deploy-chatwoot-in-linux-vm"
echo "***************************************************************************"
else
function setup_ssl() {
echo "debug: setting up ssl"
echo "debug: domain: $domain_name"
echo "debug: letsencrypt email: $le_email"
curl https://ssl-config.mozilla.org/ffdhe4096.txt >> /etc/ssl/dhparam
wget https://raw.githubusercontent.com/chatwoot/chatwoot/develop/deployment/nginx_chatwoot.conf
cp nginx_chatwoot.conf /etc/nginx/sites-available/nginx_chatwoot.conf
certbot certonly --non-interactive --agree-tos --nginx -m $le_email -d $domain_name
certbot certonly --non-interactive --agree-tos --nginx -m "$le_email" -d "$domain_name"
sed -i "s/chatwoot.domain.com/$domain_name/g" /etc/nginx/sites-available/nginx_chatwoot.conf
ln -s /etc/nginx/sites-available/nginx_chatwoot.conf /etc/nginx/sites-enabled/nginx_chatwoot.conf
systemctl restart nginx
@ -148,17 +163,123 @@ cd chatwoot
sed -i "s/http:\/\/0.0.0.0:3000/https:\/\/$domain_name/g" .env
EOF
systemctl restart chatwoot.target
echo -en "\n\n***************************************************************************\n"
echo "Woot! Woot!! Chatwoot server installation is complete"
echo "The server will be accessible at https://$domain_name"
echo "***************************************************************************"
fi
}
function setup_logging() {
touch /var/log/chatwoot-setup.log
LOG_FILE="/var/log/chatwoot-setup.log"
}
if [ $install_pg_redis == "no" ]
function main() {
setup_logging
cat << EOF
***************************************************************************
Chatwoot Installation (latest)
***************************************************************************
For more verbose logs, open up a second terminal and follow along using, `tail -f /var/log/chatwoot`.
EOF
sleep 3
read -rp 'Would you like to configure a domain and SSL for Chatwoot?(yes or no): ' configure_webserver
if [ "$configure_webserver" == "yes" ]
then
echo -en "\n\n***************************************************************************\n"
echo "DB migrations are not run as pg and redis is not installed."
echo "After modifying .env with your external db creds, run db migrations !!!"
echo "***************************************************************************"
get_domain_info
fi
echo -en "\n"
read -rp 'Would you like to install Postgres and Redis? (Answer no if you plan to use external services): ' install_pg_redis
if [ "$install_pg_redis" == "no" ]
then
echo "***** Skipping Postgres and Redis installation. ****"
fi
echo -en "\n➥ 1/9 Installing dependencies. This takes a while."
install_dependencies &>> "${LOG_FILE}"
if [ "$install_pg_redis" != "no" ]
then
echo "➥ 2/9 Installing databases"
install_databases &>> "${LOG_FILE}"
fi
if [ "$configure_webserver" == "yes" ]
then
echo "➥ 3/9 Installing webserver"
install_webserver &>> "${LOG_FILE}"
fi
echo "➥ 4/9 Setting up Ruby"
configure_rvm &>> "${LOG_FILE}"
if [ "$install_pg_redis" != "no" ]
then
echo "➥ 5/9 Setting up the database"
configure_db &>> "${LOG_FILE}"
fi
echo "➥ 6/9 Installing Chatwoot. This takes a while."
setup_chatwoot &>> "${LOG_FILE}"
if [ "$install_pg_redis" != "no" ]
then
echo "➥ 7/9 Running migrations"
run_db_migrations &>> "${LOG_FILE}"
fi
echo "➥ 8/9 Setting up systemd services"
configure_systemd_services &>> "${LOG_FILE}"
public_ip=$(curl http://checkip.amazonaws.com -s)
if [ "$configure_webserver" != "yes" ]
then
cat << EOF
***************************************************************************
Woot! Woot!! Chatwoot server installation is complete.
The server will be accessible at http://$public_ip:3000
To configure a domain and SSL certificate, follow the guide at
https://www.chatwoot.com/docs/deployment/deploy-chatwoot-in-linux-vm
Join the community at https://chatwoot.com/community
***************************************************************************
EOF
else
echo "➥ 9/9 Setting up SSL/TLS"
setup_ssl &>> "${LOG_FILE}"
cat << EOF
***************************************************************************
Woot! Woot!! Chatwoot server installation is complete.
The server will be accessible at https://$domain_name
Join the community at https://chatwoot.com/community
***************************************************************************
EOF
fi
if [ "$install_pg_redis" == "no" ]
then
cat <<EOF
***************************************************************************
The database migrations had not run as Postgres and Redis were not installed
as part of the installation process. After modifying the environment
variables (in the .env file) with your external database credentials, run
the database migrations using the below command.
`RAILS_ENV=production bundle exec rails db:chatwoot_prepare`.
***************************************************************************
EOF
fi
exit 0
}
main "$@"