gitlab/nginx: Slapos'ify config and turn nginx into a service
[slapos.git] / software / gitlab / instance-gitlab.cfg.in
1 # GitLab instance
2 # NOTE instance/software layout is inspired by gitlab omnibus
3 # NOTE all services are interconnected via unix sockets - because of easier
4 #      security and performance reasons (unix has 2x less latency and more
5 #      throughput compared to tcp over loopback).
6 [buildout]
7 extends = {{ gitlab_parameters_cfg }}
8 parts =
9     directory
10
11 #   gitlab-<prog>
12 # ? mailroom
13 {% set gitlab_progv = 'rails rake unicorn sidekiq unicorn-startup' .split() %}
14 {% for prog in gitlab_progv %}
15     gitlab-{{ prog }}
16 {% endfor %}
17
18     gitconfig
19
20     gitlab-work
21     gitlab-shell-work
22
23     service-gitlab-workhorse
24     service-unicorn
25     service-sidekiq
26
27     service-nginx
28     service-postgresql
29     service-redis
30
31     service-cron
32
33     on-reinstantiate
34
35 # std stuff for slapos instance
36 eggs-directory = {{ eggs_directory }}
37 develop-eggs-directory = {{ develop_eggs_directory }}
38 offline = true
39
40
41 ##################################
42 #   GitLab instance parameters   #
43 ##################################
44
45 [instance-parameter]
46 # std stuff to fetch slapos instance parameters
47 recipe  = slapos.cookbook:slapconfiguration
48 computer= ${slap-connection:computer-id}
49 partition=${slap-connection:partition-id}
50 url     = ${slap-connection:server-url}
51 key     = ${slap-connection:key-file}
52 cert    = ${slap-connection:cert-file}
53
54 # autogenerated gitlab instance parameters
55 <= gitlab-parameters
56
57 # adjust/override some default settings:
58
59 # automatically load all available CPUs
60 configuration.unicorn_worker_processes  = {{ multiprocessing.cpu_count() + 1 }}
61 configuration.nginx_worker_processes    = {{ multiprocessing.cpu_count() }}
62
63
64
65 # for convenience
66 [external-url]
67 recipe  = slapos.cookbook:urlparse
68 url     = ${instance-parameter:configuration.external_url}
69
70 [backend-info]
71 host    = ${instance-parameter:ipv6-random}
72 port    = 7777
73 # whether to use http or https - determined by external url
74 url     = ${external-url:scheme}://[${:host}]:${:port}
75
76 # current slapuserX
77 user    = {{ pwd.getpwuid(os.getuid())[0] }}
78
79
80
81 #############################
82 #   GitLab instance setup   #
83 #############################
84
85 # 1. directories
86 [directory]
87 recipe  = slapos.cookbook:mkdirectory
88 home    = ${buildout:directory}
89 bin     = ${:home}/bin
90 etc     = ${:home}/etc
91 var     = ${:home}/var
92 log     = ${:var}/log
93 run     = ${:var}/run
94 srv     = ${:home}/srv
95 # slapos startup/service/promise scripts live here:
96 startup = ${:etc}/run
97 service = ${:etc}/service
98 promise = ${:etc}/promise
99 promise.slow = ${:promise}.slow
100
101 # gitlab: etc/ log/ ...
102 [gitlab-dir]
103 recipe  = slapos.cookbook:mkdirectory
104 etc     = ${directory:etc}/gitlab
105 log     = ${directory:log}/gitlab
106
107 var     = ${directory:var}/gitlab
108 tmp     = ${:var}/tmp
109 uploads = ${:var}/uploads
110 assets  = ${:var}/assets
111 backup  = ${directory:var}/backup
112
113 [gitlab-repo-dir]
114 recipe  = slapos.cookbook:mkdirectory
115 repositories    = ${directory:var}/repositories
116 # gitlab wants it to be drwxrws---
117 # FIXME setting such mode with :mkdirectory is not possible, because mkdir(2)
118 # does & 0777 and also there is umask. So we workaround:
119 [gitlab-repo-xdir]
120 recipe  = plone.recipe.command
121 stop-on-error = yes
122 repositories = ${gitlab-repo-dir:repositories}
123 command = chmod 02770 ${:repositories}
124
125 [gitlab]
126 etc     = ${gitlab-dir:etc}
127 log     = ${gitlab-dir:log}
128 var     = ${gitlab-dir:var}
129 tmp     = ${gitlab-dir:tmp}
130 uploads = ${gitlab-dir:uploads}
131 assets  = ${gitlab-dir:assets}
132 backup  = ${gitlab-dir:backup}
133 repositories = ${gitlab-repo-xdir:repositories}
134
135
136 # gitlab-shell: etc/ log/ gitlab_shell_secret ...
137 [gitlab-shell-dir]
138 recipe  = slapos.cookbook:mkdirectory
139 etc     = ${directory:etc}/gitlab-shell
140 log     = ${directory:log}/gitlab-shell
141
142 [gitlab-shell]
143 etc     = ${gitlab-shell-dir:etc}
144 log     = ${gitlab-shell-dir:log}
145 secret  = ${secrets:secrets}/gitlab_shell_secret
146
147
148 # place to keep all secrets
149 [secrets]
150 recipe  = slapos.cookbook:mkdirectory
151 secrets = ${directory:var}/secrets
152 mode    = 0700
153
154
155
156
157 # 2. configuration files
158 [etc-template]
159 recipe  = slapos.recipe.template:jinja2
160 extensions = jinja2.ext.do
161 mode    = 0640
162 import-list =
163     rawfile macrolib.cfg.in     {{ macrolib_cfg_in }}
164 context =
165     raw     autogenerated       # This file was autogenerated. (DO NOT EDIT - changes will be lost)
166     section instance_parameter  instance-parameter
167     section backend_info        backend-info
168     import  urlparse            urlparse
169     raw     git                 {{ git }}
170     ${:context-extra}
171 context-extra =
172
173 [gitlab-etc-template]
174 <= etc-template
175 rendered= ${gitlab:etc}/${:_buildout_section_name_}
176
177 [nginx-etc-template]
178 <= etc-template
179 rendered= ${nginx:etc}/${:_buildout_section_name_}
180
181
182 [config.ru]
183 <= gitlab-etc-template
184 template = {{ config_ru_in }}
185
186 [database.yml]
187 <= gitlab-etc-template
188 template= {{ database_yml_in }}
189 context-extra =
190     section pgsql                   service-postgresql
191
192 [gitconfig]
193 <= etc-template
194 template= {{ gitconfig_in }}
195 # NOTE put directly into $HOME/ - this way git will pick it up
196 rendered= ${directory:home}/.${:_buildout_section_name_}
197
198 [gitlab-shell-config.yml]
199 <= etc-template
200 template= {{ gitlab_shell_config_yml_in }}
201 rendered= ${gitlab-shell:etc}/config.yml
202 context-extra =
203     import  urllib                  urllib
204     section gitlab                  gitlab
205     section gitlab_shell            gitlab-shell
206     section unicorn                 unicorn
207     section service_redis           service-redis
208     raw     redis_binprefix         {{ redis_binprefix }}
209
210 [gitlab.yml]
211 <= gitlab-etc-template
212 template= {{ gitlab_yml_in }}
213 context-extra =
214     section gitlab                  gitlab
215     section gitlab_shell            gitlab-shell
216     section gitlab_shell_work       gitlab-shell-work
217
218 [nginx.conf]
219 <= nginx-etc-template
220 template= {{ nginx_conf_in }}
221 context-extra =
222     section directory               directory
223     raw     nginx_mime_types        {{ nginx_mime_types }}
224     raw     nginx_gitlab_http_conf  ${nginx-gitlab-http.conf:rendered}
225
226 [nginx-gitlab-http.conf]
227 <= nginx-etc-template
228 template= {{ nginx_gitlab_http_conf_in }}
229 context-extra =
230     section nginx                   nginx
231     section gitlab_work             gitlab-work
232     section gitlab_workhorse        gitlab-workhorse
233     section unicorn                 unicorn
234
235 [rack_attack.rb]
236 <= gitlab-etc-template
237 template = {{ rack_attack_rb_in }}
238
239 [resque.yml]
240 <= gitlab-etc-template
241 template= {{ resque_yml_in }}
242 context-extra =
243     section redis                   service-redis
244
245 [smtp_settings.rb]
246 <= gitlab-etc-template
247 template= {{ smtp_settings_rb_in }}
248 # contains smtp password
249 mode    = 0600
250
251 [unicorn.rb]
252 <= gitlab-etc-template
253 template = {{ unicorn_rb_in }}
254 context-extra =
255     section unicorn                 unicorn
256     section directory               directory
257     section gitlab_work             gitlab-work
258
259
260
261 # 3. bin/
262 #   gitlab-<prog>
263 [gitlab-bin]
264 recipe  = slapos.cookbook:wrapper
265 wrapper-path = ${directory:bin}/${:_buildout_section_name_}
266 # NOTE $HOME needed to pick gitconfig
267 environment  =
268     BUNDLE_GEMFILE = {{ gitlab_repository_location }}/Gemfile
269     HOME = ${directory:home}
270     RAILS_ENV = production
271     SIDEKIQ_MEMORY_KILLER_MAX_RSS = ${instance-parameter:configuration.sidekiq_memory_killer_max_rss}
272
273 # NOTE sys.argv[1:] implicitly appended
274 # (by slapos.recipe.librecipe.execute.generic_exec() at runtime)
275 command-line =
276     {{ bundler_4gitlab }} exec sh -c
277     'cd ${gitlab-work:location} && ${:prog} "$@"' ${:prog}
278
279 {% for prog in gitlab_progv %}
280 [gitlab-{{ prog }}]
281 <= gitlab-bin
282 prog    = {{ prog }}
283 {% endfor %}
284
285
286 [gitlab-unicorn-startup]
287 recipe  = slapos.recipe.template:jinja2
288 mode    = 0755
289 template= {{ gitlab_unicorn_startup_in }}
290 rendered= ${directory:bin}/${:_buildout_section_name_}
291 context =
292     raw     bash_bin                {{ bash_bin }}
293     raw     gitlab_rake             ${gitlab-rake:wrapper-path}
294     raw     gitlab_unicorn          ${gitlab-unicorn:wrapper-path}
295     raw     psql_bin                {{ postgresql_location }}/bin/psql
296     section pgsql                   service-postgresql
297     raw     log_dir                 ${gitlab:log}
298     section unicorn_rb              unicorn.rb
299     section gitlab_work             gitlab-work
300
301
302 # 4. gitlab- & gitlab-shell- work directories
303 #
304 # Gitlab/Rails operation is tightened that config/ lives inside code, which goes
305 # against having ability to create several instances configured differently
306 # from 1 SR.
307 #
308 # One possibility to overcome this could be to make another Gitlab root
309 # symbolically linked to original SR _and_ several configuration files
310 # symbolically linked to instance place. Unfortunately this does not work -
311 # Ruby determines realpath on module import and Gitlab and Rails lookup config
312 # files relative to imported modules.
313 #
314 # we clone cloned gitlab and add proper links to vendor/bundle and instance
315 # config files.
316 # XXX there is no need for full clone - we only need worktree checkout (a-la `git
317 # worktree add`, but without creating files in original clone)
318 #
319 # This way Gitlab/Rails still think they work in 1 code / 1 instance way,
320 # and we can reuse SR.
321 # XXX better do such tricks with bind mounting, but that requires user namespaces
322
323 [work-base]
324 recipe  = plone.recipe.command
325 stop-on-error = yes
326 location = ${directory:home}/${:_buildout_section_name_}
327 command =
328 # make sure we start from well-defined empty state
329 # (needed e.g. if previous install failed in the middle)
330     rm -rf ${:location}  &&
331 # init work repository and add `software` remote pointing to main repo in SR software/...
332     {{ git }} init ${:location}  &&
333     cd ${:location}  &&
334     {{ git }} remote add software ${:software}  &&
335     ${:update-command}
336
337 update-command =
338     cd ${:location}  &&
339     {{ git }} fetch software  &&
340     {{ git }} reset --hard `cd ${:software} && {{ git }} rev-parse HEAD`  &&
341     ${:tune-command}
342
343
344 # NOTE there is no need to link/create .gitlab_shell_secret - we set path to it
345 # in gitlab & gitlab-shell configs, and gitlab creates it on its first start
346 [gitlab-work]
347 <= work-base
348 software = {{ gitlab_repository_location }}
349 tune-command =
350 # secret* config.ru tmp/ log/
351     rm -f .secret  &&
352     rm -f config.ru  &&
353     rm -rf log tmp  &&
354     ln -sf ${secrets:secrets}/gitlab_rails_secret .secret  &&
355     ln -sf ${config.ru:rendered} config.ru  &&
356     ln -sf ${gitlab:log} log  &&
357     ln -sf ${gitlab:tmp} tmp  &&
358 # config/
359     cd config  &&
360     ln -sf ${unicorn.rb:rendered} unicorn.rb  &&
361     ln -sf ${gitlab.yml:rendered} gitlab.yml  &&
362     ln -sf ${database.yml:rendered} database.yml  &&
363     ln -sf ${resque.yml:rendered} resque.yml  &&
364     ln -sf ${secrets:secrets}/gitlab_secrets.yml secrets.yml  &&
365 # config/initializers/
366     cd initializers  &&
367     ln -sf ${rack_attack.rb:rendered} rack_attack.rb  &&
368     ln -sf ${smtp_settings.rb:rendered} smtp_settings.rb  &&
369 # public/
370     cd ../../public  &&
371     rm -rf uploads assets  &&
372     ln -sf ${gitlab:uploads} uploads  &&
373     ln -sf ${gitlab:assets} assets  &&
374     true
375
376
377 # ----//---- for gitlab-shell
378 [gitlab-shell-work]
379 <= work-base
380 software = {{ gitlab_shell_repository_location }}
381
382 tune-command =
383     ln -sf ${gitlab-shell-config.yml:rendered}   config.yml  &&
384     true
385
386
387
388 # 5. services
389
390 # [promise-<something>] to generate promise wrapper <something>
391 [promise-wrapper]
392 recipe  = slapos.cookbook:wrapper
393 wrapper-path = !py! '${directory:promise}/' + '${:_buildout_section_name_}'[8:]
394
395 # [promise-<something>] to check <something> by url
396 [promise-byurl]
397 recipe  = slapos.cookbook:check_url_available
398 path    = !py! '${directory:promise}/' + '${:_buildout_section_name_}'[8:]
399 dash_path   = {{ bash_bin }}
400 curl_path   = {{ curl_bin }}
401 http_code   = 200
402
403
404
405 #####################
406 #   Postgresql db   #
407 #####################
408
409 # XXX gitlab-omnibus also tunes:
410 # - shared_buffers
411 # - work_mem
412 # - checkpoint_*
413 # - effective_check_size
414 # - lc_* en_US.UTF-8 -> C  (?)
415 [service-postgresql]
416 recipe  = slapos.cookbook:postgres
417 bin     = {{ postgresql_location }}/bin
418 services= ${directory:service}
419
420 dbname  = gitlabhq_production
421 # NOTE db name must match to what was used in KVM on lab.nexedi.com (restore script grants access to this user)
422 superuser = gitlab-psql
423 # no password - pgsql will listen only on unix sockets (see below) thus access
424 # is protected with filesystem-level permissions.
425 # ( besides, if we use slapos.cookbook:generate.password and do `password = ...`
426 #   the password is stored in plain text in .installed and thus becomes insecure )
427 password=
428
429 pgdata-directory = ${directory:srv}/postgresql
430
431 # empty addresses - listen only on unix socket
432 ipv4    = !py!set([])
433 ipv6    = !py!set([])
434 ipv6-random =
435 port    =
436
437 depend  =
438     ${promise-postgresql:recipe}
439
440 [promise-postgresql]
441 <= promise-wrapper
442 command-line =
443     {{ postgresql_location }}/bin/psql
444         -h ${service-postgresql:pgdata-directory}
445         -U ${service-postgresql:superuser}
446         -d ${service-postgresql:dbname}
447         -c '\q'
448
449 # postgresql logs to stdout/stderr - logs are handled by slapos not us
450 # [logrotate-entry-postgresql]
451
452
453 #############
454 #   Redis   #
455 #############
456 [redis]
457 recipe  = slapos.cookbook:mkdirectory
458 srv     = ${directory:srv}/redis
459 log     = ${directory:log}/redis
460
461
462 [service-redis]
463 recipe  = slapos.cookbook:redis.server
464 wrapper = ${directory:service}/redis
465 promise_wrapper = ${directory:promise}/redis
466
467 server_dir  = ${redis:srv}
468 config_file = ${directory:etc}/redis.conf
469 log_file    = ${redis:log}/redis.log
470 pid_file    = ${directory:run}/redis.pid
471 use_passwd  = false
472 unixsocket  = ${:server_dir}/redis.socket
473 # port = 0 means "don't listen on TCP at all" - listen only on unix socket
474 ipv6    = ::1
475 port    = 0
476
477 server_bin  = {{ redis_binprefix }}/redis-server
478 depend  =
479     ${logrotate-entry-redis:recipe}
480
481
482 # NOTE slapos.cookbook:redis.server setups promise automatically
483
484 [logrotate-entry-redis]
485 <= logrotate-entry
486 log     = ${redis:log}/*.log
487
488
489 ########################
490 #   gitlab-workhorse   #
491 ########################
492 [gitlab-workhorse-dir]
493 recipe  = slapos.cookbook:mkdirectory
494 srv     = ${directory:srv}/gitlab-workhorse
495
496 [gitlab-workhorse]
497 srv     = ${gitlab-workhorse-dir:srv}
498 socket  = ${gitlab-workhorse:srv}/gitlab-workhorse.socket
499
500 [service-gitlab-workhorse]
501 recipe  = slapos.cookbook:wrapper
502 wrapper-path    = ${directory:service}/gitlab-workhorse
503 command-line    = {{ gitlab_workhorse }}
504     -listenNetwork unix
505     -listenAddr ${gitlab-workhorse:socket}
506     -authSocket ${unicorn:socket}
507 # NOTE for profiling
508 #   -pprofListenAddr ...
509
510 # NOTE environment for:
511 #   - git to be available on path
512 #   - ruby to be available on path  (gitlab-workhorse -> gitlab-shell -> hooks  on push)
513 #   - gitconfig be found from ~/.gitconfig
514 environment =
515     PATH={{ git_location }}/bin:{{ ruby_location }}/bin:%(PATH)s
516     HOME=${directory:home}
517
518 depend  =
519     ${promise-gitlab-workhorse:recipe}
520
521
522 [promise-gitlab-workhorse]
523 <= promise-byurl
524 # gitlab-workhorse works on repositories. Here we only check it accepts an
525 # serves requests, so request is non-existent URL and expected code is 403
526 url     = --unix-socket ${gitlab-workhorse:socket}  http:/non-existent
527 http_code   = 403
528
529
530 # gitlab-workhorse logs to stdout/stderr - logs are handled by slapos not us
531 # [logrotate-entry-gitlab-workhorse]
532
533
534 ######################
535 #   unicorn worker   #
536 ######################
537 [unicorn-dir]
538 recipe  = slapos.cookbook:mkdirectory
539 srv     = ${directory:srv}/unicorn
540 log     = ${directory:log}/unicorn
541
542 [unicorn]
543 srv     = ${unicorn-dir:srv}
544 log     = ${unicorn-dir:log}
545 socket  = ${:srv}/unicorn.socket
546
547 [service-unicorn]
548 recipe  = slapos.cookbook:wrapper
549 wrapper-path    = ${directory:service}/unicorn
550 # NOTE we perform db setup / migrations as part of unicorn startup.
551 # Those operations require PG and Redis to be up and running already, that's
552 # why we do it here. See gitlab-unicorn-startup for details.
553 command-line    = ${gitlab-unicorn-startup:rendered}
554
555 depend  =
556     ${promise-unicorn:recipe}
557     ${promise-gitlab-app:recipe}
558     ${promise-gitlab-shell:recipe}
559
560     ${logrotate-entry-unicorn:recipe}
561 # gitlab is a service "run" under unicorn
562 # gitlab-shell is called by gitlab
563 # -> associate their logs rotation to here
564     ${logrotate-entry-gitlab:recipe}
565
566
567 [promise-unicorn]
568 <= promise-byurl
569 url     = --unix-socket ${unicorn:socket}  http:/
570
571 [promise-rakebase]
572 recipe  = slapos.cookbook:wrapper
573 # FIXME gitlab-rake is too slow to load and promise timeouts
574 # that's why we instantiate to <promise>.slow/ (and this way promises are not run)
575 wrapper-path    = !py!'${directory:promise.slow}/' + '${:_buildout_section_name_}'[8:]
576 rake    = ${gitlab-rake:wrapper-path}
577
578
579 [promise-gitlab-app]
580 <= promise-rakebase
581 command-line    = ${:rake} gitlab:app:check
582
583 [promise-gitlab-shell]
584 <= promise-rakebase
585 command-line    = ${:rake} gitlab:gitlab_shell:check
586
587 # very slow
588 # rake gitlab:repo:check        (fsck all repos)
589
590
591 [logrotate-entry-unicorn]
592 <= logrotate-entry
593 log     = ${unicorn:log}/*.log
594
595 [logrotate-entry-gitlab]
596 <= logrotate-entry
597 log     = ${gitlab:log}/*.log
598
599 [logrotate-entry-gitlab-shell]
600 <= logrotate-entry
601 log     = ${gitlab-shell:log}/*.log
602
603
604 #######################################
605 #   sidekiq background jobs manager   #
606 #######################################
607 [sidekiq-dir]
608 recipe  = slapos.cookbook:mkdirectory
609 log     = ${directory:log}/sidekiq
610
611 [sidekiq]
612 log     = ${sidekiq-dir:log}
613
614 # NOTE see queue list here:
615 # https://gitlab.com/gitlab-org/gitlab-ce/blob/master/Procfile
616 # https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-cookbooks/gitlab/templates/default/sv-sidekiq-run.erb
617 # (last updated for ominbus-gitlab 8.2.3+ce.0-0-g8eda093)
618 [service-sidekiq]
619 recipe  = slapos.cookbook:wrapper
620 wrapper-path    = ${directory:service}/sidekiq
621 command-line    =
622 # NOTE Sidekiq memory killer just makes sidekiq processes to be SIGKILL
623 # terminated and relies on managing service to restart it. In slapos we don't
624 # have mechanism to set autorestart=true, nor bang/watchdog currently work with
625 # slapproxy, so we do the monitoring ourselves.
626     {{ watcher_sigkill }}
627
628     ${gitlab-sidekiq:wrapper-path}
629 # XXX -q runner ?  (present in gitlab-ce/Procfile  but not in omnibus)
630 # XXX -P ?  (pidfile)
631     -e production
632     -r ${gitlab-work:location}
633     -t ${instance-parameter:configuration.sidekiq_shutdown_timeout}
634     -c ${instance-parameter:configuration.sidekiq_concurrency}
635     -L ${sidekiq:log}/sidekiq.log
636
637     -q post_receive
638     -q mailer
639     -q archive_repo
640     -q system_hook
641     -q project_web_hook
642     -q gitlab_shell
643     -q incoming_email
644     -q common
645     -q default
646
647 depend  =
648     ${promise-sidekiq:recipe}
649     ${logrotate-entry-sidekiq:recipe}
650
651 [promise-sidekiq]
652 <= promise-rakebase
653 command-line    = ${:rake} gitlab:sidekiq:check
654
655 [logrotate-entry-sidekiq]
656 <= logrotate-entry
657 log     = ${sidekiq:log}/*.log
658
659
660 ######################
661 #   Nginx frontend   #
662 ######################
663
664 # srv/nginx/ prefix  +  etc/ log/ ...
665 [nginx-dir]
666 recipe  = slapos.cookbook:mkdirectory
667 srv     = ${directory:srv}/nginx
668 etc     = ${directory:etc}/nginx
669 log     = ${directory:log}/nginx
670
671 [nginx-ssl-dir]
672 recipe  = slapos.cookbook:mkdirectory
673 ssl     = ${nginx-dir:etc}/ssl
674 # contains https key
675 mode    = 0700
676
677 # self-signed certificate for https
678 [nginx-generate-certificate]
679 # NOTE there is slapos.cookbook:certificate_authority.request but it requires
680 # to start whole service and has up to 60 seconds latency to generate
681 # certificate. We only need to run 1 command to do it...
682 recipe  = plone.recipe.command
683 stop-on-error   = true
684 cert_file   = ${nginx-ssl-dir:ssl}/gitlab_backend.crt
685 key_file    = ${nginx-ssl-dir:ssl}/gitlab_backend.key
686
687 command =
688     test -e ${:key_file} || \
689         {{ openssl_bin }} req -newkey rsa -batch -new -x509 -days 3650 -nodes   \
690         -keyout ${:key_file} -out ${:cert_file}
691 update-command = ${:command}
692
693
694 [nginx]
695 srv     = ${nginx-dir:srv}
696 etc     = ${nginx-dir:etc}
697 log     = ${nginx-dir:log}
698 ssl     = ${nginx-ssl-dir:ssl}
699
700 cert_file   = ${nginx-generate-certificate:cert_file}
701 key_file    = ${nginx-generate-certificate:key_file}
702
703
704 [nginx-symlinks]
705 # (nginx wants <prefix>/logs to be there from start - else it issues alarm to the log)
706 recipe  = cns.recipe.symlink
707 symlink = ${nginx:log}  = ${nginx:srv}/logs
708
709 [service-nginx]
710 recipe  = slapos.cookbook:wrapper
711 wrapper-path    = ${directory:service}/nginx
712 command-line    = {{ nginx_bin }} -p ${nginx:srv} -c ${nginx.conf:rendered}
713 depend  =
714     ${nginx-symlinks:recipe}
715     ${promise-nginx:recipe}
716     ${logrotate-entry-nginx:recipe}
717
718
719 [promise-nginx]
720 <= promise-byurl
721 url     = ${backend-info:url}/static.css
722
723 [logrotate-entry-nginx]
724 <= logrotate-entry
725 log     = ${nginx:log}/*.log
726
727
728
729 #############
730 #   cron    #
731 #############
732 [cron-dir]
733 recipe  = slapos.cookbook:mkdirectory
734 cron.d  = ${directory:etc}/cron.d
735 crontabs= ${directory:srv}/cron/crontabs
736 cronstamps = ${directory:var}/cron/cronstamps
737 log     = ${directory:log}/cron
738
739 [service-cron]
740 recipe  = slapos.cookbook:cron
741 binary  = ${directory:service}/crond
742 cron-entries    = ${cron-dir:cron.d}
743 crontabs        = ${cron-dir:crontabs}
744 cronstamps      = ${cron-dir:cronstamps}
745 catcher         = ${cron-simplelogger:wrapper}
746
747 dcrond-binary   = {{ dcron_bin }}
748
749 depends =
750     ${logrotate-entry-cron:recipe}
751
752 # "mailer" that cron uses to emit messages to logfile
753 [cron-simplelogger]
754 recipe  = slapos.cookbook:simplelogger
755 wrapper = ${directory:bin}/${:_buildout_section_name_}
756 log     = ${cron-dir:log}/cron.log
757
758
759 # base entry for clients who registers to cron
760 [cron-entry]
761 recipe  = slapos.cookbook:cron.d
762 # name  = <section-name>.strip_prefix('cron-entry-')
763 # XXX len() is not available in !py! - 11 hardcoded
764 name    = !py!'${:_buildout_section_name_}' [11:]
765 # NOTE _not_ ${service-cron:cron-entries}  - though the value is the same we do
766 # not want service-cron to be instantiated just if a cron-entry is registered.
767 cron-entries = ${cron-dir:cron.d}
768
769 # cron logs are also rotated
770 [logrotate-entry-cron]
771 <= logrotate-entry
772 log     = ${cron-dir:log}/*.log
773
774
775 #######################################
776 #   logrotate base for all services   #
777 #######################################
778 [logrotate-dir]
779 recipe  = slapos.cookbook:mkdirectory
780 srv     = ${directory:srv}/logrotate
781 entries = ${directory:etc}/logrotate.d
782
783 [logrotate]
784 recipe  = slapos.cookbook:logrotate
785 wrapper = ${directory:bin}/${:_buildout_section_name_}
786 conf    = ${directory:etc}/logrotate.conf
787 logrotate-entries   = ${logrotate-dir:entries}
788 state-file  = ${logrotate-dir:srv}/logrotate.status
789
790 logrotate-binary    = {{ logrotate_bin }}
791 gzip-binary     = {{ gzip_bin }}
792 gunzip-binary   = {{ gunzip_bin }}
793
794 depend  = ${cron-entry-logrotate:recipe}
795
796
797 # base entry for clients who registers to logrotate
798 [logrotate-entry]
799 recipe  = slapos.cookbook:logrotate.d
800 logrotate-entries   = ${logrotate:logrotate-entries}
801 # name  = <section-name>.strip_prefix('logrotate-entry-')
802 # XXX len is not available in !py! - 16 hardcoded
803 name    = !py!'${:_buildout_section_name_}'[16:]
804 # NOTE frequency is hardcoded to `daily` in slapos.cookbook:logrotate.d
805 # NOTE backup is also used to add custom logrotate options (hack)
806 backup  = ...
807 # TODO settle whether we need/want olddir or not
808     noolddir
809 # override create emitted by slapos.cookbook:logrotate.d
810     nocreate
811 # do not move log file and this way we do not need to signal its program to
812 # reopen the log. There are a lot of bugs when on such reopen / restart /
813 # graceful-restart something bad happens. Even if copytruncate is a bit racy
814 # and can loose some data, it is better to keep the system the stable way.
815     copytruncate
816
817
818 # hook logrotate into cron
819 [cron-entry-logrotate]
820 <= cron-entry
821 time    = daily
822 command = ${logrotate:wrapper}
823
824
825
826 # 6. on-reinstantiate actions
827
828 # NOTE here we only recompile assets. Other on-reinstantiate actions, which
829 # require pg and redis running, are performed as part of unicorn service -
830 # right before its startup (see gitlab-unicorn-startup).
831 [on-reinstantiate]
832 recipe  = plone.recipe.command
833 stop-on-error   = true
834 rake    = ${gitlab-rake:wrapper-path}
835 # run command on every reinstantiation
836 update-command = ${:command}
837
838 command =
839     ${:rake} assets:clean  &&
840     ${:rake} assets:precompile  &&
841     true