4 ## Do we have enough memory and disk space for Discourse?
6 check_disk_and_memory
() {
9 avail_mem
="$(LANG=C free -m | grep '^Mem:' | awk '{print $2}')"
10 if [ "$avail_mem" -lt 900 ]; then
11 resources
="insufficient"
12 echo "WARNING: Discourse requires 1GB RAM to run. This system does not appear"
13 echo "to have sufficient memory."
15 echo "Your site may not work properly, or future upgrades of Discourse may not"
16 echo "complete successfully."
17 elif [ "$avail_mem" -lt 1800 ]; then
18 total_swap
="$(LANG=C free -m | grep ^Swap: | awk '{print $2}')"
19 if [ "$total_swap" -lt 1000 ]; then
20 resources
="insufficient"
21 echo "WARNING: Discourse requires at least 1GB of swap when running with less "
22 echo "than 2GB of RAM. This system does not appear to have sufficient swap space."
24 echo "Without sufficient swap space, your site may not work properly, and future"
25 echo "upgrades of Discourse may not complete successfully."
27 read -p "Press ENTER to create a 2GB swapfile automatically, or Ctrl-C to exit"
30 ## derived from https://meta.discourse.org/t/13880
32 install -o root
-g root
-m 0600 /dev
/null
/swapfile
33 dd if=/dev
/zero of
=/swapfile bs
=1k count
=2048k
36 echo "/swapfile swap swap auto 0 0" | sudo
tee -a /etc
/fstab
37 sudo sysctl
-w vm.swappiness
=10
38 echo vm.swappiness
= 10 | sudo
tee -a /etc
/sysctl.conf
40 total_swap
="$(LANG=C free -m | grep ^Swap: | awk '{print $2}')"
41 if [ "$total_swap" -lt 1000 ]; then
42 echo "Failed to create swap, sorry!"
49 free_disk
="$(df /var | tail -n 1 | awk '{print $4}')"
50 if [ "$free_disk" -lt 5000 ]; then
51 resources
="insufficient"
52 echo "WARNING: Discourse requires at least 5GB free disk space. This system"
53 echo "does not appear to have sufficient disk space."
55 echo "Insufficient disk space may result in problems running your site, and"
56 echo "may not even allow Discourse installation to complete successfully."
58 echo "Please free up some space, or expand your disk, before continuing."
60 echo "Run \`apt-get autoremove && apt-get autoclean\` to clean up unused"
61 echo "packages and \`./launcher cleanup\` to remove stale Docker containers."
65 if [ -t 0 ] && [ "$resources" != "ok" ]; then
67 read -p "Press ENTER to continue, or Ctrl-C to exit and give your system more resources"
73 ## If we have lots of RAM or lots of CPUs, bump up the defaults to scale better
77 local changelog
=/tmp
/changelog.
$PPID
78 # grab info about total system ram and physical (NOT LOGICAL!) CPU cores
79 avail_mem
="$(LANG=C free -m | grep '^Mem:' | awk '{print $2}')"
80 avail_gb
=$
(( $avail_mem / 950 ))
81 avail_cores
=`cat /proc/cpuinfo | grep "cpu cores" | uniq | awk '{print $4}'`
82 echo "Found ${avail_gb}GB of memory and $avail_cores physical CPU cores"
84 # db_shared_buffers: 128MB for 1GB, 256MB for 2GB, or 256MB * GB, max 4096MB
85 if [ "$avail_gb" -eq "1" ]
89 if [ "$avail_gb" -eq "2" ]
93 db_shared_buffers
=$
(( 256 * $avail_gb ))
96 db_shared_buffers
=$
(( db_shared_buffers
< 4096 ? db_shared_buffers
: 4096 ))
98 sed -i -e "s/^ #db_shared_buffers:.*/ db_shared_buffers: \"${db_shared_buffers}MB\"/w $changelog" $config_file
101 echo "setting db_shared_buffers = ${db_shared_buffers}MB"
105 # UNICORN_WORKERS: 2 * GB for 2GB or less, or 2 * CPU, max 8
106 if [ "$avail_gb" -le "2" ]
108 unicorn_workers
=$
(( 2 * $avail_gb ))
110 unicorn_workers
=$
(( 2 * $avail_cores ))
112 unicorn_workers
=$
(( unicorn_workers
< 8 ? unicorn_workers
: 8 ))
114 sed -i -e "s/^ #UNICORN_WORKERS:.*/ UNICORN_WORKERS: ${unicorn_workers}/w $changelog" $config_file
117 echo "setting UNICORN_WORKERS = ${unicorn_workers}"
125 ## standard http / https ports must not be occupied
130 echo "Ports 80 and 443 are free for use"
135 ## check a port to see if it is already in use
139 local valid
=$
(netstat
-tln |
awk '{print $4}' |
grep ":${1}\$")
141 if [ -n "$valid" ]; then
142 echo "Port ${1} appears to already be in use."
144 echo "If you are trying to run Discourse simultaneously with another web"
145 echo "server like Apache or nginx, you will need to bind to a different port"
147 echo "See https://meta.discourse.org/t/17247"
153 ## prompt user for typical Discourse config file values
155 ask_user_for_config
() {
157 local changelog
=/tmp
/changelog.
$PPID
158 local hostname
="discourse.example.com"
159 local developer_emails
="me@example.com,you@example.com"
160 local smtp_address
="smtp.example.com"
161 local smtp_user_name
="postmaster@discourse.example.com"
162 local smtp_password
=""
163 local letsencrypt_account_email
="me@example.com"
164 local letsencrypt_status
="ENTER to skip"
172 while [[ "$config_ok" == "n" ]]
174 if [ ! -z $hostname ]
176 read -p "Hostname for your Discourse? [$hostname]: " new_value
177 if [ ! -z $new_value ]
183 if [ ! -z $developer_emails ]
185 read -p "Email address for admin account? [$developer_emails]: " new_value
186 if [ ! -z $new_value ]
188 developer_emails
=$new_value
192 if [ ! -z $smtp_address ]
194 read -p "SMTP server address? [$smtp_address]: " new_value
195 if [ ! -z $new_value ]
197 smtp_address
=$new_value
201 if [ "$smtp_address" == "smtp.sparkpostmail.com" ]
203 smtp_user_name
="SMTP_Injection"
206 if [ "$smtp_address" == "smtp.sendgrid.net" ]
208 smtp_user_name
="apikey"
211 if [ ! -z $smtp_user_name ]
213 read -p "SMTP user name? [$smtp_user_name]: " new_value
214 if [ ! -z $new_value ]
216 smtp_user_name
=$new_value
220 read -p "SMTP password? [$smtp_password]: " new_value
221 if [ ! -z $new_value ]
223 smtp_password
=$new_value
226 if [ ! -z $letsencrypt_account_email ]
228 read -p "Let's Encrypt account email? ($letsencrypt_status) [$letsencrypt_account_email]: " new_value
229 if [ ! -z $new_value ]
231 letsencrypt_account_email
=$new_value
232 if [ "$new_value" == "off" ]
234 letsencrypt_status
="ENTER to skip"
236 letsencrypt_status
="Enter 'OFF' to disable."
241 echo -e "\nDoes this look right?\n"
242 echo "Hostname : $hostname"
243 echo "Email : $developer_emails"
244 echo "SMTP address : $smtp_address"
245 echo "SMTP username : $smtp_user_name"
246 echo "SMTP password : $smtp_password"
248 if [ "$letsencrypt_status" == "Enter 'OFF' to disable." ]
250 echo "Let's Encrypt : $letsencrypt_account_email"
254 read -p "Press ENTER to continue, 'n' to try again, or ^C to exit: " config_ok
257 sed -i -e "s/^ DISCOURSE_HOSTNAME:.*/ DISCOURSE_HOSTNAME: $hostname/w $changelog" $config_file
262 echo "DISCOURSE_HOSTNAME change failed."
266 sed -i -e "s/^ DISCOURSE_DEVELOPER_EMAILS:.*/ DISCOURSE_DEVELOPER_EMAILS: \'$developer_emails\'/w $changelog" $config_file
271 echo "DISCOURSE_DEVELOPER_EMAILS change failed."
275 sed -i -e "s/^ DISCOURSE_SMTP_ADDRESS:.*/ DISCOURSE_SMTP_ADDRESS: $smtp_address/w $changelog" $config_file
280 echo "DISCOURSE_SMTP_ADDRESS change failed."
284 sed -i -e "s/^ #DISCOURSE_SMTP_USER_NAME:.*/ DISCOURSE_SMTP_USER_NAME: $smtp_user_name/w $changelog" $config_file
289 echo "DISCOURSE_SMTP_USER_NAME change failed."
293 sed -i -e "s/^ #DISCOURSE_SMTP_PASSWORD:.*/ DISCOURSE_SMTP_PASSWORD: $smtp_password/w $changelog" $config_file
298 echo "DISCOURSE_SMTP_PASSWORD change failed."
302 if [ "$letsencrypt_status" != "ENTER to skip" ]
304 sed -i -e "s/^ #LETSENCRYPT_ACCOUNT_EMAIL:.*/ LETSENCRYPT_ACCOUNT_EMAIL: $letsencrypt_account_email/w $changelog" $config_file
309 echo "LETSENCRYPT_ACCOUNT_EMAIL change failed."
312 local src
='^ #- "templates\/web.ssl.template.yml"'
313 local dst
=' \- "templates\/web.ssl.template.yml"'
314 sed -i -e "s/$src/$dst/w $changelog" $config_file
317 echo "web.ssl.template.yml enabled"
320 echo "web.ssl.template.yml NOT ENABLED--was it on already?"
322 local src
='^ #- "templates\/web.letsencrypt.ssl.template.yml"'
323 local dst
=' - "templates\/web.letsencrypt.ssl.template.yml"'
325 sed -i -e "s/$src/$dst/w $changelog" $config_file
328 echo "letsencrypt.ssl.template.yml enabled"
331 echo "letsencrypt.ssl.template.yml NOT ENABLED -- was it on already?"
335 if [ "$update_ok" == "y" ]
337 echo -e "\nConfiguration file at $config_file updated successfully!\n"
339 echo -e "\nUnfortunately, there was an error changing $config_file\n"
345 ## is our config file valid? Does it have the required fields set?
351 for x
in DISCOURSE_SMTP_ADDRESS DISCOURSE_SMTP_USER_NAME DISCOURSE_SMTP_PASSWORD \
352 DISCOURSE_DEVELOPER_EMAILS DISCOURSE_HOSTNAME
354 config_line
=`grep "^ $x:" $config_file`
356 local default
="example.com"
360 if [[ $config_line = *"$default"* ]]
362 echo "$x left at incorrect default of example.com"
365 config_val
=`echo $config_line | awk '{print $2}'`
366 if [ -z $config_val ]
368 echo "$x was left blank"
372 echo "$x not present"
377 if [ "$valid_config" != "y" ]; then
378 echo -e "\nSorry, these $config_file settings aren't valid -- can't continue!"
385 ## template file names
388 template_path
=samples
/standalone.yml
389 config_file
=containers
/$app_name.yml
390 changelog
=/tmp
/changelog
393 ## Check requirements before creating a copy of a config file we won't edit
395 check_disk_and_memory
399 ## make a copy of the simple standalone config file
401 if [ -a $config_file ]
403 echo "The configuration file $config_file already exists!"
405 echo "If you want to delete your old configuration file and start over:"
406 echo "rm $config_file"
409 cp $template_path $config_file
417 ## if we reach this point without exiting, OK to proceed
419 .
/launcher bootstrap
$app_name
420 .
/launcher start
$app_name