#!/bin/bash
+##
+## Make sure only root can run our script
+##
+check_root() {
+ if [[ $EUID -ne 0 ]]; then
+ echo "This script must be run as root. Please sudo or log in as root first." 1>&2
+ exit 1
+ fi
+}
+
+
+##
+## Do we have docker?
+##
+check_and_install_docker () {
+ docker_path=`which docker.io || which docker`
+ if [ -z $docker_path ]; then
+ read -p "Docker not installed. Enter to install from https://get.docker.com/ or Ctrl+C to exit"
+ curl https://get.docker.com/ | sh
+ fi
+ docker_path=`which docker.io || which docker`
+ if [ -z $docker_path ]; then
+ echo Docker install failed. Quitting.
+ exit
+ fi
+}
+
+##
+## What are we running on
+##
+check_OS() {
+ echo `uname -s`
+}
+
+##
+## OS X available memory
+##
+check_osx_memory() {
+ echo `top -l 1 | awk '/PhysMem:/ {print $2}' | sed s/G//`
+}
+
+##
+## Linux available memory
+##
+check_linux_memory() {
+ echo `free -g --si | awk ' /Mem:/ {print $2} '`
+}
+
##
## Do we have enough memory and disk space for Discourse?
##
check_disk_and_memory() {
-
- resources="ok"
- avail_mem="$(LANG=C free -m | grep '^Mem:' | awk '{print $2}')"
- if [ "$avail_mem" -lt 900 ]; then
- resources="insufficient"
- echo "WARNING: Discourse requires 1GB RAM to run. This system does not appear to have sufficient memory."
- echo
- echo "Your site may not work properly, or future upgrades of Discourse may not complete successfully."
+
+ os_type=$(check_OS)
+ avail_mem=0
+ if [ $os_type == "Darwin" ]; then
+ avail_mem=$(check_osx_memory)
+ else
+ avail_mem=$(check_linux_memory)
+ fi
+
+ if [ "$avail_mem" -lt 1 ]; then
+ echo "WARNING: Discourse requires 1GB RAM to run. This system does not appear"
+ echo "to have sufficient memory."
echo
- echo "See https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md#create-new-cloud-server"
- elif [ "$avail_mem" -lt 1800 ]; then
- total_swap="$(LANG=C free -m | grep ^Swap: | awk '{print $2}')"
- if [ "$total_swap" -lt 1000 ]; then
- resources="insufficient"
- echo "WARNING: Discourse requires at least 1GB of swap when running with less than 2GB of RAM. This system does not appear to have sufficient swap space."
+ echo "Your site may not work properly, or future upgrades of Discourse may not"
+ echo "complete successfully."
+ exit 1
+ fi
+
+ if [ "$avail_mem" -le 2 ]; then
+ total_swap=`free -g --si | awk ' /Swap:/ {print $2} '`
+ if [ "$total_swap" -lt 2 ]; then
+ echo "WARNING: Discourse requires at least 2GB of swap when running with 2GB of RAM"
+ echo "or less. This system does not appear to have sufficient swap space."
echo
- echo "Without sufficient swap space, your site may not work properly, or future upgrades of Discourse may not complete successfully."
+ echo "Without sufficient swap space, your site may not work properly, and future"
+ echo "upgrades of Discourse may not complete successfully."
echo
- echo "See https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md#set-up-swap-if-needed"
+ read -p "ENTER to create a 2GB swapfile now, or Ctrl+C to exit"
+
+ ##
+ ## derived from https://meta.discourse.org/t/13880
+ ##
+ install -o root -g root -m 0600 /dev/null /swapfile
+ dd if=/dev/zero of=/swapfile bs=1k count=2048k
+ mkswap /swapfile
+ swapon /swapfile
+ echo "/swapfile swap swap auto 0 0" | tee -a /etc/fstab
+ sysctl -w vm.swappiness=10
+ echo vm.swappiness = 10 | tee -a /etc/sysctl.conf
+
+ total_swap=`free -g --si | awk ' /Swap:/ {print $2} '`
+ if [ "$total_swap" -lt 2 ]; then
+ echo "Failed to create swap, sorry!"
+ exit 1
+ fi
+
fi
fi
+
free_disk="$(df /var | tail -n 1 | awk '{print $4}')"
if [ "$free_disk" -lt 5000 ]; then
- resources="insufficient"
- echo "WARNING: Discourse requires at least 5GB free disk space. This system does not appear to have sufficient disk space."
+ echo "WARNING: Discourse requires at least 5GB free disk space. This system"
+ echo "does not appear to have sufficient disk space."
echo
- echo "Insufficient disk space may result in problems running your site, and may not even allow Discourse installation to complete successfully."
+ echo "Insufficient disk space may result in problems running your site, and"
+ echo "may not even allow Discourse installation to complete successfully."
echo
echo "Please free up some space, or expand your disk, before continuing."
echo
- echo "Run \`apt-get autoremove && apt-get autoclean\` to clean up unused packages and \`./launcher cleanup\` to remove stale Docker containers."
+ echo "Run \`apt-get autoremove && apt-get autoclean\` to clean up unused"
+ echo "packages and \`./launcher cleanup\` to remove stale Docker containers."
exit 1
fi
- if [ -t 0 ] && [ "$resources" != "ok" ]; then
- echo
- read -p "Press ENTER to continue, or Ctrl-C to exit and give your system more resources"
- fi
}
local changelog=/tmp/changelog.$PPID
# grab info about total system ram and physical (NOT LOGICAL!) CPU cores
- avail_mem="$(LANG=C free -m | grep '^Mem:' | awk '{print $2}')"
- avail_gb=$(( $avail_mem / 950 ))
- avail_cores=`cat /proc/cpuinfo | grep "cpu cores" | uniq | awk '{print $4}'`
+ avail_gb=0
+ avail_cores=0
+ os_type=$(check_OS)
+ if [ $os_type == "Darwin" ]; then
+ avail_gb=$(check_osx_memory)
+ avail_cores=`sysctl hw.ncpu | awk '/hw.ncpu:/ {print $2}'`
+ else
+ avail_gb=$(check_linux_memory)
+ avail_cores=$((`awk '/cpu cores/ {print $4;exit}' /proc/cpuinfo`*`sort /proc/cpuinfo | uniq | grep -c "physical id"`))
+ fi
echo "Found ${avail_gb}GB of memory and $avail_cores physical CPU cores"
# db_shared_buffers: 128MB for 1GB, 256MB for 2GB, or 256MB * GB, max 4096MB
}
-##
+##
## standard http / https ports must not be occupied
##
check_ports() {
## check a port to see if it is already in use
##
check_port() {
-
+
local valid=$(netstat -tln | awk '{print $4}' | grep ":${1}\$")
if [ -n "$valid" ]; then
echo "Port ${1} appears to already be in use."
echo
- echo "If you are trying to run Discourse simultaneously with another web server like Apache or nginx, you will need to bind to a different port -- see https://meta.discourse.org/t/17247 for help."
+ echo "If you are trying to run Discourse simultaneously with another web"
+ echo "server like Apache or nginx, you will need to bind to a different port"
+ echo
+ echo "See https://meta.discourse.org/t/17247"
exit 1
fi
}
## prompt user for typical Discourse config file values
##
ask_user_for_config() {
-
+
local changelog=/tmp/changelog.$PPID
local hostname="discourse.example.com"
local developer_emails="me@example.com,you@example.com"
local smtp_address="smtp.example.com"
+ local smtp_port="587"
local smtp_user_name="postmaster@discourse.example.com"
local smtp_password=""
local letsencrypt_account_email="me@example.com"
local new_value=""
local config_ok="n"
local update_ok="y"
-
+
echo ""
while [[ "$config_ok" == "n" ]]
hostname=$new_value
fi
fi
-
+
if [ ! -z $developer_emails ]
then
read -p "Email address for admin account? [$developer_emails]: " new_value
developer_emails=$new_value
fi
fi
-
+
if [ ! -z $smtp_address ]
then
read -p "SMTP server address? [$smtp_address]: " new_value
smtp_address=$new_value
fi
fi
-
+
+ if [ ! -z $smtp_port ]
+ then
+ read -p "SMTP port? [$smtp_port]: " new_value
+ if [ ! -z $new_value ]
+ then
+ smtp_port=$new_value
+ fi
+ fi
+
+ ##
+ ## automatically set correct user name based on common mail providers
+ ##
if [ "$smtp_address" == "smtp.sparkpostmail.com" ]
then
smtp_user_name="SMTP_Injection"
fi
-
if [ "$smtp_address" == "smtp.sendgrid.net" ]
then
smtp_user_name="apikey"
fi
-
+ if [ "$smtp_address" == "smtp.mailgun.org" ]
+ then
+ smtp_user_name="postmaster@$hostname"
+ fi
+
if [ ! -z $smtp_user_name ]
then
read -p "SMTP user name? [$smtp_user_name]: " new_value
smtp_user_name=$new_value
fi
fi
-
+
read -p "SMTP password? [$smtp_password]: " new_value
if [ ! -z $new_value ]
then
smtp_password=$new_value
fi
-
+
if [ ! -z $letsencrypt_account_email ]
then
read -p "Let's Encrypt account email? ($letsencrypt_status) [$letsencrypt_account_email]: " new_value
fi
fi
- echo -e "\nThat's it! Everything is set. Does this look right?\n"
+ echo -e "\nDoes this look right?\n"
echo "Hostname : $hostname"
echo "Email : $developer_emails"
echo "SMTP address : $smtp_address"
+ echo "SMTP port : $smtp_port"
echo "SMTP username : $smtp_user_name"
echo "SMTP password : $smtp_password"
-
+
if [ "$letsencrypt_status" == "Enter 'OFF' to disable." ]
then
echo "Let's Encrypt : $letsencrypt_account_email"
fi
-
+
echo ""
- read -p "Press ENTER to continue, 'n' to try again, or ^C to exit: " config_ok
+ read -p "ENTER to continue, 'n' to try again, Ctrl+C to exit: " config_ok
done
sed -i -e "s/^ DISCOURSE_HOSTNAME:.*/ DISCOURSE_HOSTNAME: $hostname/w $changelog" $config_file
update_ok="n"
fi
+ sed -i -e "s/^ #DISCOURSE_SMTP_PORT:.*/ DISCOURSE_SMTP_PORT: $smtp_port/w $changelog" $config_file
+ if [ -s $changelog ]
+ then
+ rm $changelog
+ else
+ echo "DISCOURSE_SMTP_PORT change failed."
+ update_ok="n"
+ fi
+
sed -i -e "s/^ #DISCOURSE_SMTP_USER_NAME:.*/ DISCOURSE_SMTP_USER_NAME: $smtp_user_name/w $changelog" $config_file
if [ -s $changelog ]
then
update_ok="n"
fi
- sed -i -e "s/^ #DISCOURSE_SMTP_PASSWORD:.*/ DISCOURSE_SMTP_PASSWORD: $smtp_password/w $changelog" $config_file
+ sed -i -e "s/^ #DISCOURSE_SMTP_PASSWORD:.*/ DISCOURSE_SMTP_PASSWORD: \"${smtp_password/\//\\/}\"/w $changelog" $config_file
if [ -s $changelog ]
then
rm $changelog
update_ok="n"
echo "letsencrypt.ssl.template.yml NOT ENABLED -- was it on already?"
fi
- fi
+ fi
if [ "$update_ok" == "y" ]
then
validate_config() {
valid_config="y"
-
+
for x in DISCOURSE_SMTP_ADDRESS DISCOURSE_SMTP_USER_NAME DISCOURSE_SMTP_PASSWORD \
DISCOURSE_DEVELOPER_EMAILS DISCOURSE_HOSTNAME
do
- config_line=`grep "^ $x:" $config_file`
+ config_line=`grep "^ $x:" $config_file`
local result=$?
local default="example.com"
valid_config="n"
fi
done
-
+
if [ "$valid_config" != "y" ]; then
echo -e "\nSorry, these $config_file settings aren't valid -- can't continue!"
+ echo "If you have unusual requirements, edit $config_file and then: "
+ echo "./launcher bootstrap $app_name"
exit 1
fi
}
##
## Check requirements before creating a copy of a config file we won't edit
##
+check_root
+check_and_install_docker
check_disk_and_memory
check_ports
##
## if we reach this point without exiting, OK to proceed
##
-./launcher bootstrap $app_name
-./launcher start $app_name
\ No newline at end of file
+./launcher bootstrap $app_name && ./launcher start $app_name