Bump base image (#538)
[discourse_docker.git] / discourse-setup
1 #!/usr/bin/env bash
2 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
3 cd $DIR
4
5 if [ "$1" == "2container" ]
6 then
7 TWO_CONTAINER="1"
8 echo "2container argument is deprecated. Use --two-container"
9 shift 1
10 fi
11
12 while [ ${#} -gt 0 ]; do
13 case "${1}" in
14 --debug)
15 DEBUG="1"
16 SKIP_REBUILD="1"
17 ;;
18 --skip-rebuild)
19 SKIP_REBUILD="1"
20 ;;
21 --two-container)
22 TWO_CONTAINER="1"
23 ;;
24 --skip-connection-test)
25 SKIP_CONNECTION_TEST="1"
26 echo "skipping connection test"
27 ;;
28 esac
29
30 shift 1
31 done
32
33 ##
34 ## Make sure only root can run our script
35 ##
36 check_root() {
37 if [[ $EUID -ne 0 ]]; then
38 echo "This script must be run as root. Please sudo or log in as root first." 1>&2
39 exit 1
40 fi
41 }
42
43 ##
44 ## Check whether a connection to HOSTNAME ($1) on PORT ($2) is possible
45 ##
46 connect_to_port () {
47 HOST="$1"
48 PORT="$2"
49 VERIFY=$(date +%s | sha256sum | base64 | head -c 20)
50 if ! [ -x "$(command -v nc)" ]; then
51 echo "In order to check the connection to $HOST:$PORT we need to open a socket using netcat."
52 echo However netcat is not installed on your system. You can continue without this check
53 echo or abort the setup, install netcat and try again.
54 while true; do
55 read -p "Would you like to continue without this check? [yn] " yn
56 case $yn in
57 [Yy]*) return 2 ;;
58 [Nn]*) exit ;;
59 *) echo "Please answer y or n." ;;
60 esac
61 done
62 else
63 echo -e "HTTP/1.1 200 OK\n\n $VERIFY" | nc -w 4 -l -p $PORT >/dev/null 2>&1 &
64 if curl --proto =http -s $HOST:$PORT --connect-timeout 3 | grep $VERIFY >/dev/null 2>&1; then
65 return 0
66 else
67 curl --proto =http -s localhost:$PORT >/dev/null 2>&1
68 return 1
69 fi
70 fi
71 }
72
73 check_IP_match() {
74 HOST="$1"
75 echo
76 if [ "$SKIP_CONNECTION_TEST" == 1 ]
77 then
78 echo "Setting EC to 2"
79 ec=2
80 else
81 echo Checking your domain name . . .
82 connect_to_port $HOST 443; ec=$?
83 fi
84 case $ec in
85 0)
86 echo "Connection to $HOST succeeded."
87 ;;
88 1)
89 echo "WARNING: Port 443 of computer does not appear to be accessible using hostname: $HOST."
90 if connect_to_port $HOST 80; then
91 echo
92 echo SUCCESS: A connection to port 80 succeeds!
93 echo This suggests that your DNS settings are correct,
94 echo but something is keeping traffic to port 443 from getting to your server.
95 echo Check your networking configuration to see that connections to port 443 are allowed.
96 else
97 echo "WARNING: Connection to http://$HOST (port 80) also fails."
98 echo
99 echo "This suggests that $HOST resolves to some IP address that does not reach this "
100 echo machine where you are installing discourse.
101 fi
102 echo
103 echo "The first thing to do is confirm that $HOST resolves to the IP address of this server."
104 echo You usually do this at the same place you purchased the domain.
105 echo
106 echo If you are sure that the IP address resolves correctly, it could be a firewall issue.
107 echo A web search for \"open ports YOUR CLOUD SERVICE\" might help.
108 echo
109 echo This tool is designed only for the most standard installations. If you cannot resolve
110 echo the issue above, you will need to edit containers/app.yml yourself and then type
111 echo
112 echo ./launcher rebuild app
113 echo
114 exit 1
115 ;;
116 2)
117 echo "Skipping port check."
118 ;;
119 esac
120 }
121
122 ##
123 ## Do we have docker?
124 ##
125 check_and_install_docker () {
126 docker_path=`which docker.io || which docker`
127 if [ -z $docker_path ]; then
128 read -p "Docker not installed. Enter to install from https://get.docker.com/ or Ctrl+C to exit"
129 curl https://get.docker.com/ | sh
130 fi
131 docker_path=`which docker.io || which docker`
132 if [ -z $docker_path ]; then
133 echo Docker install failed. Quitting.
134 exit
135 fi
136 }
137
138 ##
139 ## What are we running on
140 ##
141 check_OS() {
142 echo `uname -s`
143 }
144
145 ##
146 ## OS X available memory
147 ##
148 check_osx_memory() {
149 echo `free -m | awk '/Mem:/ {print $2}'`
150 }
151
152 ##
153 ## Linux available memory
154 ##
155 check_linux_memory() {
156 ## some VMs report just under 1GB of RAM, so
157 ## make an exception and allow those with more
158 ## than 989MB
159 mem=`free -m --si | awk ' /Mem:/ {print $2}'`
160 if [ "$mem" -ge 990 -a "$mem" -lt 1000 ]; then
161 echo 1
162 else
163 echo `free -g --si | awk ' /Mem:/ {print $2} '`
164 fi
165 }
166
167 ##
168 ## Do we have enough memory and disk space for Discourse?
169 ##
170 check_disk_and_memory() {
171
172 os_type=$(check_OS)
173 avail_mem=0
174 if [ "$os_type" == "Darwin" ]; then
175 avail_mem=$(check_osx_memory)
176 else
177 avail_mem=$(check_linux_memory)
178 fi
179
180 if [ "$avail_mem" -lt 1 ]; then
181 echo "WARNING: Discourse requires 1GB RAM to run. This system does not appear"
182 echo "to have sufficient memory."
183 echo
184 echo "Your site may not work properly, or future upgrades of Discourse may not"
185 echo "complete successfully."
186 exit 1
187 fi
188
189 if [ "$avail_mem" -le 2 ]; then
190 total_swap=`free -g --si | awk ' /Swap:/ {print $2} '`
191
192 if [ "$total_swap" -lt 2 ]; then
193 echo "WARNING: Discourse requires at least 2GB of swap when running with 2GB of RAM"
194 echo "or less. This system does not appear to have sufficient swap space."
195 echo
196 echo "Without sufficient swap space, your site may not work properly, and future"
197 echo "upgrades of Discourse may not complete successfully."
198 echo
199 echo "Ctrl+C to exit or wait 5 seconds to have a 2GB swapfile created."
200 sleep 5
201
202 ##
203 ## derived from https://meta.discourse.org/t/13880
204 ##
205 install -o root -g root -m 0600 /dev/null /swapfile
206 fallocate -l 2G /swapfile
207 mkswap /swapfile
208 swapon /swapfile
209 echo "/swapfile swap swap auto 0 0" | tee -a /etc/fstab
210 sysctl -w vm.swappiness=10
211 echo 'vm.swappiness = 10' > /etc/sysctl.d/30-discourse-swap.conf
212
213 total_swap=`free -g --si | awk ' /Swap:/ {print $2} '`
214 if [ "$total_swap" -lt 2 ]; then
215 echo "Failed to create swap: are you root? Are you running on real hardware, or a fully virtualized server?"
216 exit 1
217 fi
218
219 fi
220 fi
221
222 free_disk="$(df /var | tail -n 1 | awk '{print $4}')"
223 if [ "$free_disk" -lt 5000 ]; then
224 echo "WARNING: Discourse requires at least 5GB free disk space. This system"
225 echo "does not appear to have sufficient disk space."
226 echo
227 echo "Insufficient disk space may result in problems running your site, and"
228 echo "may not even allow Discourse installation to complete successfully."
229 echo
230 echo "Please free up some space, or expand your disk, before continuing."
231 echo
232 echo "Run \`apt-get autoremove && apt-get autoclean\` to clean up unused"
233 echo "packages and \`./launcher cleanup\` to remove stale Docker containers."
234 exit 1
235 fi
236
237 }
238
239
240 ##
241 ## If we have lots of RAM or lots of CPUs, bump up the defaults to scale better
242 ##
243 scale_ram_and_cpu() {
244
245 local changelog=/tmp/changelog.$PPID
246 # grab info about total system ram and physical (NOT LOGICAL!) CPU cores
247 avail_gb=0
248 avail_cores=0
249 os_type=$(check_OS)
250 if [ "$os_type" == "Darwin" ]; then
251 avail_gb=$(check_osx_memory)
252 avail_cores=`sysctl hw.ncpu | awk '/hw.ncpu:/ {print $2}'`
253 else
254 avail_gb=$(check_linux_memory)
255 avail_cores=$((`awk '/cpu cores/ {print $4;exit}' /proc/cpuinfo`*`sort /proc/cpuinfo | uniq | grep -c "physical id"`))
256 fi
257 echo "Found ${avail_gb}GB of memory and $avail_cores physical CPU cores"
258
259 # db_shared_buffers: 128MB for 1GB, 256MB for 2GB, or 256MB * GB, max 4096MB
260 if [ "$avail_gb" -eq "1" ]
261 then
262 db_shared_buffers=128
263 else
264 if [ "$avail_gb" -eq "2" ]
265 then
266 db_shared_buffers=256
267 else
268 db_shared_buffers=$(( 256 * $avail_gb ))
269 fi
270 fi
271 db_shared_buffers=$(( db_shared_buffers < 4096 ? db_shared_buffers : 4096 ))
272
273 sed -i -e "s/^ #\?db_shared_buffers:.*/ db_shared_buffers: \"${db_shared_buffers}MB\"/w $changelog" $data_file
274 if [ -s $changelog ]
275 then
276 echo "setting db_shared_buffers = ${db_shared_buffers}MB"
277 rm $changelog
278 fi
279
280 # UNICORN_WORKERS: 2 * GB for 2GB or less, or 2 * CPU, max 8
281 if [ "$avail_gb" -le "2" ]
282 then
283 unicorn_workers=$(( 2 * $avail_gb ))
284 else
285 unicorn_workers=$(( 2 * $avail_cores ))
286 fi
287 unicorn_workers=$(( unicorn_workers < 8 ? unicorn_workers : 8 ))
288
289 sed -i -e "s/^ #\?UNICORN_WORKERS:.*/ UNICORN_WORKERS: ${unicorn_workers}/w $changelog" $web_file
290 if [ -s $changelog ]
291 then
292 echo "setting UNICORN_WORKERS = ${unicorn_workers}"
293 rm $changelog
294 fi
295
296 echo $data_file memory parameters updated.
297 }
298
299
300 ##
301 ## standard http / https ports must not be occupied
302 ##
303 check_ports() {
304 check_port "80"
305 check_port "443"
306 echo "Ports 80 and 443 are free for use"
307 }
308
309
310 ##
311 ## check a port to see if it is already in use
312 ##
313 check_port() {
314
315 local valid=$(lsof -i:${1} | grep "LISTEN")
316
317 if [ -n "$valid" ]; then
318 echo "Port ${1} appears to already be in use."
319 echo
320 echo "This will show you what command is using port ${1}"
321 lsof -i tcp:${1} -s tcp:listen
322 echo
323 echo "If you are trying to run Discourse simultaneously with another web"
324 echo "server like Apache or nginx, you will need to bind to a different port"
325 echo
326 echo "See https://meta.discourse.org/t/17247"
327 echo
328 echo "If you are reconfiguring an already-configured Discourse, use "
329 echo
330 echo "./launcher stop app"
331 echo
332 echo "to stop Discourse before you reconfigure it and try again."
333 exit 1
334 fi
335 }
336
337 ##
338 ## read a variable from the config file
339 ##
340 read_config() {
341 config_line=`egrep "^ #?$1:" $web_file`
342 read_config_result=`echo $config_line | awk -F":" '{print $2}'`
343 read_config_result=`echo $read_config_result | sed "s/^\([\"']\)\(.*\)\1\$/\2/g"`
344 }
345
346 read_default() {
347 config_line=`egrep "^ #?$1:" samples/standalone.yml`
348 read_default_result=`echo $config_line | awk -F":" '{print $2}'`
349 read_default_result=`echo $read_config_result | sed "s/^\([\"']\)\(.*\)\1\$/\2/g"`
350 }
351
352 assert_maxmind_license_key() {
353 if ! grep DISCOURSE_MAXMIND_LICENSE_KEY $web_file >/dev/null 2>&1
354 then
355 echo "Adding MAXMIND placeholder to $web_file"
356 sed -i '/^.*LETSENCRYPT_ACCOUNT_EMAIL.*/a \ \ #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456' $web_file
357 fi
358 if ! grep DISCOURSE_MAXMIND_LICENSE_KEY $web_file >/dev/null 2>&1
359 then
360 cat <<EOF
361
362 Adding DISCOURSE_MAXMIND_LICENSE_KEY to $web_file has failed! This
363 indicates either that your $web_file is very old or otherwise not
364 what the script expects or that there is a bug in this script. The
365 best solution for a novice is to delete $web_file and start over.
366 An expert might prefer to edit $web_file by hand.
367
368 EOF
369 read -p "Press return to continue or control-c to quit..."
370 fi
371 }
372
373 assert_smtp_domain() {
374 if ! grep DISCOURSE_SMTP_DOMAIN $web_file >/dev/null 2>&1
375 then
376 echo "Adding SMTP_DOMAIN placeholder to $web_file"
377 sed -i '/^.*DISCOURSE_SMTP_PASSWORD.*/a \ \ #DISCOURSE_SMTP_DOMAIN: discourse.example.com # (required by some providers)' $web_file
378 fi
379 if ! grep DISCOURSE_SMTP_DOMAIN $web_file >/dev/null 2>&1
380 then
381 cat <<EOF
382
383 Adding DISCOURSE_SMTP_DOMAIN to $web_file has failed! This
384 indicates either that your $web_file is very old or otherwise not
385 what the script expects or that there is a bug in this script. The
386 best solution for a novice is to delete $web_file and start over.
387 An expert might prefer to edit $web_file by hand.
388
389 EOF
390 read -p "Press return to continue or control-c to quit..."
391 fi
392 }
393
394
395 assert_notification_email() {
396 if ! grep DISCOURSE_NOTIFICATION_EMAIL $web_file >/dev/null 2>&1
397 then
398 echo "Adding DISCOURSE_NOTIFICATION_EMAIL placeholder to $web_file"
399 sed -i '/^.*DISCOURSE_SMTP_PASSWORD.*/a \ \ #DISCOURSE_NOTIFICATION_EMAIL: nobody@discourse.example.com # (address to send notifications from)' $web_file
400 fi
401 if ! grep DISCOURSE_NOTIFICATION_EMAIL $web_file >/dev/null 2>&1
402 then
403 cat <<EOF
404
405 Adding DISCOURSE_NOTIFICATION_EMAIL to $web_file has failed! This
406 indicates either that your $web_file is very old or otherwise not
407 what the script expects or that there is a bug in this script. The
408 best solution for a novice is to delete $web_file and start over.
409 An expert might prefer to edit $web_file by hand.
410
411 EOF
412 read -p "Press return to continue or control-c to quit..."
413 fi
414 }
415
416
417 ##
418 ## prompt user for typical Discourse config file values
419 ##
420 ask_user_for_config() {
421
422 # NOTE: Defaults now come from standalone.yml
423
424 read_config "DISCOURSE_HOSTNAME"
425 hostname=$read_config_result
426 local changelog=/tmp/changelog.$PPID
427 read_config "DISCOURSE_SMTP_ADDRESS"
428 local smtp_address=$read_config_result
429 # NOTE: if there are spaces between emails, this breaks, but a human should be paying attention
430 read_config "DISCOURSE_DEVELOPER_EMAILS"
431 local developer_emails=$read_config_result
432 read_config "DISCOURSE_SMTP_PASSWORD"
433 local smtp_password=$read_config_result
434 read_config "DISCOURSE_SMTP_PORT"
435 local smtp_port=$read_config_result
436 read_config "DISCOURSE_SMTP_USER_NAME"
437 local smtp_user_name=$read_config_result
438 if [ "$smtp_password" = "pa$$word" ]
439 then
440 smtp_password = ""
441 fi
442 read_config "DISCOURSE_NOTIFICATION_EMAIL"
443 local notification_email=$read_config_result
444 read_config "DISCOURSE_SMTP_DOMAIN"
445 local discourse_smtp_DOMAIN=$read_config_result
446
447 read_config "LETSENCRYPT_ACCOUNT_EMAIL"
448 local letsencrypt_account_email=$read_config_result
449 if [ -z $letsencrypt_account_email ]
450 then
451 letsencrypt_account_email="me@example.com"
452 fi
453 if [ "$letsencrypt_account_email" = "me@example.com" ]
454 then
455 local letsencrypt_status="ENTER to skip"
456 else
457 local letsencrypt_status="Enter 'OFF' to disable."
458 fi
459
460 read_config "DISCOURSE_MAXMIND_LICENSE_KEY"
461 local maxmind_license_key=$read_config_result
462 if [ -z $maxmind_license_key ]
463 then
464 maxmind_license_key="1234567890123456"
465 fi
466 if [ "$maxmind_license_key" == "1234567890123456" ]
467 then
468 local maxmind_status="ENTER to continue without MAXMIND GeoLite2 geolocation database"
469 fi
470
471 local new_value=""
472 local config_ok="n"
473 local update_ok="y"
474
475 echo ""
476
477 while [[ "$config_ok" == "n" ]]
478 do
479 if [ ! -z "$hostname" ]
480 then
481 read -p "Hostname for your Discourse? [$hostname]: " new_value
482 if [ ! -z "$new_value" ]
483 then
484 hostname="$new_value"
485 fi
486 if [[ $hostname =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
487 then
488 echo
489 echo "Discourse requires a DNS hostname. IP addresses are unsupported and will not work."
490 echo
491 hostname="discourse.example.com"
492 fi
493 fi
494
495 check_IP_match $hostname
496
497 if [ ! -z "$developer_emails" ]
498 then
499 local email_valid="n"
500 until [ "$email_valid" == "y" ]
501 do
502 read -p "Email address for admin account(s)? [$developer_emails]: " new_value
503 if [ ! -z "$new_value" ]
504 then
505 if [[ ${#new_value} -ge 7 && $new_value == *@* ]]
506 then
507 developer_emails="$new_value"
508 email_valid="y"
509 else
510 echo
511 echo "[Error] Invalid email address"
512 echo
513 fi
514 else
515 email_valid="y"
516 fi
517 done
518 fi
519
520 if [ ! -z "$smtp_address" ]
521 then
522 read -p "SMTP server address? [$smtp_address]: " new_value
523 if [ ! -z "$new_value" ]
524 then
525 smtp_address="$new_value"
526 fi
527 fi
528
529 if [ ! -z "$smtp_port" ]
530 then
531 read -p "SMTP port? [$smtp_port]: " new_value
532 if [ ! -z "$new_value" ]
533 then
534 smtp_port="$new_value"
535 fi
536 fi
537
538 ##
539 ## automatically set correct user name based on common mail providers unless it's been set
540 ##
541 if [ "$smtp_user_name" == "user@example.com" ]
542 then
543 if [ "$smtp_address" == "smtp.sparkpostmail.com" ]
544 then
545 smtp_user_name="SMTP_Injection"
546 fi
547 if [ "$smtp_address" == "smtp.sendgrid.net" ]
548 then
549 smtp_user_name="apikey"
550 fi
551 if [ "$smtp_address" == "smtp.mailgun.org" ]
552 then
553 smtp_user_name="postmaster@$hostname"
554 fi
555 fi
556
557 if [ ! -z "$smtp_user_name" ]
558 then
559 read -p "SMTP user name? [$smtp_user_name]: " new_value
560 if [ ! -z "$new_value" ]
561 then
562 smtp_user_name="$new_value"
563 fi
564 fi
565
566 read -p "SMTP password? [$smtp_password]: " new_value
567 if [ ! -z "$new_value" ]
568 then
569 smtp_password="$new_value"
570 fi
571
572 if [[ "$notification_email" == "noreply@discourse.example.com"* ]]
573 then
574 notification_email="noreply@$hostname"
575 fi
576
577 read -p "notification email address? [$notification_email]: " new_value
578 if [ ! -z "$new_value" ]
579 then
580 notification_email="$new_value"
581 fi
582
583 # set smtp_domain default value here rather than use Rails default of localhost
584 smtp_domain=$(echo $notification_email | sed -e "s/.*@//")
585
586 if [ ! -z $letsencrypt_account_email ]
587 then
588 read -p "Optional email address for Let's Encrypt warnings? ($letsencrypt_status) [$letsencrypt_account_email]: " new_value
589 if [ ! -z "$new_value" ]
590 then
591 letsencrypt_account_email="$new_value"
592 if [ "${new_value,,}" = "off" ]
593 then
594 letsencrypt_status="ENTER to skip"
595 else
596 letsencrypt_status="Enter 'OFF' to disable."
597 fi
598 fi
599 fi
600
601 read_config "DISCOURSE_MAXMIND_LICENSE_KEY"
602 local maxmind_license_key=$read_config_result
603 read -p "Optional Maxmind License key ($maxmind_status) [$maxmind_license_key]: " new_value
604 if [ ! -z "$new_value" ]
605 then
606 maxmind_license_key="$new_value"
607 fi
608
609 echo -e "\nDoes this look right?\n"
610 echo "Hostname : $hostname"
611 echo "Email : $developer_emails"
612 echo "SMTP address : $smtp_address"
613 echo "SMTP port : $smtp_port"
614 echo "SMTP username : $smtp_user_name"
615 echo "SMTP password : $smtp_password"
616 echo "Notification email: $notification_email"
617
618 if [ "$letsencrypt_status" == "Enter 'OFF' to disable." ]
619 then
620 echo "Let's Encrypt : $letsencrypt_account_email"
621 fi
622
623 if [ "$maxmind_license_key" != "1234567890123456" ]
624 then
625 echo "Maxmind license: $maxmind_license_key"
626 else
627 echo "Maxmind license: (unset)"
628 fi
629
630 echo ""
631 read -p "ENTER to continue, 'n' to try again, Ctrl+C to exit: " config_ok
632 done
633
634 sed -i -e "s/^ DISCOURSE_HOSTNAME:.*/ DISCOURSE_HOSTNAME: $hostname/w $changelog" $web_file
635 if [ -s $changelog ]
636 then
637 rm $changelog
638 else
639 echo "DISCOURSE_HOSTNAME change failed."
640 update_ok="n"
641 fi
642
643 sed -i -e "s/^ DISCOURSE_DEVELOPER_EMAILS:.*/ DISCOURSE_DEVELOPER_EMAILS: \'$developer_emails\'/w $changelog" $web_file
644 if [ -s $changelog ]
645 then
646 rm $changelog
647 else
648 echo "DISCOURSE_DEVELOPER_EMAILS change failed."
649 update_ok="n"
650 fi
651
652 sed -i -e "s/^ DISCOURSE_SMTP_ADDRESS:.*/ DISCOURSE_SMTP_ADDRESS: $smtp_address/w $changelog" $web_file
653 if [ -s $changelog ]
654 then
655 rm $changelog
656 else
657 echo "DISCOURSE_SMTP_ADDRESS change failed."
658 update_ok="n"
659 fi
660
661 sed -i -e "s/^ #\?DISCOURSE_SMTP_PORT:.*/ DISCOURSE_SMTP_PORT: $smtp_port/w $changelog" $web_file
662 if [ -s $changelog ]
663 then
664 rm $changelog
665 else
666 echo "DISCOURSE_SMTP_PORT change failed."
667 update_ok="n"
668 fi
669
670 sed -i -e "s/^ #\?DISCOURSE_SMTP_USER_NAME:.*/ DISCOURSE_SMTP_USER_NAME: $smtp_user_name/w $changelog" $web_file
671 if [ -s $changelog ]
672 then
673 rm $changelog
674 else
675 echo "DISCOURSE_SMTP_USER_NAME change failed."
676 update_ok="n"
677 fi
678
679 sed -i -e "s/^ #\?DISCOURSE_NOTIFICATION_EMAIL:.*/ DISCOURSE_NOTIFICATION_EMAIL: $notification_email/w $changelog" $web_file
680 if [ -s $changelog ]
681 then
682 rm $changelog
683 else
684 echo "DISCOURSE_NOTIFICATION_EMAIL change failed."
685 update_ok="n"
686 fi
687
688 sed -i -e "s/^ #\?DISCOURSE_SMTP_DOMAIN:.*/ DISCOURSE_SMTP_DOMAIN: $smtp_domain/w $changelog" $web_file
689 if [ -s $changelog ]
690 then
691 rm $changelog
692 else
693 echo "DISCOURSE_SMTP_DOMAIN change failed."
694 update_ok="n"
695 fi
696
697 if [[ "$smtp_password" == *"\""* ]]
698 then
699 SLASH="BROKEN"
700 echo "========================================"
701 echo "WARNING!!!"
702 echo "Your password contains a quote (\")"
703 echo "Your SMTP Password will not be set. You will need to edit app.yml to enter it."
704 echo "========================================"
705 update_ok="n"
706 else
707 SLASH="|"
708 if [[ "$smtp_password" == *"$SLASH"* ]]
709 then SLASH="+"
710 if [[ "$smtp_password" == *"$SLASH"* ]]
711 then
712 SLASH="Q"
713 if [[ "$smtp_password" == *"$SLASH"* ]]
714 then
715 SLASH="BROKEN"
716 echo "========================================"
717 echo "WARNING!!!"
718 echo "Your password contains all available delimiters (+, |, and Q). "
719 echo "Your SMTP Password will not be set. You will need to edit app.yml to enter it."
720 echo "========================================"
721 update_ok="n"
722 fi
723 fi
724 fi
725 fi
726 if [[ "$SLASH" != "BROKEN" ]]
727 then
728 sed -i -e "s${SLASH}^ #\?DISCOURSE_SMTP_PASSWORD:.*${SLASH} DISCOURSE_SMTP_PASSWORD: \"${smtp_password}\"${SLASH}w $changelog" $web_file
729
730 if [ -s $changelog ]
731 then
732 rm $changelog
733 else
734 echo "DISCOURSE_SMTP_PASSWORD change failed."
735 update_ok="n"
736 fi
737 fi
738
739 if ! [ -z $DEBUG ]
740 then
741 echo "Enabling Let's Encrypt"
742 fi
743 sed -i -e "s/^ #\?LETSENCRYPT_ACCOUNT_EMAIL:.*/ LETSENCRYPT_ACCOUNT_EMAIL: $letsencrypt_account_email/w $changelog" $web_file
744 if [ -s $changelog ]
745 then
746 rm $changelog
747 else
748 echo "LETSENCRYPT_ACCOUNT_EMAIL change failed."
749 update_ok="n"
750 fi
751 local src='^ #\?- "templates\/web.ssl.template.yml"'
752 local dst=' \- "templates\/web.ssl.template.yml"'
753 sed -i -e "s/$src/$dst/w $changelog" $web_file
754 if [ -s $changelog ]
755 then
756 if ! [ -z $DEBUG ]
757 then
758 echo "web.ssl.template.yml enabled"
759 fi
760 else
761 update_ok="n"
762 echo "web.ssl.template.yml NOT ENABLED--was it on already?"
763 fi
764 local src='^ #\?- "templates\/web.letsencrypt.ssl.template.yml"'
765 local dst=' - "templates\/web.letsencrypt.ssl.template.yml"'
766
767 sed -i -e "s/$src/$dst/w $changelog" $web_file
768 if [ -s $changelog ]
769 then
770 echo "letsencrypt.ssl.template.yml enabled"
771 else
772 update_ok="n"
773 echo "letsencrypt.ssl.template.yml NOT ENABLED -- was it on already?"
774 fi
775
776 echo
777 if [ $maxmind_license_key != "1234567890123456" ]
778 then
779 sed -i -e "s/^.*DISCOURSE_MAXMIND_LICENSE_KEY:.*/ DISCOURSE_MAXMIND_LICENSE_KEY: $maxmind_license_key/w $changelog" $web_file
780 if [ -s $changelog ]
781 then
782 rm $changelog
783 else
784 echo "DISCOURSE_MAXMIND_LICENSE_KEY change failed."
785 update_ok="n"
786 fi
787 fi
788
789 if [ "$update_ok" == "y" ]
790 then
791 echo -e "\nConfiguration file at $web_file updated successfully!\n"
792 else
793 echo -e "\nUnfortunately, there was an error changing $web_file\n"
794 echo -e "This may happen if you have made unexpected changes."
795 exit 1
796 fi
797 }
798
799 ##
800 ## is our config file valid? Does it have the required fields set?
801 ##
802 validate_config() {
803
804 valid_config="y"
805
806 for x in DISCOURSE_SMTP_ADDRESS DISCOURSE_SMTP_USER_NAME DISCOURSE_SMTP_PASSWORD \
807 DISCOURSE_DEVELOPER_EMAILS DISCOURSE_HOSTNAME
808 do
809 read_config $x
810 local result=$read_config_result
811 read_default $x
812 local default=$read_default_result
813
814 if [ ! -z "$result" ]
815 then
816 if [[ "$config_line" = *"$default"* ]]
817 then
818 echo "$x left at incorrect default of $default"
819 valid_config="n"
820 fi
821 config_val=`echo $config_line | awk '{print $2}'`
822 if [ -z $config_val ]
823 then
824 echo "$x was not configured"
825 valid_config="n"
826 fi
827 else
828 echo "$x not present"
829 valid_config="n"
830 fi
831 done
832
833 if [ "$valid_config" != "y" ]; then
834 echo -e "\nSorry, these $web_file settings aren't valid -- can't continue!"
835 echo "If you have unusual requirements, edit $web_file and then: "
836 echo "./launcher bootstrap $app_name"
837 exit 1
838 fi
839 }
840
841
842 ##
843 ## template file names
844 ##
845
846 if [ "$TWO_CONTAINER" ] || [ -f containers/web_only.yml ]
847 then
848 app_name=web_only
849 data_name=data
850 web_template=samples/web_only.yml
851 data_template=samples/data.yml
852 web_file=containers/$app_name.yml
853 data_file=containers/$data_name.yml
854 else
855 app_name=app
856 data_name=app
857 web_template=samples/standalone.yml
858 data_template=""
859 web_file=containers/$app_name.yml
860 data_file=containers/$app_name.yml
861 fi
862 changelog=/tmp/changelog
863
864 ##
865 ## Check requirements before creating a copy of a config file we won't edit
866 ##
867 check_root
868 check_and_install_docker
869 check_disk_and_memory
870
871 if [ -a "$web_file" ]
872 then
873 echo "The configuration file $web_file already exists!"
874 echo
875 echo ". . . reconfiguring . . ."
876 echo
877 echo
878 DATE=`date +"%Y-%m-%d-%H%M%S"`
879 BACKUP=$app_name.yml.$DATE.bak
880 echo Saving old file as $BACKUP
881 cp $web_file containers/$BACKUP
882 if [ "$DEBUG" != "1" ]
883 then
884 echo "Stopping existing container in 5 seconds or Control-C to cancel."
885 sleep 5
886 else
887 echo "DEBUG MODE ON. Not stopping the container."
888 fi
889 ./launcher stop $app_name
890 assert_maxmind_license_key
891 assert_notification_email
892 assert_smtp_domain
893 echo
894 else
895 if [ "$SKIP_CONNECTION_TEST" != 1 ]
896 then
897 check_ports
898 fi
899 cp -v $web_template $web_file
900 if [ "$data_name" == "data" ]
901 then
902 echo "--------------------------------------------------"
903 echo "This two container setup is currently unsupported. Use at your own risk!"
904 echo "--------------------------------------------------"
905 DISCOURSE_DB_PASSWORD=`date +%s | sha256sum | base64 | head -c 20`
906
907 sed -i -e "s/DISCOURSE_DB_PASSWORD: SOME_SECRET/DISCOURSE_DB_PASSWORD: $DISCOURSE_DB_PASSWORD/w $changelog" $web_file
908 if [ -s $changelog ]
909 then
910 rm $changelog
911 else
912 echo "Problem changing DISCOURSE_DB_PASSWORD" in $web_file
913 fi
914
915 cp -v $data_template $data_file
916 quote=\'
917 sed -i -e "s/password ${quote}SOME_SECRET${quote}/password '$DISCOURSE_DB_PASSWORD'/w $changelog" $data_file
918 if [ -s $changelog ]
919 then
920 rm $changelog
921 else
922 echo "Problem changing DISCOURSE_DB_PASSWORD" in $data_file
923 fi
924 fi
925 fi
926
927 scale_ram_and_cpu
928 ask_user_for_config
929 validate_config
930
931 ##
932 ## if we reach this point without exiting, OK to proceed
933 ## rebuild won't fail if there's nothing to rebuild and does the restart
934 ##
935 if [ "$SKIP_REBUILD" ]
936 then
937 echo "Updates successful. --skip-rebuild requested. Exiting."
938 exit
939 fi
940
941 echo "Updates successful. Rebuilding in 5 seconds."
942 sleep 5 # Just a chance to ^C in case they were too fast on the draw
943
944 if [ "$data_name" == "$app_name" ]
945 then
946 echo Building $app_name
947 ./launcher rebuild $app_name
948 else
949 echo Building $data_name now . . .
950 ./launcher rebuild $data_name
951 echo Building $app_name now . . .
952 ./launcher rebuild $app_name
953 fi