4 ## Make sure only root can run our script
7 if [[ $EUID -ne 0 ]]; then
8 echo "This script must be run as root. Please sudo or log in as root first." 1>&2
17 check_and_install_docker
() {
18 docker_path
=`which docker.io || which docker`
19 if [ -z $docker_path ]; then
20 read -p "Docker not installed. Enter to install from https://get.docker.com/ or Ctrl+C to exit"
21 curl https
://get.docker.com
/ | sh
23 docker_path
=`which docker.io || which docker`
24 if [ -z $docker_path ]; then
25 echo Docker
install failed. Quitting.
32 ## Do we have enough memory and disk space for Discourse?
34 check_disk_and_memory
() {
36 avail_mem
=`free -g --si | awk ' /Mem:/ {print $2} '`
37 if [ "$avail_mem" -lt 1 ]; then
38 echo "WARNING: Discourse requires 1GB RAM to run. This system does not appear"
39 echo "to have sufficient memory."
41 echo "Your site may not work properly, or future upgrades of Discourse may not"
42 echo "complete successfully."
46 if [ "$avail_mem" -lt 2 ]; then
47 total_swap
=`free -g --si | awk ' /Swap:/ {print $2} '`
48 if [ "$total_swap" -lt 2 ]; then
49 echo "WARNING: Discourse requires at least 2GB of swap when running with less "
50 echo "than 2GB of RAM. This system does not appear to have sufficient swap space."
52 echo "Without sufficient swap space, your site may not work properly, and future"
53 echo "upgrades of Discourse may not complete successfully."
55 read -p "ENTER to create a 2GB swapfile now, or Ctrl+C to exit"
58 ## derived from https://meta.discourse.org/t/13880
60 install -o root
-g root
-m 0600 /dev
/null
/swapfile
61 dd if=/dev
/zero of
=/swapfile bs
=1k count
=2048k
64 echo "/swapfile swap swap auto 0 0" |
tee -a /etc
/fstab
65 sysctl
-w vm.swappiness
=10
66 echo vm.swappiness
= 10 |
tee -a /etc
/sysctl.conf
68 total_swap
=`free -g --si | awk ' /Swap:/ {print $2} '`
69 if [ "$total_swap" -lt 2 ]; then
70 echo "Failed to create swap, sorry!"
78 free_disk
="$(df /var | tail -n 1 | awk '{print $4}')"
79 if [ "$free_disk" -lt 5000 ]; then
80 echo "WARNING: Discourse requires at least 5GB free disk space. This system"
81 echo "does not appear to have sufficient disk space."
83 echo "Insufficient disk space may result in problems running your site, and"
84 echo "may not even allow Discourse installation to complete successfully."
86 echo "Please free up some space, or expand your disk, before continuing."
88 echo "Run \`apt-get autoremove && apt-get autoclean\` to clean up unused"
89 echo "packages and \`./launcher cleanup\` to remove stale Docker containers."
97 ## If we have lots of RAM or lots of CPUs, bump up the defaults to scale better
101 local changelog
=/tmp
/changelog.
$PPID
102 # grab info about total system ram and physical (NOT LOGICAL!) CPU cores
103 avail_gb
="$(LANG=C free -g --si | grep '^Mem:' | awk '{print $2}')"
104 avail_cores
=`cat /proc/cpuinfo | grep "cpu cores" | uniq | awk '{print $4}'`
105 echo "Found ${avail_gb}GB of memory and $avail_cores physical CPU cores"
107 # db_shared_buffers: 128MB for 1GB, 256MB for 2GB, or 256MB * GB, max 4096MB
108 if [ "$avail_gb" -eq "1" ]
110 db_shared_buffers
=128
112 if [ "$avail_gb" -eq "2" ]
114 db_shared_buffers
=256
116 db_shared_buffers
=$
(( 256 * $avail_gb ))
119 db_shared_buffers
=$
(( db_shared_buffers
< 4096 ? db_shared_buffers
: 4096 ))
121 sed -i -e "s/^ #db_shared_buffers:.*/ db_shared_buffers: \"${db_shared_buffers}MB\"/w $changelog" $config_file
124 echo "setting db_shared_buffers = ${db_shared_buffers}MB"
128 # UNICORN_WORKERS: 2 * GB for 2GB or less, or 2 * CPU, max 8
129 if [ "$avail_gb" -le "2" ]
131 unicorn_workers
=$
(( 2 * $avail_gb ))
133 unicorn_workers
=$
(( 2 * $avail_cores ))
135 unicorn_workers
=$
(( unicorn_workers
< 8 ? unicorn_workers
: 8 ))
137 sed -i -e "s/^ #UNICORN_WORKERS:.*/ UNICORN_WORKERS: ${unicorn_workers}/w $changelog" $config_file
140 echo "setting UNICORN_WORKERS = ${unicorn_workers}"
148 ## standard http / https ports must not be occupied
153 echo "Ports 80 and 443 are free for use"
158 ## check a port to see if it is already in use
162 local valid
=$
(netstat
-tln |
awk '{print $4}' |
grep ":${1}\$")
164 if [ -n "$valid" ]; then
165 echo "Port ${1} appears to already be in use."
167 echo "If you are trying to run Discourse simultaneously with another web"
168 echo "server like Apache or nginx, you will need to bind to a different port"
170 echo "See https://meta.discourse.org/t/17247"
176 ## prompt user for typical Discourse config file values
178 ask_user_for_config
() {
180 local changelog
=/tmp
/changelog.
$PPID
181 local hostname
="discourse.example.com"
182 local developer_emails
="me@example.com,you@example.com"
183 local smtp_address
="smtp.example.com"
184 local smtp_port
="587"
185 local smtp_user_name
="postmaster@discourse.example.com"
186 local smtp_password
=""
187 local letsencrypt_account_email
="me@example.com"
188 local letsencrypt_status
="ENTER to skip"
196 while [[ "$config_ok" == "n" ]]
198 if [ ! -z $hostname ]
200 read -p "Hostname for your Discourse? [$hostname]: " new_value
201 if [ ! -z $new_value ]
207 if [ ! -z $developer_emails ]
209 read -p "Email address for admin account? [$developer_emails]: " new_value
210 if [ ! -z $new_value ]
212 developer_emails
=$new_value
216 if [ ! -z $smtp_address ]
218 read -p "SMTP server address? [$smtp_address]: " new_value
219 if [ ! -z $new_value ]
221 smtp_address
=$new_value
225 if [ ! -z $smtp_port ]
227 read -p "SMTP port? [$smtp_port]: " new_value
228 if [ ! -z $new_value ]
235 ## automatically set correct user name based on common mail providers
237 if [ "$smtp_address" == "smtp.sparkpostmail.com" ]
239 smtp_user_name
="SMTP_Injection"
241 if [ "$smtp_address" == "smtp.sendgrid.net" ]
243 smtp_user_name
="apikey"
245 if [ "$smtp_address" == "smtp.mailgun.org" ]
247 smtp_user_name
="postmaster@$hostname"
250 if [ ! -z $smtp_user_name ]
252 read -p "SMTP user name? [$smtp_user_name]: " new_value
253 if [ ! -z $new_value ]
255 smtp_user_name
=$new_value
259 read -p "SMTP password? [$smtp_password]: " new_value
260 if [ ! -z $new_value ]
262 smtp_password
=$new_value
265 if [ ! -z $letsencrypt_account_email ]
267 read -p "Let's Encrypt account email? ($letsencrypt_status) [$letsencrypt_account_email]: " new_value
268 if [ ! -z $new_value ]
270 letsencrypt_account_email
=$new_value
271 if [ "$new_value" == "off" ]
273 letsencrypt_status
="ENTER to skip"
275 letsencrypt_status
="Enter 'OFF' to disable."
280 echo -e "\nDoes this look right?\n"
281 echo "Hostname : $hostname"
282 echo "Email : $developer_emails"
283 echo "SMTP address : $smtp_address"
284 echo "SMTP port : $smtp_port"
285 echo "SMTP username : $smtp_user_name"
286 echo "SMTP password : $smtp_password"
288 if [ "$letsencrypt_status" == "Enter 'OFF' to disable." ]
290 echo "Let's Encrypt : $letsencrypt_account_email"
294 read -p "ENTER to continue, 'n' to try again, Ctrl+C to exit: " config_ok
297 sed -i -e "s/^ DISCOURSE_HOSTNAME:.*/ DISCOURSE_HOSTNAME: $hostname/w $changelog" $config_file
302 echo "DISCOURSE_HOSTNAME change failed."
306 sed -i -e "s/^ DISCOURSE_DEVELOPER_EMAILS:.*/ DISCOURSE_DEVELOPER_EMAILS: \'$developer_emails\'/w $changelog" $config_file
311 echo "DISCOURSE_DEVELOPER_EMAILS change failed."
315 sed -i -e "s/^ DISCOURSE_SMTP_ADDRESS:.*/ DISCOURSE_SMTP_ADDRESS: $smtp_address/w $changelog" $config_file
320 echo "DISCOURSE_SMTP_ADDRESS change failed."
324 sed -i -e "s/^ #DISCOURSE_SMTP_PORT:.*/ DISCOURSE_SMTP_PORT: $smtp_port/w $changelog" $config_file
329 echo "DISCOURSE_SMTP_PORT change failed."
333 sed -i -e "s/^ #DISCOURSE_SMTP_USER_NAME:.*/ DISCOURSE_SMTP_USER_NAME: $smtp_user_name/w $changelog" $config_file
338 echo "DISCOURSE_SMTP_USER_NAME change failed."
342 sed -i -e "s/^ #DISCOURSE_SMTP_PASSWORD:.*/ DISCOURSE_SMTP_PASSWORD: \"${smtp_password/\//\\/}\"/w $changelog" $config_file
347 echo "DISCOURSE_SMTP_PASSWORD change failed."
351 if [ "$letsencrypt_status" != "ENTER to skip" ]
353 sed -i -e "s/^ #LETSENCRYPT_ACCOUNT_EMAIL:.*/ LETSENCRYPT_ACCOUNT_EMAIL: $letsencrypt_account_email/w $changelog" $config_file
358 echo "LETSENCRYPT_ACCOUNT_EMAIL change failed."
361 local src
='^ #- "templates\/web.ssl.template.yml"'
362 local dst
=' \- "templates\/web.ssl.template.yml"'
363 sed -i -e "s/$src/$dst/w $changelog" $config_file
366 echo "web.ssl.template.yml enabled"
369 echo "web.ssl.template.yml NOT ENABLED--was it on already?"
371 local src
='^ #- "templates\/web.letsencrypt.ssl.template.yml"'
372 local dst
=' - "templates\/web.letsencrypt.ssl.template.yml"'
374 sed -i -e "s/$src/$dst/w $changelog" $config_file
377 echo "letsencrypt.ssl.template.yml enabled"
380 echo "letsencrypt.ssl.template.yml NOT ENABLED -- was it on already?"
384 if [ "$update_ok" == "y" ]
386 echo -e "\nConfiguration file at $config_file updated successfully!\n"
388 echo -e "\nUnfortunately, there was an error changing $config_file\n"
394 ## is our config file valid? Does it have the required fields set?
400 for x
in DISCOURSE_SMTP_ADDRESS DISCOURSE_SMTP_USER_NAME DISCOURSE_SMTP_PASSWORD \
401 DISCOURSE_DEVELOPER_EMAILS DISCOURSE_HOSTNAME
403 config_line
=`grep "^ $x:" $config_file`
405 local default
="example.com"
409 if [[ $config_line = *"$default"* ]]
411 echo "$x left at incorrect default of example.com"
414 config_val
=`echo $config_line | awk '{print $2}'`
415 if [ -z $config_val ]
417 echo "$x was left blank"
421 echo "$x not present"
426 if [ "$valid_config" != "y" ]; then
427 echo -e "\nSorry, these $config_file settings aren't valid -- can't continue!"
428 echo "If you have unusual requirements, edit $config_file and then: "
429 echo "./launcher bootstrap $app_name"
436 ## template file names
439 template_path
=samples
/standalone.yml
440 config_file
=containers
/$app_name.yml
441 changelog
=/tmp
/changelog
444 ## Check requirements before creating a copy of a config file we won't edit
447 check_and_install_docker
448 check_disk_and_memory
452 ## make a copy of the simple standalone config file
454 if [ -a $config_file ]
456 echo "The configuration file $config_file already exists!"
458 echo "If you want to delete your old configuration file and start over:"
459 echo "rm $config_file"
462 cp $template_path $config_file
470 ## if we reach this point without exiting, OK to proceed
472 .
/launcher bootstrap
$app_name && .
/launcher start
$app_name