]> Sergey Matveev's repositories - sgblog.git/blob - README.texi
Experimental gemini support
[sgblog.git] / README.texi
1 \input texinfo
2 @documentencoding UTF-8
3 @settitle SGBlog
4
5 @copying
6 Copyright @copyright{} 2020 @email{stargrave@@stargrave.org, Sergey Matveev}
7 @end copying
8
9 @node Top
10 @top SGBlog
11
12 SGBlog is minimalistic and simple Git-backed CGI/UCSPI
13 @url{https://en.wikipedia.org/wiki/Blog, blogging} (@code{http://}/@code{https://}),
14 @url{https://en.wikipedia.org/wiki/Phlog, phlogging} (@code{gopher://}) and
15 gemlogging (@code{gemini://}) engine
16 with email-backed comments support, written on @url{https://golang.org/, Go}.
17
18 Its main competitive features:
19
20 @itemize
21 @item Single binary, responsible for both blog, phlog and gemlog
22 @item @url{https://git-scm.com/, Git} DVCS as a storage for posts and comments
23 @item Single small @url{https://hjson.github.io/, Hjson} configuration file
24 @item Uses @url{https://en.wikipedia.org/wiki/Common_Gateway_Interface, CGI}
25     interface (simplicity, remember?) for dealing with HTTP-server
26 @item Uses
27     @url{https://en.wikipedia.org/wiki/Inetd, inetd}/@url{http://cr.yp.to/ucspi-tcp.html, UCSPI-TCP}
28     interface for working as
29     @url{https://en.wikipedia.org/wiki/Gopher_(protocol), Gopher} server
30 @item Topics (tags/categories) support
31 @item Supports on the fly generation of
32     @url{https://en.wikipedia.org/wiki/Atom_(feed), Atom} feeds
33     for posts, comments and per-post comments
34 @item Single binary for email-backed comments posting
35 @item If access is granted, then everyone can easily create an offline
36     copy of your blog/phlog/gemlog!
37 @end itemize
38
39 All of that, except for comments, topics and phlog/gemlog, could be achieved
40 with some Git viewer like @url{https://git.zx2c4.com/cgit/about/, cgit}.
41 But SGBlog also is able to:
42
43 @itemize
44 @item Convert URLs to clickable links
45 @item Convert SHA1-like hashes to blog links itself
46 @item Include relative @code{<link rel>} links for ease of navigation in
47     some browsers
48 @item @url{https://en.wikipedia.org/wiki/Gzip, gzip} compress both HTML
49     pages and Atom feeds
50 @item Respect @url{https://en.wikipedia.org/wiki/HTTP_ETag, ETag}
51     caching for both of them above
52 @end itemize
53
54 @url{http://blog.stargrave.org/example/, Here} is an example blog.
55
56 SGBlog is free software, licenced under
57 @url{https://www.gnu.org/licenses/agpl-3.0.html, GNU AGPLv3}:
58 see the file COPYING for copying conditions.
59
60 @node Comments
61 @unnumbered Comments
62
63 Comments are posted through the email interface, just by sending the
64 message to special address. For example:
65
66 @example
67 $ mutt "mailto:comment@@blog.example.com?subject=BlaBlaBla%20(576540a5b98517b46d0efc791bb90b9121bf147e)" <<EOF
68 This is the comments contents.
69 Could be multilined of course.
70 EOF
71 @end example
72
73 Comments are stored in Git as a @url{https://git-scm.com/docs/git-notes, note}.
74 Those objects could be updated without touching the base commit itself.
75
76 Each comment is just a plaintext with @code{From} and @code{Date}
77 headers. @code{From} is a name of email sender (with email address
78 stripped off).
79
80 Only @code{text/plain} or @code{multipart/signed+text/plain} email
81 messages are accepted and only with UTF-8, US-ASCII, ISO-8859-1
82 character sets. Sane people won't send HTML email anyway, but this is
83 just a precaution.
84
85 Comments are stored in @dfn{recfiles} --
86 @url{https://www.gnu.org/software/recutils/, GNU recutils}
87 human-editable plaintext database format. But they do not contain
88 records description:
89
90 @verbatim
91 %rec: Comment
92 %doc: SGBlog's comment
93 %mandatory: From Date Body
94 %type: Date date
95 @end verbatim
96
97 @node Topics
98 @unnumbered Topics
99
100 Each post can have any number of attached topics (also known as tags or
101 categories). They are whitespace separated single words kept in separate
102 @url{https://git-scm.com/docs/git-notes, note} namespace. You can
103 add/change comments with commands like:
104
105 @example
106 $ git notes --ref=topics add -m "linux hate" @@
107 $ git push origin mybranch refs/notes/topics
108 @end example
109
110 To reset incorrectly added topic:
111
112 @example
113 $ git update-ref refs/notes/topics refs/notes/topics^
114 @end example
115
116 @node Installation
117 @unnumbered Installation
118
119 SGBlog's is written on Go and uses its modules. Hopefully you can
120 install it just by running:
121
122 @example
123 $ go get go.stargrave.org/sgblog/cmd/sgblog
124 $ go get go.stargrave.org/sgblog/cmd/sgblog-comment-add # if you need commenting
125 @end example
126
127 Unfortunately by default it uses HTTPS and Go's third party servers
128 (@code{sum.golang.org}, @code{proxy.golang.org}) that trust neither
129 @code{CACert.org}'s CA (used previously) nor @code{ca.cypherpunks.ru}
130 CAs. So either disable their usage and trust that certificate:
131 @code{GOPRIVATE=go.stargrave.org/sgblog}, or clone its source code
132 manually and build in place:
133 @url{git://git.stargrave.org/sgblog.git},
134 @url{https://git.stargrave.org/sgblog.git}.
135
136 For enabling blog availability you have to use HTTP server with CGI
137 interface. Example part of @url{http://www.lighttpd.net/, lighttpd}'s
138 configuration:
139
140 @example
141 $HTTP["host"] == "blog.example.com" @{
142   server.document-root = www_dir + "/blog.example.com"
143   $HTTP["url"] =~ "^/example" @{
144     alias.url += ("/example" => "/path/to/sgblog")
145     cgi.assign = ("sgblog" => "/path/to/sgblog")
146     setenv.add-environment = (
147       "SGBLOG_CFG" => "/path/to/example.hjson",
148     )
149   @}
150 @}
151 @end example
152
153 And be sure that you have read access to the Git repository, for example
154 by placing @code{lighttpd} user into @code{git} group.
155
156 Example @command{inetd} configuration (for phlog):
157
158 @example
159 gopher stream tcp6 nowait lighttpd /path/to/sgblog sgblog -gopher /path/to/gopher.hjson
160 @end example
161
162 Example @command{UCSPI-TCP} service running under
163 @url{http://cr.yp.to/daemontools.html, daemontools}:
164
165 @example
166 # mkdir -p /var/service/.phlog-ipv6/log
167 # cd /var/service/.phlog-ipv6
168
169 # cat > run <<EOF
170 #!/bin/sh -e
171 uid=\`id -u lighttpd\`
172 gid=\`id -g git\`
173 addr=2001::123
174 exec tcpserver -DHR -u $uid -g $gid -l 0 $addr gopher \
175   sgblog -gopher /path/to/gopher.hjson
176 EOF
177
178 # cat > log/run <<EOF
179 #!/bin/sh -e
180 exec setuidgid whatever-user multilog t ./main
181 EOF
182
183 # chmod -R 755 /var/service/.phlog-ipv6
184 # mv /var/service/.phlog-ipv6 /var/service/phlog-ipv6
185 @end example
186
187 Gemlog uses Gemini protocol that requires TLS usage, that can be
188 achieved with @url{go.cypherpunks.ru/ucspi} tools:
189
190 @example
191 exec tcpserver -DRH -u $uid -g $gid -l 0 ::0 1965 \
192   tlss -key gemlog.key.pem -cert gemlog.pem \
193   sgblog -gemini /home/sgblog/gemlog.hjson 2>&1
194 @end example
195
196 For comments workability you have to configure your SMTP server to feed
197 incoming messages to @command{sgblog-comment-add} utility. For example,
198 Postfix'es @file{/etc/aliases} can contain:
199
200 @example
201 comment: "| /path/to/sgblog-comment-add -git-dir /path/to/blog.git -committer-email comment@@blog.example.com"
202 @end example
203
204 to run that utility for all @code{comment@@} address messages.
205 You must have enough permission to be able to write to Git repository,
206 but Postfix by default runs all that commands from a @code{nobody} user.
207 So possibly you will need to @code{setuid} that executable give
208 permission for @code{nobody} running:
209
210 @example
211 -rwsr-x--- git:nobody sgblog-comment-add
212 @end example
213
214 And also do not forget about @code{lighttpd} user's (possibly in
215 @code{git} group) read permission permissions. Make sure
216 @command{sgblog-comment-add} runs with correctly set @code{-umask} (027
217 by default) for newly created Git objects/files.
218
219 @node Configuration
220 @unnumbered Configuration
221
222 SGBlog is configured via Hjson configuration file. More or less
223 self-describing blog configuration looks like that and contains many
224 optional fields:
225
226 @example
227 @{
228   GitPath: /home/sgblog/blog.git
229   Branch: refs/heads/example
230   Title: "Example blog"
231
232   BaseURL: http://blog.example.com
233   URLPrefix: /example
234
235   AtomId: "urn:uuid:54e6e53f-c615-48f1-812c-6f6b094ebbdd"
236   AtomAuthor: John Doe
237
238   # URL to CSS file, optional
239   CSS: /style.css
240   # Email address of the webmaster, optional
241   Webmaster: "webmaster@@example.com"
242   # URL to about page, optional
243   AboutURL: /
244   # Optional list of optional Git URLs for corresponding <link rel="vcs-git">
245   GitURLs: [
246     git://git.example.com/blog.git
247     https://git.example.com/git/blog.git
248   ]
249
250   # If that ref is set, then comments will be loaded from it
251   CommentsNotesRef: refs/notes/comments
252   # Display link for comment writing, if email is set
253   CommentsEmail: something@@example.com
254
255   # If that ref is set, then topics will be loaded from it
256   TopicsNotesRef: refs/notes/topics
257   # Optional file for topics state caching
258   TopicsCachePath: /path/to/sgblog-topics-cache.gob
259 @}
260 @end example
261
262 Gopher configuration can use the same file, but it requires much less
263 options:
264
265 @example
266 @{
267   GitPath: /home/sgblog/blog.git
268   Branch: refs/heads/example
269   Title: "Example blog"
270
271   GopherDomain: phlog.example.com
272
273   AboutURL: http://blog.example.com/
274
275   # Both are optional
276   CommentsNotesRef: refs/notes/comments
277   CommentsEmail: something@@example.com
278
279   # Both are optional too
280   TopicsNotesRef: refs/notes/topics
281   TopicsCachePath: /path/to/sgblog-topics-cache.gob
282 @}
283 @end example
284
285 @bye