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