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