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