Merge pull request #297 from simongareste/master
[discourse_docker.git] / discourse-setup
index e881dd810e6ffff23215372faca4fd1e95525c6e..8026da078e4a5efcfa3be612a4b7eb0168eb14e0 100755 (executable)
@@ -1,12 +1,67 @@
 #!/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() {
-  
-  avail_mem="$(LANG=C free -m | grep '^Mem:' | awk '{print $2}')"
-  if [ "$avail_mem" -lt 900 ]; then
+
+  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
@@ -14,38 +69,39 @@ check_disk_and_memory() {
     echo "complete successfully."
     exit 1
   fi
-    
-  if [ "$avail_mem" -lt 1800 ]; then
-    total_swap="$(LANG=C free -m | grep ^Swap: | awk '{print $2}')"
-    if [ "$total_swap" -lt 1000 ]; then
-      echo "WARNING: Discourse requires at least 1GB of swap when running with less "
-      echo "than 2GB of RAM. This system does not appear to have sufficient swap space."
+
+  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, and future"
       echo "upgrades of Discourse may not complete successfully."
       echo
-      read -p "ENTER to create a 2GB swapfile automatically, or Ctrl-C to exit"
-      
+      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" | sudo tee -a /etc/fstab
-      sudo sysctl -w vm.swappiness=10
-      echo vm.swappiness = 10 | sudo tee -a /etc/sysctl.conf
+      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="$(LANG=C free -m | grep ^Swap: | awk '{print $2}')"
-      if [ "$total_swap" -lt 1000 ]; then
+      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
     echo "WARNING: Discourse requires at least 5GB free disk space. This system"
@@ -71,9 +127,16 @@ 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_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=`cat /proc/cpuinfo | grep "cpu cores" | uniq | awk '{print $4}'`
+  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
@@ -116,7 +179,7 @@ scale_ram_and_cpu() {
 }
 
 
-## 
+##
 ## standard http / https ports must not be occupied
 ##
 check_ports() {
@@ -130,7 +193,7 @@ 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
@@ -138,7 +201,7 @@ check_port() {
     echo
     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
     echo "See https://meta.discourse.org/t/17247"
     exit 1
   fi
@@ -148,11 +211,12 @@ check_port() {
 ## 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"
@@ -161,7 +225,7 @@ ask_user_for_config() {
   local new_value=""
   local config_ok="n"
   local update_ok="y"
-  
+
   echo ""
 
   while [[ "$config_ok" == "n" ]]
@@ -174,7 +238,7 @@ ask_user_for_config() {
           hostname=$new_value
       fi
     fi
-    
+
     if [ ! -z $developer_emails ]
     then
       read -p "Email address for admin account? [$developer_emails]: " new_value
@@ -183,7 +247,7 @@ ask_user_for_config() {
           developer_emails=$new_value
       fi
     fi
-    
+
     if [ ! -z $smtp_address ]
     then
       read -p "SMTP server address? [$smtp_address]: " new_value
@@ -192,17 +256,32 @@ ask_user_for_config() {
         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
@@ -211,13 +290,13 @@ ask_user_for_config() {
           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
@@ -237,16 +316,17 @@ ask_user_for_config() {
     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 "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
@@ -276,6 +356,15 @@ ask_user_for_config() {
     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
@@ -285,7 +374,7 @@ ask_user_for_config() {
     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
@@ -325,7 +414,7 @@ ask_user_for_config() {
         update_ok="n"
         echo "letsencrypt.ssl.template.yml NOT ENABLED -- was it on already?"
       fi
-  fi 
+  fi
 
   if [ "$update_ok" == "y" ]
   then
@@ -342,11 +431,11 @@ ask_user_for_config() {
 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"
 
@@ -368,9 +457,11 @@ validate_config() {
       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
 }
@@ -387,6 +478,8 @@ changelog=/tmp/changelog
 ##
 ## 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
 
@@ -411,5 +504,4 @@ validate_config
 ##
 ## if we reach this point without exiting, OK to proceed
 ##
-./launcher bootstrap $app_name
-./launcher start $app_name
+./launcher bootstrap $app_name && ./launcher start $app_name