Fix new docker_squash install
[discourse_docker.git] / discourse-setup
CommitLineData
c2d3ee4a
JA
1#!/bin/bash
2
ebdd72f3
JA
3##
4## Make sure only root can run our script
5##
6check_root() {
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
9 exit 1
10 fi
11}
12
18602189 13
c87c4b0a 14##
18602189
JP
15## Do we have docker?
16##
17check_and_install_docker () {
7cf781fc 18 docker_path=`which docker.io || which docker`
18602189
JP
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"
c87c4b0a 21 curl https://get.docker.com/ | sh
18602189 22 fi
7cf781fc 23 docker_path=`which docker.io || which docker`
18602189
JP
24 if [ -z $docker_path ]; then
25 echo Docker install failed. Quitting.
26 exit
27 fi
28}
29
69dcbef5
SG
30##
31## What are we running on
32##
33check_OS() {
34 echo `uname -s`
35}
36
e5ec8aa1
SG
37##
38## OS X available memory
39##
40check_osx_memory() {
41 echo `top -l 1 | awk '/PhysMem:/ {print $2}' | sed s/G//`
42}
43
44##
45## Linux available memory
46##
47check_linux_memory() {
48 echo `free -g --si | awk ' /Mem:/ {print $2} '`
49}
c87c4b0a 50
c2d3ee4a
JA
51##
52## Do we have enough memory and disk space for Discourse?
53##
54check_disk_and_memory() {
c87c4b0a 55
69dcbef5
SG
56 os_type=$(check_OS)
57 avail_mem=0
58 if [ $os_type == "Darwin" ]; then
e5ec8aa1 59 avail_mem=$(check_osx_memory)
69dcbef5 60 else
e5ec8aa1 61 avail_mem=$(check_linux_memory)
69dcbef5
SG
62 fi
63
c6374a12 64 if [ "$avail_mem" -lt 1 ]; then
51890305
JA
65 echo "WARNING: Discourse requires 1GB RAM to run. This system does not appear"
66 echo "to have sufficient memory."
c2d3ee4a 67 echo
51890305
JA
68 echo "Your site may not work properly, or future upgrades of Discourse may not"
69 echo "complete successfully."
c87c4b0a 70 exit 1
cdd99376 71 fi
c87c4b0a 72
f7bb85e6 73 if [ "$avail_mem" -le 2 ]; then
c6374a12
JP
74 total_swap=`free -g --si | awk ' /Swap:/ {print $2} '`
75 if [ "$total_swap" -lt 2 ]; then
bd7e6e26
JP
76 echo "WARNING: Discourse requires at least 2GB of swap when running with 2GB of RAM"
77 echo "or less. This system does not appear to have sufficient swap space."
c2d3ee4a 78 echo
8f70d450 79 echo "Without sufficient swap space, your site may not work properly, and future"
51890305 80 echo "upgrades of Discourse may not complete successfully."
c2d3ee4a 81 echo
ac1a2d67 82 read -p "ENTER to create a 2GB swapfile now, or Ctrl+C to exit"
c87c4b0a 83
8f70d450
JA
84 ##
85 ## derived from https://meta.discourse.org/t/13880
c87c4b0a 86 ##
8f70d450
JA
87 install -o root -g root -m 0600 /dev/null /swapfile
88 dd if=/dev/zero of=/swapfile bs=1k count=2048k
89 mkswap /swapfile
90 swapon /swapfile
7c2777f9 91 echo "/swapfile swap swap auto 0 0" | tee -a /etc/fstab
7802f679 92 sysctl -w vm.swappiness=10
7c2777f9 93 echo vm.swappiness = 10 | tee -a /etc/sysctl.conf
8f70d450 94
c6374a12
JP
95 total_swap=`free -g --si | awk ' /Swap:/ {print $2} '`
96 if [ "$total_swap" -lt 2 ]; then
8f70d450
JA
97 echo "Failed to create swap, sorry!"
98 exit 1
99 fi
c87c4b0a 100
c2d3ee4a
JA
101 fi
102 fi
103
c6374a12 104
c2d3ee4a
JA
105 free_disk="$(df /var | tail -n 1 | awk '{print $4}')"
106 if [ "$free_disk" -lt 5000 ]; then
51890305
JA
107 echo "WARNING: Discourse requires at least 5GB free disk space. This system"
108 echo "does not appear to have sufficient disk space."
c2d3ee4a 109 echo
51890305
JA
110 echo "Insufficient disk space may result in problems running your site, and"
111 echo "may not even allow Discourse installation to complete successfully."
c2d3ee4a
JA
112 echo
113 echo "Please free up some space, or expand your disk, before continuing."
114 echo
51890305
JA
115 echo "Run \`apt-get autoremove && apt-get autoclean\` to clean up unused"
116 echo "packages and \`./launcher cleanup\` to remove stale Docker containers."
c2d3ee4a
JA
117 exit 1
118 fi
119
c2d3ee4a
JA
120}
121
122
123##
124## If we have lots of RAM or lots of CPUs, bump up the defaults to scale better
125##
126scale_ram_and_cpu() {
127
642b870f 128 local changelog=/tmp/changelog.$PPID
c2d3ee4a 129 # grab info about total system ram and physical (NOT LOGICAL!) CPU cores
e5ec8aa1
SG
130 avail_gb=0
131 avail_cores=0
132 os_type=$(check_OS)
133 if [ $os_type == "Darwin" ]; then
134 avail_gb=$(check_osx_memory)
135 avail_cores=`sysctl hw.ncpu | awk '/hw.ncpu:/ {print $2}'`
136 else
137 avail_gb=$(check_linux_memory)
138 avail_cores=`cat /proc/cpuinfo | grep "cpu cores" | uniq | awk '{print $4}'`
139 fi
c2d3ee4a
JA
140 echo "Found ${avail_gb}GB of memory and $avail_cores physical CPU cores"
141
142 # db_shared_buffers: 128MB for 1GB, 256MB for 2GB, or 256MB * GB, max 4096MB
143 if [ "$avail_gb" -eq "1" ]
144 then
145 db_shared_buffers=128
146 else
147 if [ "$avail_gb" -eq "2" ]
148 then
149 db_shared_buffers=256
150 else
151 db_shared_buffers=$(( 256 * $avail_gb ))
152 fi
153 fi
154 db_shared_buffers=$(( db_shared_buffers < 4096 ? db_shared_buffers : 4096 ))
155
156 sed -i -e "s/^ #db_shared_buffers:.*/ db_shared_buffers: \"${db_shared_buffers}MB\"/w $changelog" $config_file
157 if [ -s $changelog ]
158 then
159 echo "setting db_shared_buffers = ${db_shared_buffers}MB"
160 rm $changelog
161 fi
162
c2d3ee4a
JA
163 # UNICORN_WORKERS: 2 * GB for 2GB or less, or 2 * CPU, max 8
164 if [ "$avail_gb" -le "2" ]
165 then
166 unicorn_workers=$(( 2 * $avail_gb ))
167 else
168 unicorn_workers=$(( 2 * $avail_cores ))
169 fi
170 unicorn_workers=$(( unicorn_workers < 8 ? unicorn_workers : 8 ))
171
172 sed -i -e "s/^ #UNICORN_WORKERS:.*/ UNICORN_WORKERS: ${unicorn_workers}/w $changelog" $config_file
173 if [ -s $changelog ]
174 then
175 echo "setting UNICORN_WORKERS = ${unicorn_workers}"
176 rm $changelog
177 fi
178
179}
180
181
c87c4b0a 182##
c2d3ee4a
JA
183## standard http / https ports must not be occupied
184##
185check_ports() {
186 check_port "80"
187 check_port "443"
188 echo "Ports 80 and 443 are free for use"
189}
190
191
192##
193## check a port to see if it is already in use
194##
195check_port() {
c87c4b0a 196
c2d3ee4a
JA
197 local valid=$(netstat -tln | awk '{print $4}' | grep ":${1}\$")
198
199 if [ -n "$valid" ]; then
200 echo "Port ${1} appears to already be in use."
201 echo
51890305
JA
202 echo "If you are trying to run Discourse simultaneously with another web"
203 echo "server like Apache or nginx, you will need to bind to a different port"
c87c4b0a 204 echo
51890305 205 echo "See https://meta.discourse.org/t/17247"
c2d3ee4a
JA
206 exit 1
207 fi
208}
209
210##
211## prompt user for typical Discourse config file values
212##
4b1b25e3 213ask_user_for_config() {
c87c4b0a 214
642b870f 215 local changelog=/tmp/changelog.$PPID
c2d3ee4a 216 local hostname="discourse.example.com"
642b870f 217 local developer_emails="me@example.com,you@example.com"
c2d3ee4a 218 local smtp_address="smtp.example.com"
7c2777f9 219 local smtp_port="587"
c87c4b0a 220 local smtp_user_name="postmaster@discourse.example.com"
c2d3ee4a
JA
221 local smtp_password=""
222 local letsencrypt_account_email="me@example.com"
223 local letsencrypt_status="ENTER to skip"
224
225 local new_value=""
226 local config_ok="n"
227 local update_ok="y"
c87c4b0a 228
c2d3ee4a
JA
229 echo ""
230
231 while [[ "$config_ok" == "n" ]]
232 do
233 if [ ! -z $hostname ]
234 then
235 read -p "Hostname for your Discourse? [$hostname]: " new_value
236 if [ ! -z $new_value ]
237 then
238 hostname=$new_value
239 fi
240 fi
c87c4b0a 241
c2d3ee4a
JA
242 if [ ! -z $developer_emails ]
243 then
244 read -p "Email address for admin account? [$developer_emails]: " new_value
245 if [ ! -z $new_value ]
246 then
247 developer_emails=$new_value
248 fi
249 fi
c87c4b0a 250
c2d3ee4a
JA
251 if [ ! -z $smtp_address ]
252 then
253 read -p "SMTP server address? [$smtp_address]: " new_value
254 if [ ! -z $new_value ]
255 then
256 smtp_address=$new_value
257 fi
258 fi
c87c4b0a 259
7c2777f9 260 if [ ! -z $smtp_port ]
c2d3ee4a 261 then
7c2777f9
JA
262 read -p "SMTP port? [$smtp_port]: " new_value
263 if [ ! -z $new_value ]
264 then
265 smtp_port=$new_value
266 fi
c2d3ee4a 267 fi
c87c4b0a 268
7c2777f9
JA
269 ##
270 ## automatically set correct user name based on common mail providers
271 ##
272 if [ "$smtp_address" == "smtp.sparkpostmail.com" ]
273 then
274 smtp_user_name="SMTP_Injection"
c87c4b0a 275 fi
c2d3ee4a
JA
276 if [ "$smtp_address" == "smtp.sendgrid.net" ]
277 then
278 smtp_user_name="apikey"
279 fi
7c2777f9
JA
280 if [ "$smtp_address" == "smtp.mailgun.org" ]
281 then
282 smtp_user_name="postmaster@$hostname"
283 fi
c87c4b0a 284
c2d3ee4a
JA
285 if [ ! -z $smtp_user_name ]
286 then
287 read -p "SMTP user name? [$smtp_user_name]: " new_value
288 if [ ! -z $new_value ]
289 then
290 smtp_user_name=$new_value
291 fi
292 fi
c87c4b0a 293
c2d3ee4a
JA
294 read -p "SMTP password? [$smtp_password]: " new_value
295 if [ ! -z $new_value ]
296 then
297 smtp_password=$new_value
298 fi
c87c4b0a 299
c2d3ee4a
JA
300 if [ ! -z $letsencrypt_account_email ]
301 then
302 read -p "Let's Encrypt account email? ($letsencrypt_status) [$letsencrypt_account_email]: " new_value
303 if [ ! -z $new_value ]
304 then
305 letsencrypt_account_email=$new_value
306 if [ "$new_value" == "off" ]
307 then
308 letsencrypt_status="ENTER to skip"
309 else
310 letsencrypt_status="Enter 'OFF' to disable."
311 fi
312 fi
313 fi
314
51890305 315 echo -e "\nDoes this look right?\n"
c2d3ee4a
JA
316 echo "Hostname : $hostname"
317 echo "Email : $developer_emails"
318 echo "SMTP address : $smtp_address"
7c2777f9 319 echo "SMTP port : $smtp_port"
c2d3ee4a
JA
320 echo "SMTP username : $smtp_user_name"
321 echo "SMTP password : $smtp_password"
c87c4b0a 322
c2d3ee4a
JA
323 if [ "$letsencrypt_status" == "Enter 'OFF' to disable." ]
324 then
325 echo "Let's Encrypt : $letsencrypt_account_email"
326 fi
c87c4b0a 327
c2d3ee4a 328 echo ""
ac1a2d67 329 read -p "ENTER to continue, 'n' to try again, Ctrl+C to exit: " config_ok
c2d3ee4a
JA
330 done
331
013b5931 332 sed -i -e "s/^ DISCOURSE_HOSTNAME:.*/ DISCOURSE_HOSTNAME: $hostname/w $changelog" $config_file
c2d3ee4a
JA
333 if [ -s $changelog ]
334 then
335 rm $changelog
336 else
337 echo "DISCOURSE_HOSTNAME change failed."
338 update_ok="n"
339 fi
340
341 sed -i -e "s/^ DISCOURSE_DEVELOPER_EMAILS:.*/ DISCOURSE_DEVELOPER_EMAILS: \'$developer_emails\'/w $changelog" $config_file
342 if [ -s $changelog ]
343 then
344 rm $changelog
345 else
346 echo "DISCOURSE_DEVELOPER_EMAILS change failed."
347 update_ok="n"
348 fi
349
013b5931 350 sed -i -e "s/^ DISCOURSE_SMTP_ADDRESS:.*/ DISCOURSE_SMTP_ADDRESS: $smtp_address/w $changelog" $config_file
c2d3ee4a
JA
351 if [ -s $changelog ]
352 then
353 rm $changelog
354 else
355 echo "DISCOURSE_SMTP_ADDRESS change failed."
356 update_ok="n"
357 fi
358
7c2777f9
JA
359 sed -i -e "s/^ #DISCOURSE_SMTP_PORT:.*/ DISCOURSE_SMTP_PORT: $smtp_port/w $changelog" $config_file
360 if [ -s $changelog ]
361 then
362 rm $changelog
363 else
364 echo "DISCOURSE_SMTP_PORT change failed."
365 update_ok="n"
366 fi
367
013b5931 368 sed -i -e "s/^ #DISCOURSE_SMTP_USER_NAME:.*/ DISCOURSE_SMTP_USER_NAME: $smtp_user_name/w $changelog" $config_file
c2d3ee4a
JA
369 if [ -s $changelog ]
370 then
371 rm $changelog
372 else
373 echo "DISCOURSE_SMTP_USER_NAME change failed."
374 update_ok="n"
375 fi
376
63b6095f 377 sed -i -e "s/^ #DISCOURSE_SMTP_PASSWORD:.*/ DISCOURSE_SMTP_PASSWORD: \"${smtp_password/\//\\/}\"/w $changelog" $config_file
c2d3ee4a
JA
378 if [ -s $changelog ]
379 then
380 rm $changelog
381 else
382 echo "DISCOURSE_SMTP_PASSWORD change failed."
383 update_ok="n"
384 fi
385
386 if [ "$letsencrypt_status" != "ENTER to skip" ]
387 then
642b870f 388 sed -i -e "s/^ #LETSENCRYPT_ACCOUNT_EMAIL:.*/ LETSENCRYPT_ACCOUNT_EMAIL: $letsencrypt_account_email/w $changelog" $config_file
c2d3ee4a
JA
389 if [ -s $changelog ]
390 then
391 rm $changelog
392 else
393 echo "LETSENCRYPT_ACCOUNT_EMAIL change failed."
394 update_ok="n"
395 fi
396 local src='^ #- "templates\/web.ssl.template.yml"'
397 local dst=' \- "templates\/web.ssl.template.yml"'
398 sed -i -e "s/$src/$dst/w $changelog" $config_file
399 if [ -s $changelog ]
400 then
642b870f 401 echo "web.ssl.template.yml enabled"
c2d3ee4a
JA
402 else
403 update_ok="n"
404 echo "web.ssl.template.yml NOT ENABLED--was it on already?"
405 fi
406 local src='^ #- "templates\/web.letsencrypt.ssl.template.yml"'
407 local dst=' - "templates\/web.letsencrypt.ssl.template.yml"'
408
409 sed -i -e "s/$src/$dst/w $changelog" $config_file
410 if [ -s $changelog ]
411 then
412 echo "letsencrypt.ssl.template.yml enabled"
413 else
414 update_ok="n"
415 echo "letsencrypt.ssl.template.yml NOT ENABLED -- was it on already?"
416 fi
c87c4b0a 417 fi
c2d3ee4a
JA
418
419 if [ "$update_ok" == "y" ]
420 then
421 echo -e "\nConfiguration file at $config_file updated successfully!\n"
422 else
423 echo -e "\nUnfortunately, there was an error changing $config_file\n"
424 exit 1
425 fi
426}
427
428##
429## is our config file valid? Does it have the required fields set?
430##
4b1b25e3 431validate_config() {
c2d3ee4a
JA
432
433 valid_config="y"
c87c4b0a 434
c2d3ee4a
JA
435 for x in DISCOURSE_SMTP_ADDRESS DISCOURSE_SMTP_USER_NAME DISCOURSE_SMTP_PASSWORD \
436 DISCOURSE_DEVELOPER_EMAILS DISCOURSE_HOSTNAME
437 do
c87c4b0a 438 config_line=`grep "^ $x:" $config_file`
c2d3ee4a
JA
439 local result=$?
440 local default="example.com"
441
442 if (( result == 0 ))
443 then
444 if [[ $config_line = *"$default"* ]]
445 then
446 echo "$x left at incorrect default of example.com"
447 valid_config="n"
448 fi
449 config_val=`echo $config_line | awk '{print $2}'`
450 if [ -z $config_val ]
451 then
452 echo "$x was left blank"
453 valid_config="n"
454 fi
455 else
456 echo "$x not present"
457 valid_config="n"
458 fi
459 done
c87c4b0a 460
c2d3ee4a
JA
461 if [ "$valid_config" != "y" ]; then
462 echo -e "\nSorry, these $config_file settings aren't valid -- can't continue!"
d8613c71
JA
463 echo "If you have unusual requirements, edit $config_file and then: "
464 echo "./launcher bootstrap $app_name"
c2d3ee4a
JA
465 exit 1
466 fi
467}
468
469
470##
471## template file names
472##
473app_name=app
474template_path=samples/standalone.yml
475config_file=containers/$app_name.yml
476changelog=/tmp/changelog
477
4b1b25e3
JA
478##
479## Check requirements before creating a copy of a config file we won't edit
480##
ebdd72f3 481check_root
18602189 482check_and_install_docker
642b870f
JP
483check_disk_and_memory
484check_ports
485
4b1b25e3 486##
c2d3ee4a 487## make a copy of the simple standalone config file
4b1b25e3 488##
c2d3ee4a
JA
489if [ -a $config_file ]
490then
491 echo "The configuration file $config_file already exists!"
492 echo ""
493 echo "If you want to delete your old configuration file and start over:"
494 echo "rm $config_file"
495 exit 1
496else
497 cp $template_path $config_file
498fi
499
c2d3ee4a 500scale_ram_and_cpu
4b1b25e3
JA
501ask_user_for_config
502validate_config
c2d3ee4a 503
4b1b25e3
JA
504##
505## if we reach this point without exiting, OK to proceed
506##
02fd0d94 507./launcher bootstrap $app_name && ./launcher start $app_name