aboutsummaryrefslogtreecommitdiff
path: root/gn/services/discourse.scm
blob: 0074c7b0a22b3206b48ad45905516a7ef60b8d26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
(define-module (gn services discourse))

(use-modules (gnu)
             (gn packages ruby)
             (guix modules)
             (guix records)
             (ice-9 match))
(use-service-modules networking shepherd web)
(use-package-modules node ruby)

(define-record-type* <discourse-configuration>
  discourse-configuration
  make-discourse-configuration
  discourse-configuration?
  (package          discourse-configuration-package     ; package
                    (default discourse))
  (deploy-directory discourse-deploy-directory          ; string
                    (default "/srv/http"))
  (port             discourse-configuration-port        ; list of strings
                    (default '("3000")))
  (bundler          discourse-configuration-bundler     ; package
                    (default bundler))
  )

(define discourse-activation
  (match-lambda
    (($ <discourse-configuration> package deploy-directory port bundler)
     #~(begin
         (mkdir-p #$deploy-directory)
         (copy-recursively #$package #$deploy-directory)
         (for-each make-file-writable (find-files #$deploy-directory))
         (with-directory-excursion #$deploy-directory
           ;; copied from the discourse package.
           (substitute* "Gemfile"
             ;; Don't require specific versions of these gems
             (("6.0.3.3") (package-version ruby-rails))
             (("2.0.1") (package-version ruby-sassc))
             (("active_model_serializers.*") "active_model_serializers'\n")
             ;; Add tzinfo-data and figure out how to use non-Ruby version later
             (("active_model_serializers'")
              "active_model_serializers'\ngem 'tzinfo-data'")
             ;; ruby-cppjieba-rb never finishes the install phase with ruby-2.6
             ((".*cppjieba_rb.*") ""))
           (invoke #$(file-append node "/bin/npm") "install" "svgo")
           )
         ))))

(define discourse-service
  (match-lambda
    (($ <discourse-configuration> package deploy-directory port bundler)
     (with-imported-modules (source-module-closure
                              '((gnu build shepherd)
                                (gnu system file-systems)))
       (list (shepherd-service
               (provision '(discourse))
               (requirement '(networking))
               (modules '((gnu build shepherd)
                          (gnu system file-systems)))
               (start #~(make-forkexec-constructor/container
                          (list #$(file-append package "/server.py"))
                          ;; Needs to run from the directory it is located in.
                          #:directory #$deploy-directory
                          #:log-file "/var/log/discourse.log"
                          ;; We don't need to set TMPDIR because we're inside a container.
                          #:environment-variables
                          '(
                            ;"EDIRECT_PUBMED_MASTER=/export2/PubMed"
                            ;"NLTK_DATA=/var/cache/nltk_data"
                            ;"PERL_LWP_SSL_CA_FILE=/etc/ssl/certs/ca-certificates.crt"
                            )
                          ;#:mappings (list (file-system-mapping
                          ;                   (source "/export2/PubMed")
                          ;                   (target source)
                          ;                   (writable? #t))
                          ;                 (file-system-mapping
                          ;                   (source "/export/ratspub")
                          ;                   (target source)
                          ;                   (writable? #t))
                          ;                 (file-system-mapping
                          ;                   (source "/var/cache/nltk_data")
                          ;                   (target source))
                          ;                 (file-system-mapping
                          ;                   (source "/etc/ssl/certs")
                          ;                   (target source)))
                          ))
               (stop  #~(make-kill-destructor)))))
     )))

(define discourse-service-type
  (service-type
    (name 'discourse)
    (extensions
      (list
        (service-extension activation-service-type
                           discourse-activation)
        (service-extension shepherd-root-service-type
                           discourse-service)
        ;; Make sure discourse doesn't get garbage collected.
        (service-extension profile-service-type
                           (compose list discourse-configuration-package))
        ;; Make sure php-fpm is instantiated.
        (service-extension php-fpm-service-type
                           (const #t))))
    (default-value (discourse-configuration))
    (description
     "Run an instance of Discourse.")))

(operating-system
  (host-name "discourse")
  (timezone "Etc/UTC")
  (locale "en_US.utf8")

  (bootloader (bootloader-configuration
               (bootloader grub-bootloader)
               (targets '("does-not-matter"))))
  (file-systems %base-file-systems)
  ;; No firmware for VMs.
  (firmware '())
  (packages (append
              (list node)
              %base-packages))

  (services (list (service dhcp-client-service-type)
                  (service discourse-service-type
                           ;; The following is for testing:
                           ;(discourse-configuration
                           ;  (port '("3333")))
                           ))))