FEATURE: Add default Referrer Policy in SSL template
[discourse_docker.git] / discourse-setup
CommitLineData
f17af951 1#!/usr/bin/env bash
c2d3ee4a 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
07f3b11e
JP
14##
15## Does the current IP match the domain name?
16##
17check_IP_match () {
18 echo
19 echo Checking your domain name . . .
20 sleep 1
21 local IFACE=none
22 local IFCONFIG=`which ifconfig`
23 /sbin/route |grep default > /tmp/route$PPID
24
25 if grep default /tmp/route$PPID > /dev/null
26 then
27 local IFACE=`cut -c 73-100 /tmp/route$PPID |head -1`
28 else
29 echo WARNING: Cannot check your IP number.
30 fi
31 local IP=`$IFCONFIG $IFACE|grep "inet addr:" |cut -d":" -f 2|cut -d" " -f1|head -1`
32 local RESOLVED_IP=`dig +short $1`
33
34 IP_LOOKS_GOOD=0
35 if [[ ! -z $RESOLVED_IP ]]
36 then
17f62d87 37 if [ "$IP" == "$RESOLVED_IP" ]
07f3b11e
JP
38 then
39 echo $1 resolves to $IP. Looks good!
40 echo
41 local IP_LOOKS_GOOD=1
42 fi
43 fi
44 if [ $IP_LOOKS_GOOD == 0 ]
45 then
46 echo "-----------------------------------------"
17f62d87
JP
47 echo WARNING:: $1 does not appear to resolve to $IP.
48 echo ""
49 echo LET\'S ENCRYPT cannot work if their servers cannot access your host by name.
50 echo Unless you think you know why this naive check failed, DO NOT USE Let\'s Encrypt.
51 echo "(A typical reason for failure is an AWS server with an elastic IP.)"
07f3b11e 52 echo
17f62d87 53 echo You should probably answer \"n\" at the next prompt and disable Let\'s Encrypt.
07f3b11e
JP
54 echo "-----------------------------------------"
55 fi
56 sleep 1
57}
58
c87c4b0a 59##
18602189
JP
60## Do we have docker?
61##
62check_and_install_docker () {
7cf781fc 63 docker_path=`which docker.io || which docker`
18602189
JP
64 if [ -z $docker_path ]; then
65 read -p "Docker not installed. Enter to install from https://get.docker.com/ or Ctrl+C to exit"
c87c4b0a 66 curl https://get.docker.com/ | sh
18602189 67 fi
7cf781fc 68 docker_path=`which docker.io || which docker`
18602189
JP
69 if [ -z $docker_path ]; then
70 echo Docker install failed. Quitting.
71 exit
72 fi
73}
74
69dcbef5
SG
75##
76## What are we running on
77##
78check_OS() {
79 echo `uname -s`
80}
81
e5ec8aa1
SG
82##
83## OS X available memory
84##
85check_osx_memory() {
86 echo `top -l 1 | awk '/PhysMem:/ {print $2}' | sed s/G//`
87}
88
89##
90## Linux available memory
91##
92check_linux_memory() {
93 echo `free -g --si | awk ' /Mem:/ {print $2} '`
94}
c87c4b0a 95
c2d3ee4a
JA
96##
97## Do we have enough memory and disk space for Discourse?
98##
99check_disk_and_memory() {
c87c4b0a 100
69dcbef5
SG
101 os_type=$(check_OS)
102 avail_mem=0
17f62d87 103 if [ "$os_type" == "Darwin" ]; then
e5ec8aa1 104 avail_mem=$(check_osx_memory)
69dcbef5 105 else
e5ec8aa1 106 avail_mem=$(check_linux_memory)
69dcbef5
SG
107 fi
108
c6374a12 109 if [ "$avail_mem" -lt 1 ]; then
51890305
JA
110 echo "WARNING: Discourse requires 1GB RAM to run. This system does not appear"
111 echo "to have sufficient memory."
c2d3ee4a 112 echo
51890305
JA
113 echo "Your site may not work properly, or future upgrades of Discourse may not"
114 echo "complete successfully."
c87c4b0a 115 exit 1
cdd99376 116 fi
c87c4b0a 117
f7bb85e6 118 if [ "$avail_mem" -le 2 ]; then
c6374a12
JP
119 total_swap=`free -g --si | awk ' /Swap:/ {print $2} '`
120 if [ "$total_swap" -lt 2 ]; then
bd7e6e26
JP
121 echo "WARNING: Discourse requires at least 2GB of swap when running with 2GB of RAM"
122 echo "or less. This system does not appear to have sufficient swap space."
c2d3ee4a 123 echo
8f70d450 124 echo "Without sufficient swap space, your site may not work properly, and future"
51890305 125 echo "upgrades of Discourse may not complete successfully."
c2d3ee4a 126 echo
ac1a2d67 127 read -p "ENTER to create a 2GB swapfile now, or Ctrl+C to exit"
c87c4b0a 128
8f70d450
JA
129 ##
130 ## derived from https://meta.discourse.org/t/13880
c87c4b0a 131 ##
8f70d450
JA
132 install -o root -g root -m 0600 /dev/null /swapfile
133 dd if=/dev/zero of=/swapfile bs=1k count=2048k
134 mkswap /swapfile
135 swapon /swapfile
7c2777f9 136 echo "/swapfile swap swap auto 0 0" | tee -a /etc/fstab
7802f679 137 sysctl -w vm.swappiness=10
7c2777f9 138 echo vm.swappiness = 10 | tee -a /etc/sysctl.conf
8f70d450 139
c6374a12
JP
140 total_swap=`free -g --si | awk ' /Swap:/ {print $2} '`
141 if [ "$total_swap" -lt 2 ]; then
8f70d450
JA
142 echo "Failed to create swap, sorry!"
143 exit 1
144 fi
c87c4b0a 145
c2d3ee4a
JA
146 fi
147 fi
148
c6374a12 149
c2d3ee4a
JA
150 free_disk="$(df /var | tail -n 1 | awk '{print $4}')"
151 if [ "$free_disk" -lt 5000 ]; then
51890305
JA
152 echo "WARNING: Discourse requires at least 5GB free disk space. This system"
153 echo "does not appear to have sufficient disk space."
c2d3ee4a 154 echo
51890305
JA
155 echo "Insufficient disk space may result in problems running your site, and"
156 echo "may not even allow Discourse installation to complete successfully."
c2d3ee4a
JA
157 echo
158 echo "Please free up some space, or expand your disk, before continuing."
159 echo
51890305
JA
160 echo "Run \`apt-get autoremove && apt-get autoclean\` to clean up unused"
161 echo "packages and \`./launcher cleanup\` to remove stale Docker containers."
c2d3ee4a
JA
162 exit 1
163 fi
164
c2d3ee4a
JA
165}
166
167
168##
169## If we have lots of RAM or lots of CPUs, bump up the defaults to scale better
170##
171scale_ram_and_cpu() {
172
642b870f 173 local changelog=/tmp/changelog.$PPID
c2d3ee4a 174 # grab info about total system ram and physical (NOT LOGICAL!) CPU cores
e5ec8aa1
SG
175 avail_gb=0
176 avail_cores=0
177 os_type=$(check_OS)
17f62d87 178 if [ "$os_type" == "Darwin" ]; then
e5ec8aa1
SG
179 avail_gb=$(check_osx_memory)
180 avail_cores=`sysctl hw.ncpu | awk '/hw.ncpu:/ {print $2}'`
181 else
96568673
TH
182 avail_gb=$(check_linux_memory)
183 avail_cores=$((`awk '/cpu cores/ {print $4;exit}' /proc/cpuinfo`*`sort /proc/cpuinfo | uniq | grep -c "physical id"`))
e5ec8aa1 184 fi
c2d3ee4a
JA
185 echo "Found ${avail_gb}GB of memory and $avail_cores physical CPU cores"
186
187 # db_shared_buffers: 128MB for 1GB, 256MB for 2GB, or 256MB * GB, max 4096MB
188 if [ "$avail_gb" -eq "1" ]
189 then
190 db_shared_buffers=128
191 else
192 if [ "$avail_gb" -eq "2" ]
193 then
194 db_shared_buffers=256
195 else
196 db_shared_buffers=$(( 256 * $avail_gb ))
197 fi
198 fi
199 db_shared_buffers=$(( db_shared_buffers < 4096 ? db_shared_buffers : 4096 ))
200
f17af951 201 sed -i -e "s/^ #\?db_shared_buffers:.*/ db_shared_buffers: \"${db_shared_buffers}MB\"/w $changelog" $config_file
c2d3ee4a
JA
202 if [ -s $changelog ]
203 then
204 echo "setting db_shared_buffers = ${db_shared_buffers}MB"
205 rm $changelog
206 fi
207
c2d3ee4a
JA
208 # UNICORN_WORKERS: 2 * GB for 2GB or less, or 2 * CPU, max 8
209 if [ "$avail_gb" -le "2" ]
210 then
211 unicorn_workers=$(( 2 * $avail_gb ))
212 else
213 unicorn_workers=$(( 2 * $avail_cores ))
214 fi
215 unicorn_workers=$(( unicorn_workers < 8 ? unicorn_workers : 8 ))
216
f17af951 217 sed -i -e "s/^ #\?UNICORN_WORKERS:.*/ UNICORN_WORKERS: ${unicorn_workers}/w $changelog" $config_file
c2d3ee4a
JA
218 if [ -s $changelog ]
219 then
220 echo "setting UNICORN_WORKERS = ${unicorn_workers}"
221 rm $changelog
222 fi
223
224}
225
226
c87c4b0a 227##
c2d3ee4a
JA
228## standard http / https ports must not be occupied
229##
230check_ports() {
231 check_port "80"
232 check_port "443"
233 echo "Ports 80 and 443 are free for use"
234}
235
236
237##
238## check a port to see if it is already in use
239##
240check_port() {
c87c4b0a 241
c2d3ee4a
JA
242 local valid=$(netstat -tln | awk '{print $4}' | grep ":${1}\$")
243
244 if [ -n "$valid" ]; then
245 echo "Port ${1} appears to already be in use."
246 echo
51890305
JA
247 echo "If you are trying to run Discourse simultaneously with another web"
248 echo "server like Apache or nginx, you will need to bind to a different port"
c87c4b0a 249 echo
51890305 250 echo "See https://meta.discourse.org/t/17247"
f17af951
JP
251 echo
252 echo "If you are reconfiguring an already-configured Discourse, use "
253 echo
254 echo "./launcher stop app"
255 echo
256 echo "to stop Discourse before you reconfigure it and try again."
c2d3ee4a
JA
257 exit 1
258 fi
259}
260
f17af951
JP
261##
262## read a variable from the config file
263##
264read_config() {
265
266 config_line=`egrep "^ #?$1:" $config_file`
267 read_config_result=`echo $config_line | awk '{print $2}'`
268 read_config_result=`echo $read_config_result | sed "s/^\([\"']\)\(.*\)\1\$/\2/g"`
269}
270
271
272
c2d3ee4a
JA
273##
274## prompt user for typical Discourse config file values
275##
4b1b25e3 276ask_user_for_config() {
c87c4b0a 277
f17af951
JP
278 # NOTE: Defaults now come from standalone.yml
279
642b870f 280 local changelog=/tmp/changelog.$PPID
f17af951
JP
281 read_config "DISCOURSE_SMTP_ADDRESS"
282 local smtp_address=$read_config_result
283 # NOTE: if there are spaces between emails, this breaks, but a human should be paying attention
284 read_config "DISCOURSE_DEVELOPER_EMAILS"
285 local developer_emails=$read_config_result
286 read_config "DISCOURSE_SMTP_PASSWORD"
287 local smtp_password=$read_config_result
288 read_config "DISCOURSE_SMTP_PORT"
289 local smtp_port=$read_config_result
290 read_config "DISCOURSE_SMTP_USER_NAME"
291 local smtp_user_name=$read_config_result
292 if [ "$smtp_password" = "pa$$word" ]
293 then
294 smtp_password = ""
295 fi
296 read_config "LETSENCRYPT_ACCOUNT_EMAIL"
297 local letsencrypt_account_email=$read_config_result
17f62d87
JP
298 if [ -z $letsencrypt_account_email ]
299 then
300 letsencrypt_account_email="me@example.com"
301 fi
302 if [ "$letsencrypt_account_email" = "me@example.com" ]
f17af951
JP
303 then
304 local letsencrypt_status="ENTER to skip"
305 else
306 local letsencrypt_status="Enter 'OFF' to disable."
307 fi
308
309 read_config "DISCOURSE_HOSTNAME"
310 hostname=$read_config_result
c2d3ee4a
JA
311
312 local new_value=""
313 local config_ok="n"
314 local update_ok="y"
c87c4b0a 315
c2d3ee4a
JA
316 echo ""
317
318 while [[ "$config_ok" == "n" ]]
319 do
320 if [ ! -z $hostname ]
321 then
322 read -p "Hostname for your Discourse? [$hostname]: " new_value
323 if [ ! -z $new_value ]
324 then
325 hostname=$new_value
326 fi
327 fi
c87c4b0a 328
c2d3ee4a
JA
329 if [ ! -z $developer_emails ]
330 then
f17af951 331 read -p "Email address for admin account(s)? [$developer_emails]: " new_value
c2d3ee4a
JA
332 if [ ! -z $new_value ]
333 then
334 developer_emails=$new_value
335 fi
336 fi
c87c4b0a 337
c2d3ee4a
JA
338 if [ ! -z $smtp_address ]
339 then
340 read -p "SMTP server address? [$smtp_address]: " new_value
341 if [ ! -z $new_value ]
342 then
343 smtp_address=$new_value
344 fi
345 fi
c87c4b0a 346
7c2777f9 347 if [ ! -z $smtp_port ]
c2d3ee4a 348 then
7c2777f9
JA
349 read -p "SMTP port? [$smtp_port]: " new_value
350 if [ ! -z $new_value ]
351 then
352 smtp_port=$new_value
353 fi
c2d3ee4a 354 fi
c87c4b0a 355
7c2777f9
JA
356 ##
357 ## automatically set correct user name based on common mail providers
358 ##
359 if [ "$smtp_address" == "smtp.sparkpostmail.com" ]
360 then
361 smtp_user_name="SMTP_Injection"
c87c4b0a 362 fi
c2d3ee4a
JA
363 if [ "$smtp_address" == "smtp.sendgrid.net" ]
364 then
365 smtp_user_name="apikey"
366 fi
7c2777f9
JA
367 if [ "$smtp_address" == "smtp.mailgun.org" ]
368 then
369 smtp_user_name="postmaster@$hostname"
370 fi
c87c4b0a 371
c2d3ee4a
JA
372 if [ ! -z $smtp_user_name ]
373 then
374 read -p "SMTP user name? [$smtp_user_name]: " new_value
375 if [ ! -z $new_value ]
376 then
377 smtp_user_name=$new_value
378 fi
379 fi
c87c4b0a 380
c2d3ee4a
JA
381 read -p "SMTP password? [$smtp_password]: " new_value
382 if [ ! -z $new_value ]
383 then
384 smtp_password=$new_value
385 fi
c87c4b0a 386
c2d3ee4a
JA
387 if [ ! -z $letsencrypt_account_email ]
388 then
389 read -p "Let's Encrypt account email? ($letsencrypt_status) [$letsencrypt_account_email]: " new_value
390 if [ ! -z $new_value ]
391 then
392 letsencrypt_account_email=$new_value
f17af951 393 if [ "${new_value,,}" = "off" ]
c2d3ee4a
JA
394 then
395 letsencrypt_status="ENTER to skip"
396 else
397 letsencrypt_status="Enter 'OFF' to disable."
398 fi
399 fi
400 fi
401
07f3b11e
JP
402 if [ "$letsencrypt_status" == "Enter 'OFF' to disable." ]
403 then
404 check_IP_match $hostname
405 fi
406
51890305 407 echo -e "\nDoes this look right?\n"
c2d3ee4a
JA
408 echo "Hostname : $hostname"
409 echo "Email : $developer_emails"
410 echo "SMTP address : $smtp_address"
7c2777f9 411 echo "SMTP port : $smtp_port"
c2d3ee4a
JA
412 echo "SMTP username : $smtp_user_name"
413 echo "SMTP password : $smtp_password"
c87c4b0a 414
c2d3ee4a
JA
415 if [ "$letsencrypt_status" == "Enter 'OFF' to disable." ]
416 then
417 echo "Let's Encrypt : $letsencrypt_account_email"
418 fi
c87c4b0a 419
07f3b11e 420
c2d3ee4a 421 echo ""
ac1a2d67 422 read -p "ENTER to continue, 'n' to try again, Ctrl+C to exit: " config_ok
c2d3ee4a
JA
423 done
424
013b5931 425 sed -i -e "s/^ DISCOURSE_HOSTNAME:.*/ DISCOURSE_HOSTNAME: $hostname/w $changelog" $config_file
c2d3ee4a
JA
426 if [ -s $changelog ]
427 then
428 rm $changelog
429 else
430 echo "DISCOURSE_HOSTNAME change failed."
431 update_ok="n"
432 fi
433
434 sed -i -e "s/^ DISCOURSE_DEVELOPER_EMAILS:.*/ DISCOURSE_DEVELOPER_EMAILS: \'$developer_emails\'/w $changelog" $config_file
435 if [ -s $changelog ]
436 then
437 rm $changelog
438 else
439 echo "DISCOURSE_DEVELOPER_EMAILS change failed."
440 update_ok="n"
441 fi
442
013b5931 443 sed -i -e "s/^ DISCOURSE_SMTP_ADDRESS:.*/ DISCOURSE_SMTP_ADDRESS: $smtp_address/w $changelog" $config_file
c2d3ee4a
JA
444 if [ -s $changelog ]
445 then
446 rm $changelog
447 else
448 echo "DISCOURSE_SMTP_ADDRESS change failed."
449 update_ok="n"
450 fi
451
f17af951 452 sed -i -e "s/^ #\?DISCOURSE_SMTP_PORT:.*/ DISCOURSE_SMTP_PORT: $smtp_port/w $changelog" $config_file
7c2777f9
JA
453 if [ -s $changelog ]
454 then
455 rm $changelog
456 else
457 echo "DISCOURSE_SMTP_PORT change failed."
458 update_ok="n"
459 fi
460
f17af951 461 sed -i -e "s/^ #\?DISCOURSE_SMTP_USER_NAME:.*/ DISCOURSE_SMTP_USER_NAME: $smtp_user_name/w $changelog" $config_file
c2d3ee4a
JA
462 if [ -s $changelog ]
463 then
464 rm $changelog
465 else
466 echo "DISCOURSE_SMTP_USER_NAME change failed."
467 update_ok="n"
468 fi
469
f17af951 470 sed -i -e "s/^ #\?DISCOURSE_SMTP_PASSWORD:.*/ DISCOURSE_SMTP_PASSWORD: \"${smtp_password/\//\\/}\"/w $changelog" $config_file
c2d3ee4a
JA
471 if [ -s $changelog ]
472 then
473 rm $changelog
474 else
475 echo "DISCOURSE_SMTP_PASSWORD change failed."
476 update_ok="n"
477 fi
478
f17af951 479 if [ "$letsencrypt_status" = "ENTER to skip" ]
c2d3ee4a 480 then
f17af951
JP
481 local src='^ #\?- "templates\/web.ssl.template.yml"'
482 local dst=' #\- "templates\/web.ssl.template.yml"'
483 sed -i -e "s/$src/$dst/w $changelog" $config_file
2391b7fc 484 if [ ! -s $changelog ]
f17af951 485 then
f17af951
JP
486 update_ok="n"
487 echo "web.ssl.template.yml NOT DISABLED--Are you using a non-standard template?"
488 fi
489 local src='^ #\?- "templates\/web.letsencrypt.ssl.template.yml"'
490 local dst=' #- "templates\/web.letsencrypt.ssl.template.yml"'
491
492 sed -i -e "s/$src/$dst/w $changelog" $config_file
2391b7fc 493 if [ ! -s $changelog ]
f17af951 494 then
f17af951
JP
495 update_ok="n"
496 echo "web.ssl.template.yml NOT DISABLED--Are you using a non-standard template?"
497 fi
498 else # enable let's encrypt
499 echo "Let's Encrypt will be enabled for $letsencrypt_account_email"
500 sed -i -e "s/^ #\?LETSENCRYPT_ACCOUNT_EMAIL:.*/ LETSENCRYPT_ACCOUNT_EMAIL: $letsencrypt_account_email/w $changelog" $config_file
c2d3ee4a
JA
501 if [ -s $changelog ]
502 then
503 rm $changelog
504 else
505 echo "LETSENCRYPT_ACCOUNT_EMAIL change failed."
506 update_ok="n"
507 fi
f17af951 508 local src='^ #\?- "templates\/web.ssl.template.yml"'
c2d3ee4a
JA
509 local dst=' \- "templates\/web.ssl.template.yml"'
510 sed -i -e "s/$src/$dst/w $changelog" $config_file
511 if [ -s $changelog ]
512 then
642b870f 513 echo "web.ssl.template.yml enabled"
c2d3ee4a
JA
514 else
515 update_ok="n"
516 echo "web.ssl.template.yml NOT ENABLED--was it on already?"
517 fi
f17af951 518 local src='^ #\?- "templates\/web.letsencrypt.ssl.template.yml"'
c2d3ee4a
JA
519 local dst=' - "templates\/web.letsencrypt.ssl.template.yml"'
520
521 sed -i -e "s/$src/$dst/w $changelog" $config_file
522 if [ -s $changelog ]
523 then
524 echo "letsencrypt.ssl.template.yml enabled"
525 else
526 update_ok="n"
527 echo "letsencrypt.ssl.template.yml NOT ENABLED -- was it on already?"
528 fi
c87c4b0a 529 fi
c2d3ee4a
JA
530
531 if [ "$update_ok" == "y" ]
532 then
533 echo -e "\nConfiguration file at $config_file updated successfully!\n"
534 else
535 echo -e "\nUnfortunately, there was an error changing $config_file\n"
536 exit 1
537 fi
538}
539
540##
541## is our config file valid? Does it have the required fields set?
542##
4b1b25e3 543validate_config() {
c2d3ee4a
JA
544
545 valid_config="y"
c87c4b0a 546
c2d3ee4a
JA
547 for x in DISCOURSE_SMTP_ADDRESS DISCOURSE_SMTP_USER_NAME DISCOURSE_SMTP_PASSWORD \
548 DISCOURSE_DEVELOPER_EMAILS DISCOURSE_HOSTNAME
549 do
c87c4b0a 550 config_line=`grep "^ $x:" $config_file`
c2d3ee4a
JA
551 local result=$?
552 local default="example.com"
553
554 if (( result == 0 ))
555 then
17f62d87 556 if [[ "$config_line" = *"$default"* ]]
c2d3ee4a
JA
557 then
558 echo "$x left at incorrect default of example.com"
559 valid_config="n"
560 fi
561 config_val=`echo $config_line | awk '{print $2}'`
562 if [ -z $config_val ]
563 then
564 echo "$x was left blank"
565 valid_config="n"
566 fi
567 else
568 echo "$x not present"
569 valid_config="n"
570 fi
571 done
c87c4b0a 572
c2d3ee4a
JA
573 if [ "$valid_config" != "y" ]; then
574 echo -e "\nSorry, these $config_file settings aren't valid -- can't continue!"
d8613c71
JA
575 echo "If you have unusual requirements, edit $config_file and then: "
576 echo "./launcher bootstrap $app_name"
c2d3ee4a
JA
577 exit 1
578 fi
579}
580
581
582##
583## template file names
584##
585app_name=app
586template_path=samples/standalone.yml
587config_file=containers/$app_name.yml
588changelog=/tmp/changelog
589
4b1b25e3
JA
590##
591## Check requirements before creating a copy of a config file we won't edit
592##
ebdd72f3 593check_root
18602189 594check_and_install_docker
642b870f
JP
595check_disk_and_memory
596check_ports
597
4b1b25e3 598##
c2d3ee4a 599## make a copy of the simple standalone config file
4b1b25e3 600##
c2d3ee4a
JA
601if [ -a $config_file ]
602then
603 echo "The configuration file $config_file already exists!"
f17af951
JP
604 echo
605 echo ". . . reconfiguring . . ."
606 echo
17f62d87
JP
607 DATE=`date +"%Y-%m-%d-%H%M%S"`
608 BACKUP=$app_name.yml.$DATE.bak
609 echo Saving old file as $BACKUP
610 cp $config_file containers/$BACKUP
611 echo
c2d3ee4a
JA
612else
613 cp $template_path $config_file
614fi
615
c2d3ee4a 616scale_ram_and_cpu
4b1b25e3
JA
617ask_user_for_config
618validate_config
c2d3ee4a 619
4b1b25e3
JA
620##
621## if we reach this point without exiting, OK to proceed
f17af951 622## rebuild won't fail if there's nothing to rebuild and does the restart
4b1b25e3 623##
f17af951
JP
624sleep 5 # Just a chance to ^C in case they were too fast on the draw
625time ./launcher rebuild $app_name