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 #!/usr/bin/env bash
# Description: Chatwoot installation script # Description: Chatwoot installation script
# OS: Ubuntu 20.04 LTS / Ubuntu 20.10 # OS: Ubuntu 20.04 LTS
# Script Version: 0.8 # Script Version: 1.0
# Run this script as root # 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" ] function exit_handler() {
then if [ "$?" -ne 0 ]; then
read -p 'Enter your sub-domain to be used for Chatwoot (chatwoot.domain.com for example) : ' domain_name echo -en "\nSome error has occured. Check '/var/log/chatwoot-setup.log' for details.\n"
echo -e "\nThis script will try to generate SSL certificates via LetsEncrypt and serve chatwoot at exit 1
"https://$domain_name". Proceed further once you have pointed your DNS to the IP of the instance.\n" fi
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" ] 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 then
exit 1 exit 1
fi 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 update && apt upgrade -y
apt install -y curl apt install -y curl
curl -sL https://deb.nodesource.com/setup_12.x | bash - curl -sL https://deb.nodesource.com/setup_12.x | bash -
@ -41,26 +57,26 @@ apt install -y \
postgresql-client redis-tools \ postgresql-client redis-tools \
nodejs yarn patch ruby-dev zlib1g-dev liblzma-dev \ nodejs yarn patch ruby-dev zlib1g-dev liblzma-dev \
libgmp-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev sudo libgmp-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev sudo
}
if [ $install_pg_redis != "no" ] function install_databases() {
then
apt install -y postgresql postgresql-contrib redis-server apt install -y postgresql postgresql-contrib redis-server
fi }
if [ $configure_webserver == "yes" ] function install_webserver() {
then
apt install -y nginx nginx-full certbot python3-certbot-nginx apt install -y nginx nginx-full certbot python3-certbot-nginx
fi }
function configure_rvm() {
adduser --disabled-login --gecos "" chatwoot adduser --disabled-login --gecos "" chatwoot
gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
gpg2 --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 curl -sSL https://get.rvm.io | bash -s stable
adduser chatwoot rvm adduser chatwoot rvm
}
if [ $install_pg_redis != "no" ] function configure_db() {
then
pg_pass=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 15 ; echo '') pg_pass=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 15 ; echo '')
sudo -i -u postgres psql << EOF sudo -i -u postgres psql << EOF
\set pass `echo $pg_pass` \set pass `echo $pg_pass`
@ -77,8 +93,10 @@ EOF
systemctl enable redis-server.service systemctl enable redis-server.service
systemctl enable postgresql systemctl enable postgresql
fi
}
function setup_chatwoot() {
secret=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 63 ; echo '') secret=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 63 ; echo '')
RAILS_ENV=production RAILS_ENV=production
@ -90,11 +108,7 @@ rvm use 3.0.2 --default
git clone https://github.com/chatwoot/chatwoot.git git clone https://github.com/chatwoot/chatwoot.git
cd chatwoot cd chatwoot
if [[ -z "$1" ]]; then git checkout "$BRANCH"
git checkout master;
else
git checkout $1;
fi
bundle bundle
yarn yarn
@ -110,36 +124,37 @@ echo -en "\nINSTALLATION_ENV=linux_script" >> ".env"
rake assets:precompile RAILS_ENV=production rake assets:precompile RAILS_ENV=production
EOF EOF
if [ $install_pg_redis != "no" ] }
then
function run_db_migrations(){
sudo -i -u chatwoot << EOF sudo -i -u chatwoot << EOF
cd chatwoot cd chatwoot
RAILS_ENV=production bundle exec rake db:create RAILS_ENV=production bundle exec rake db:create
RAILS_ENV=production bundle exec rake db:reset RAILS_ENV=production bundle exec rake db:reset
EOF 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-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-worker.1.service /etc/systemd/system/chatwoot-worker.1.service
cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/chatwoot.target cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/chatwoot.target
systemctl enable chatwoot.target systemctl enable chatwoot.target
systemctl start chatwoot.target systemctl start chatwoot.target
}
public_ip=$(curl http://checkip.amazonaws.com -s)
if [ $configure_webserver != "yes" ] function setup_ssl() {
then echo "debug: setting up ssl"
echo -en "\n\n***************************************************************************\n" echo "debug: domain: $domain_name"
echo "Woot! Woot!! Chatwoot server installation is complete" echo "debug: letsencrypt email: $le_email"
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
curl https://ssl-config.mozilla.org/ffdhe4096.txt >> /etc/ssl/dhparam curl https://ssl-config.mozilla.org/ffdhe4096.txt >> /etc/ssl/dhparam
wget https://raw.githubusercontent.com/chatwoot/chatwoot/develop/deployment/nginx_chatwoot.conf wget https://raw.githubusercontent.com/chatwoot/chatwoot/develop/deployment/nginx_chatwoot.conf
cp nginx_chatwoot.conf /etc/nginx/sites-available/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 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 ln -s /etc/nginx/sites-available/nginx_chatwoot.conf /etc/nginx/sites-enabled/nginx_chatwoot.conf
systemctl restart nginx systemctl restart nginx
@ -148,17 +163,123 @@ cd chatwoot
sed -i "s/http:\/\/0.0.0.0:3000/https:\/\/$domain_name/g" .env sed -i "s/http:\/\/0.0.0.0:3000/https:\/\/$domain_name/g" .env
EOF EOF
systemctl restart chatwoot.target 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 then
echo -en "\n\n***************************************************************************\n" get_domain_info
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 "***************************************************************************"
fi 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 "$@"