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