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