FIX: remove pull for Discourse core (#499)
[discourse_docker.git] / templates / web.template.yml
... / ...
CommitLineData
1env:
2 # You can have redis on a different box
3 RAILS_ENV: 'production'
4 UNICORN_WORKERS: 3
5 UNICORN_SIDEKIQS: 1
6 # this gives us very good cache coverage, 96 -> 99
7 # in practice it is 1-2% perf improvement
8 RUBY_GLOBAL_METHOD_CACHE_SIZE: 131072
9 # stop heap doubling in size so aggressively, this conserves memory
10 RUBY_GC_HEAP_GROWTH_MAX_SLOTS: 40000
11 RUBY_GC_HEAP_INIT_SLOTS: 400000
12 RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR: 1.5
13
14 DISCOURSE_DB_SOCKET: /var/run/postgresql
15 DISCOURSE_DB_HOST:
16 DISCOURSE_DB_PORT:
17
18
19params:
20 version: tests-passed
21
22 home: /var/www/discourse
23 upload_size: 10m
24
25run:
26 - exec: thpoff echo "thpoff is installed!"
27 - exec: /usr/local/bin/ruby -e 'if ENV["DISCOURSE_SMTP_ADDRESS"] == "smtp.example.com"; puts "Aborting! Mail is not configured!"; exit 1; end'
28 - exec: /usr/local/bin/ruby -e 'if ENV["DISCOURSE_HOSTNAME"] == "discourse.example.com"; puts "Aborting! Domain is not configured!"; exit 1; end'
29 - exec: /usr/local/bin/ruby -e 'if (ENV["DISCOURSE_CDN_URL"] || "")[0..1] == "//"; puts "Aborting! CDN must have a protocol specified. Once fixed you should rebake your posts now to correct all posts."; exit 1; end'
30 - exec: chown -R discourse /home/discourse
31 # TODO: move to base image (anacron can not be fired up using rc.d)
32 - exec: rm -f /etc/cron.d/anacron
33 - file:
34 path: /etc/cron.d/anacron
35 contents: |
36 SHELL=/bin/sh
37 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
38
39 30 7 * * * root /usr/sbin/anacron -s >/dev/null
40 - file:
41 path: /etc/runit/1.d/copy-env
42 chmod: "+x"
43 contents: |
44 #!/bin/bash
45 env > ~/boot_env
46 conf=/var/www/discourse/config/discourse.conf
47
48 # find DISCOURSE_ env vars, strip the leader, lowercase the key
49 /usr/local/bin/ruby -e 'ENV.each{|k,v| puts "#{$1.downcase} = '\''#{v}'\''" if k =~ /^DISCOURSE_(.*)/}' > $conf
50
51 - file:
52 path: /etc/service/unicorn/run
53 chmod: "+x"
54 contents: |
55 #!/bin/bash
56 exec 2>&1
57 # redis
58 # postgres
59 cd $home
60 chown -R discourse:www-data /shared/log/rails
61 LD_PRELOAD=$RUBY_ALLOCATOR HOME=/home/discourse USER=discourse exec thpoff chpst -u discourse:www-data -U discourse:www-data bundle exec config/unicorn_launcher -E production -c config/unicorn.conf.rb
62
63 - file:
64 path: /etc/service/nginx/run
65 chmod: "+x"
66 contents: |
67 #!/bin/sh
68 exec 2>&1
69 exec /usr/sbin/nginx
70
71 - file:
72 path: /etc/runit/3.d/01-nginx
73 chmod: "+x"
74 contents: |
75 #!/bin/bash
76 sv stop nginx
77
78 - file:
79 path: /etc/runit/3.d/02-unicorn
80 chmod: "+x"
81 contents: |
82 #!/bin/bash
83 sv stop unicorn
84
85 - exec:
86 cd: $home
87 hook: code
88 cmd:
89 - git reset --hard
90 - git clean -f
91 - git remote set-branches --add origin master
92 - git remote set-branches origin $version
93 - git fetch --depth 1 origin $version
94 - git checkout $version
95 - mkdir -p tmp
96 - chown discourse:www-data tmp
97 - mkdir -p tmp/pids
98 - mkdir -p tmp/sockets
99 - touch tmp/.gitkeep
100 - mkdir -p /shared/log/rails
101 - bash -c "touch -a /shared/log/rails/{production,production_errors,unicorn.stdout,unicorn.stderr,sidekiq}.log"
102 - bash -c "ln -s /shared/log/rails/{production,production_errors,unicorn.stdout,unicorn.stderr,sidekiq}.log $home/log"
103 - bash -c "mkdir -p /shared/{uploads,backups}"
104 - bash -c "ln -s /shared/{uploads,backups} $home/public"
105 - bash -c "mkdir -p /shared/tmp/{backups,restores}"
106 - bash -c "ln -s /shared/tmp/{backups,restores} $home/tmp"
107 - chown -R discourse:www-data /shared/log/rails /shared/uploads /shared/backups /shared/tmp
108 # scrub broken symlinks from plugins that have been removed
109 - find public/plugins/ -maxdepth 1 -xtype l -delete
110
111 - exec:
112 cmd:
113 - "cp $home/config/nginx.sample.conf /etc/nginx/conf.d/discourse.conf"
114 - "rm /etc/nginx/sites-enabled/default"
115 - "mkdir -p /var/nginx/cache"
116
117 - replace:
118 filename: /etc/nginx/nginx.conf
119 from: pid /run/nginx.pid;
120 to: daemon off;
121
122 - replace:
123 filename: "/etc/nginx/conf.d/discourse.conf"
124 from: /upstream[^\}]+\}/m
125 to: "upstream discourse {
126 server 127.0.0.1:3000;
127 }"
128
129 - replace:
130 filename: "/etc/nginx/conf.d/discourse.conf"
131 from: /server_name.+$/
132 to: server_name _ ;
133
134 - replace:
135 filename: "/etc/nginx/conf.d/discourse.conf"
136 from: /client_max_body_size.+$/
137 to: client_max_body_size $upload_size ;
138
139 - exec:
140 cmd: echo "done configuring web"
141 hook: web_config
142
143 - exec:
144 cd: $home
145 hook: web
146 cmd:
147 # ensure we are on latest bundler
148 - gem update bundler
149 - find $home ! -user discourse -exec chown discourse {} \+
150
151 - exec:
152 cd: $home
153 hook: bundle_exec
154 cmd:
155 - su discourse -c 'bundle install --deployment --retry 3 --jobs 4 --verbose --without test development'
156
157 - exec:
158 cd: $home
159 cmd:
160 - su discourse -c 'bundle exec rake plugin:pull_compatible_all'
161 raise_on_fail: false
162
163 - exec:
164 cd: $home
165 hook: db_migrate
166 cmd:
167 - su discourse -c 'bundle exec rake db:migrate'
168 - exec:
169 cd: $home
170 hook: assets_precompile
171 cmd:
172 - su discourse -c 'bundle exec rake themes:update assets:precompile'
173
174 - file:
175 path: /usr/local/bin/discourse
176 chmod: +x
177 contents: |
178 #!/bin/bash
179 (cd /var/www/discourse && RAILS_ENV=production sudo -H -E -u discourse bundle exec script/discourse "$@")
180
181 - file:
182 path: /usr/local/bin/rails
183 chmod: +x
184 contents: |
185 #!/bin/bash
186 # If they requested a console, load pry instead
187 if [ "$*" == "c" -o "$*" == "console" ]
188 then
189 (cd /var/www/discourse && RAILS_ENV=production sudo -H -E -u discourse bundle exec pry -r ./config/environment)
190 else
191 (cd /var/www/discourse && RAILS_ENV=production sudo -H -E -u discourse bundle exec script/rails "$@")
192 fi
193
194 - file:
195 path: /usr/local/bin/rake
196 chmod: +x
197 contents: |
198 #!/bin/bash
199 (cd /var/www/discourse && RAILS_ENV=production sudo -H -E -u discourse bundle exec bin/rake "$@")
200
201 - file:
202 path: /usr/local/bin/rbtrace
203 chmod: +x
204 contents: |
205 #!/bin/bash
206 (cd /var/www/discourse && RAILS_ENV=production sudo -H -E -u discourse bundle exec rbtrace "$@")
207
208 - file:
209 path: /usr/local/bin/stackprof
210 chmod: +x
211 contents: |
212 #!/bin/bash
213 (cd /var/www/discourse && RAILS_ENV=production sudo -H -E -u discourse bundle exec stackprof "$@")
214
215 - file:
216 path: /etc/update-motd.d/10-web
217 chmod: +x
218 contents: |
219 #!/bin/bash
220 echo
221 echo Use: rails, rake or discourse to execute commands in production
222 echo
223
224 - file:
225 path: /etc/logrotate.d/rails
226 contents: |
227 /shared/log/rails/*.log
228 {
229 rotate 7
230 dateext
231 daily
232 missingok
233 delaycompress
234 compress
235 postrotate
236 sv 1 unicorn
237 endscript
238 }
239
240 - file:
241 path: /etc/logrotate.d/nginx
242 contents: |
243 /var/log/nginx/*.log {
244 daily
245 missingok
246 rotate 7
247 compress
248 delaycompress
249 create 0644 www-data www-data
250 sharedscripts
251 postrotate
252 sv 1 nginx
253 endscript
254 }
255
256 # move state out of the container this fancy is done to support rapid rebuilds of containers,
257 # we store anacron and logrotate state outside the container to ensure its maintained across builds
258 # later move this snipped into an intialization script
259 # we also ensure all the symlinks we need to /shared are in place in the correct structure
260 # this allows us to bootstrap on one machine and then run on another
261 - file:
262 path: /etc/runit/1.d/00-ensure-links
263 chmod: +x
264 contents: |
265 #!/bin/bash
266 if [[ ! -L /var/lib/logrotate ]]; then
267 rm -fr /var/lib/logrotate
268 mkdir -p /shared/state/logrotate
269 ln -s /shared/state/logrotate /var/lib/logrotate
270 fi
271 if [[ ! -L /var/spool/anacron ]]; then
272 rm -fr /var/spool/anacron
273 mkdir -p /shared/state/anacron-spool
274 ln -s /shared/state/anacron-spool /var/spool/anacron
275 fi
276 if [[ ! -d /shared/log/rails ]]; then
277 mkdir -p /shared/log/rails
278 chown -R discourse:www-data /shared/log/rails
279 fi
280 if [[ ! -d /shared/uploads ]]; then
281 mkdir -p /shared/uploads
282 chown -R discourse:www-data /shared/uploads
283 fi
284 if [[ ! -d /shared/backups ]]; then
285 mkdir -p /shared/backups
286 chown -R discourse:www-data /shared/backups
287 fi
288
289 rm -rf /shared/tmp/{backups,restores}
290 mkdir -p /shared/tmp/{backups,restores}
291 chown -R discourse:www-data /shared/tmp/{backups,restores}
292 - file:
293 path: /etc/runit/1.d/01-cleanup-web-pids
294 chmod: +x
295 contents: |
296 #!/bin/bash
297 /bin/rm -f /var/www/discourse/tmp/pids/*.pid
298 # change login directory to Discourse home
299 - file:
300 path: /root/.bash_profile
301 chmod: 644
302 contents: |
303 cd $home
304
305 - file:
306 path: /usr/local/etc/ImageMagick-7/policy.xml
307 contents: |
308 <?xml version="1.0" encoding="UTF-8"?>
309 <!DOCTYPE policymap [
310 <!ELEMENT policymap (policy)+>
311 <!ATTLIST policymap xmlns CDATA #FIXED ''>
312 <!ELEMENT policy EMPTY>
313 <!ATTLIST policy xmlns CDATA #FIXED '' domain NMTOKEN #REQUIRED
314 name NMTOKEN #IMPLIED pattern CDATA #IMPLIED rights NMTOKEN #IMPLIED
315 stealth NMTOKEN #IMPLIED value CDATA #IMPLIED>
316 ]>
317 <!--
318 Configure ImageMagick policies.
319
320 Domains include system, delegate, coder, filter, path, or resource.
321
322 Rights include none, read, write, execute and all. Use | to combine them,
323 for example: "read | write" to permit read from, or write to, a path.
324
325 Use a glob expression as a pattern.
326
327 Suppose we do not want users to process MPEG video images:
328
329 <policy domain="delegate" rights="none" pattern="mpeg:decode" />
330
331 Here we do not want users reading images from HTTP:
332
333 <policy domain="coder" rights="none" pattern="HTTP" />
334
335 The /repository file system is restricted to read only. We use a glob
336 expression to match all paths that start with /repository:
337
338 <policy domain="path" rights="read" pattern="/repository/*" />
339
340 Lets prevent users from executing any image filters:
341
342 <policy domain="filter" rights="none" pattern="*" />
343
344 Any large image is cached to disk rather than memory:
345
346 <policy domain="resource" name="area" value="1GP"/>
347
348 Define arguments for the memory, map, area, width, height and disk resources
349 with SI prefixes (.e.g 100MB). In addition, resource policies are maximums
350 for each instance of ImageMagick (e.g. policy memory limit 1GB, -limit 2GB
351 exceeds policy maximum so memory limit is 1GB).
352
353 Rules are processed in order. Here we want to restrict ImageMagick to only
354 read or write a small subset of proven web-safe image types:
355
356 <policy domain="delegate" rights="none" pattern="*" />
357 <policy domain="filter" rights="none" pattern="*" />
358 <policy domain="coder" rights="none" pattern="*" />
359 <policy domain="coder" rights="read|write" pattern="{GIF,JPEG,PNG,WEBP}" />
360 -->
361 <policymap>
362 <!-- <policy domain="system" name="shred" value="2"/> -->
363 <!-- <policy domain="system" name="precision" value="6"/> -->
364 <!-- <policy domain="system" name="memory-map" value="anonymous"/> -->
365 <!-- <policy domain="system" name="max-memory-request" value="256MiB"/> -->
366 <!-- <policy domain="resource" name="temporary-path" value="/tmp"/> -->
367 <policy domain="resource" name="memory" value="1GiB"/>
368 <policy domain="resource" name="map" value="2GiB"/>
369 <policy domain="resource" name="width" value="64KP"/>
370 <policy domain="resource" name="height" value="64KP"/>
371 <!-- <policy domain="resource" name="list-length" value="128"/> -->
372 <policy domain="resource" name="area" value="4GP"/>
373 <policy domain="resource" name="disk" value="8GiB"/>
374 <!-- <policy domain="resource" name="file" value="768"/> -->
375 <!-- <policy domain="resource" name="thread" value="4"/> -->
376 <!-- <policy domain="resource" name="throttle" value="0"/> -->
377 <!-- <policy domain="resource" name="time" value="3600"/> -->
378 <!-- <policy domain="coder" rights="none" pattern="MVG" /> -->
379 <policy domain="module" rights="none" pattern="{PS,PS2,PS3,EPS,PDF,XPS}" />
380 <!-- <policy domain="delegate" rights="none" pattern="HTTPS" /> -->
381 <!-- <policy domain="path" rights="none" pattern="@*" /> -->
382 <!-- <policy domain="cache" name="memory-map" value="anonymous"/> -->
383 <!-- <policy domain="cache" name="synchronize" value="True"/> -->
384 <!-- <policy domain="cache" name="shared-secret" value="passphrase" stealth="true"/> -->
385 </policymap>