Fix code that tests for RAM and Swap size
[discourse_docker.git] / discourse-setup
old mode 100644 (file)
new mode 100755 (executable)
index 797f5a8..69c5df5
@@ -1,52 +1,77 @@
 #!/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 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: You do not appear to have sufficient memory to run Discourse."
+  avail_mem=`free -g --si | awk ' /Mem:/  {print $2} '`
+  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 "Your system may not work properly, or future upgrades of Discourse may"
-    echo "not complete successfully."
-    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: You must have at least 1GB of swap when running with less"
-      echo "than 2GB of RAM."
+    echo "Your site may not work properly, or future upgrades of Discourse may not"
+    echo "complete successfully."
+    echo exit 1
+  fi
+    
+  if [ "$avail_mem" -lt 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 less "
+      echo "than 2GB of RAM. This system does not appear to have sufficient swap space."
       echo
-      echo "Your system may not work properly, or future upgrades of Discourse may"
-      echo "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: You must have at least 5GB of *free* disk space to run Discourse."
+    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"
-    echo "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
 }
 
 
@@ -55,9 +80,9 @@ check_disk_and_memory() {
 ##
 scale_ram_and_cpu() {
 
+  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_gb="$(LANG=C free -g --si | grep '^Mem:' | awk '{print $2}')"
   avail_cores=`cat /proc/cpuinfo | grep "cpu cores" | uniq | awk '{print $4}'`
   echo "Found ${avail_gb}GB of memory and $avail_cores physical CPU cores"
 
@@ -82,7 +107,6 @@ scale_ram_and_cpu() {
     rm $changelog
   fi
 
-
   # UNICORN_WORKERS: 2 * GB for 2GB or less, or 2 * CPU, max 8
   if [ "$avail_gb" -le "2" ]
   then
@@ -122,7 +146,10 @@ check_port() {
   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
 }
@@ -130,12 +157,14 @@ check_port() {
 ##
 ## prompt user for typical Discourse config file values
 ##
-set_config() {
+ask_user_for_config() {
   
+  local changelog=/tmp/changelog.$PPID
   local hostname="discourse.example.com"
-  local developer_emails="me@example.com"
+  local developer_emails="me@example.com,you@example.com"
   local smtp_address="smtp.example.com"
-  local smtp_user_name="postmaster@discourse.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 letsencrypt_status="ENTER to skip"
@@ -175,15 +204,30 @@ set_config() {
       fi
     fi
     
-    if [ "$smtp_address" == "smtp.sparkpostmail.com" ]
+    if [ ! -z $smtp_port ]
     then
-       smtp_user_name="SMTP_Injection"
+      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
@@ -215,10 +259,11 @@ set_config() {
       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"
     
@@ -228,10 +273,10 @@ set_config() {
     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.example.com'/  DISCOURSE_HOSTNAME: $hostname/w $changelog" $config_file
+  sed -i -e "s/^  DISCOURSE_HOSTNAME:.*/  DISCOURSE_HOSTNAME: $hostname/w $changelog" $config_file
   if [ -s $changelog ]
   then
     rm $changelog
@@ -249,7 +294,7 @@ set_config() {
     update_ok="n"
   fi
 
-  sed -i -e "s/^  DISCOURSE_SMTP_ADDRESS: smtp.example.com.*/  DISCOURSE_SMTP_ADDRESS: $smtp_address/w $changelog" $config_file
+  sed -i -e "s/^  DISCOURSE_SMTP_ADDRESS:.*/  DISCOURSE_SMTP_ADDRESS: $smtp_address/w $changelog" $config_file
   if [ -s $changelog ]
   then
     rm $changelog
@@ -258,7 +303,16 @@ set_config() {
     update_ok="n"
   fi
 
-  sed -i -e "s/^  #DISCOURSE_SMTP_USER_NAME: user@example.com.*/  DISCOURSE_SMTP_USER_NAME: $smtp_user_name/w $changelog" $config_file
+  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
     rm $changelog
@@ -267,7 +321,7 @@ set_config() {
     update_ok="n"
   fi
 
-  sed -i -e "s/^  #DISCOURSE_SMTP_PASSWORD: pa\$\$word.*/  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
@@ -278,7 +332,7 @@ set_config() {
 
   if [ "$letsencrypt_status" != "ENTER to skip" ]
   then
-      sed -i -e "s/^  #LETSENCRYPT_ACCOUNT_EMAIL: your.email@example.com/  LETSENCRYPT_ACCOUNT_EMAIL: $letsencrypt_account_email/w $changelog" $config_file
+      sed -i -e "s/^  #LETSENCRYPT_ACCOUNT_EMAIL:.*/  LETSENCRYPT_ACCOUNT_EMAIL: $letsencrypt_account_email/w $changelog" $config_file
       if [ -s $changelog ]
       then
         rm $changelog
@@ -291,7 +345,7 @@ set_config() {
       sed -i -e "s/$src/$dst/w $changelog" $config_file
       if [ -s $changelog ]
       then
-             echo "web.ssl.template.yml enabled"
+         echo "web.ssl.template.yml enabled"
       else
         update_ok="n"
         echo "web.ssl.template.yml NOT ENABLED--was it on already?"
@@ -321,7 +375,7 @@ set_config() {
 ##
 ## is our config file valid? Does it have the required fields set?
 ##
-valid_config_check() {
+validate_config() {
 
   valid_config="y"
   
@@ -353,6 +407,8 @@ valid_config_check() {
   
   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
 }
@@ -366,8 +422,16 @@ template_path=samples/standalone.yml
 config_file=containers/$app_name.yml
 changelog=/tmp/changelog
 
-## make a copy of the simple standalone config file
+##
+## Check requirements before creating a copy of a config file we won't edit
+##
+check_root
+check_disk_and_memory
+check_ports
 
+##
+## make a copy of the simple standalone config file
+##
 if [ -a $config_file ]
 then
   echo "The configuration file $config_file already exists!"
@@ -379,10 +443,11 @@ else
   cp $template_path $config_file
 fi
 
-check_disk_and_memory
-check_ports
 scale_ram_and_cpu
-set_config
-valid_config_check
+ask_user_for_config
+validate_config
 
-./launcher bootstrap $app_name
+##
+## if we reach this point without exiting, OK to proceed
+##
+./launcher bootstrap $app_name && ./launcher start $app_name