Fossil SCM

Removed a bunch of manual indents in pre blocks, MD fenced code blocks, etc. The skin does that for us now.

wyoung 2024-02-10 12:26 inskinerator-modern-backport
Commit 2a7b1de356d12a5fe5ffab37bc90e8514e2831f564e8de2ce0e1a4556394c24b
+15 -15
--- www/alerts.md
+++ www/alerts.md
@@ -91,15 +91,15 @@
9191
9292
Save your changes.
9393
9494
At the command line, say
9595
96
- $ fossil set email-send-command
96
+ $ fossil set email-send-command
9797
9898
If that gives a blank value instead of `sendmail -ti`, say
9999
100
- $ fossil set email-send-command "sendmail -ti"
100
+ $ fossil set email-send-command "sendmail -ti"
101101
102102
to force the setting. That works around a [known
103103
bug](https://fossil-scm.org/forum/forumpost/840b676410) which may be
104104
squished by the time you read this.
105105
@@ -113,13 +113,13 @@
113113
114114
<a id="status"></a>
115115
If you reload the Admin → Notification page, the Status section at the
116116
top should show:
117117
118
- Outgoing Email: Piped to command "sendmail -ti"
119
- Pending Alerts: 0 normal, 0 digest
120
- Subscribers: 0 active, 0 total
118
+ Outgoing Email: Piped to command "sendmail -ti"
119
+ Pending Alerts: 0 normal, 0 digest
120
+ Subscribers: 0 active, 0 total
121121
122122
Before you move on to the next section, you might like to read up on
123123
[some subtleties](#pipe) with the "pipe to a command" method that we did
124124
not cover above.
125125
@@ -211,11 +211,11 @@
211211
message below, then press "Send Message" to verify that outgoing email
212212
is working.
213213
214214
Another method is from the command line:
215215
216
- $ fossil alerts test-message [email protected] --body README.md --subject Test
216
+ $ fossil alerts test-message [email protected] --body README.md --subject Test
217217
218218
That should send you an email with "Test" in the subject line and the
219219
contents of your project's `README.md` file in the body.
220220
221221
That command assumes that your project contains a "readme" file, but of
@@ -261,38 +261,38 @@
261261
If email alerts aren't working, there are several useful commands you
262262
can give to figure out why.
263263
264264
(Be sure to [`cd` into a repo checkout directory](#cd) first!)
265265
266
- $ fossil alerts status
266
+ $ fossil alerts status
267267
268268
This should give much the same information as you saw [above](#status).
269269
One difference is that, since you've created a forum post, the
270270
`pending-alerts` value should only be zero if you did in fact get the
271271
requested email alert. If it's zero, check your mailer's spam folder. If
272272
it's nonzero, continue with these troubleshooting steps.
273273
274
- $ fossil backoffice
274
+ $ fossil backoffice
275275
276276
That forces Fossil to run its ["back office" process](./backoffice.md).
277277
Its only purpose at the time of this writing is to push out alert
278278
emails, but it might do other things later. Sometimes it can get stuck
279279
and needs to be kicked. For that reason, you might want to set up a
280280
crontab entry to make sure it runs occasionally.
281281
282
- $ fossil alerts send
282
+ $ fossil alerts send
283283
284284
This should also kick off the backoffice processing, if there are any
285285
pending alerts to send out.
286286
287
- $ fossil alert pending
287
+ $ fossil alert pending
288288
289289
Show any pending alerts. The number of lines output here should equal
290290
the [status output above](#status).
291291
292
- $ fossil test-add-alerts f5900
293
- $ fossil alert send
292
+ $ fossil test-add-alerts f5900
293
+ $ fossil alert send
294294
295295
Manually create an email alert and push it out immediately.
296296
297297
The `f` in the first command's final parameter means you're scheduling a
298298
"forum" alert. The integer is the ID of a forum post, which you can find
@@ -299,11 +299,11 @@
299299
by visiting `/timeline?showid` on your Fossil instance.
300300
301301
The second command above is necessary because the `test-add-alerts`
302302
command doesn't kick off a backoffice run.
303303
304
- $ fossil ale send
304
+ $ fossil ale send
305305
306306
This only does the same thing as the final command above, rather than
307307
send you an ale, as you might be hoping. Sorry.
308308
309309
@@ -421,11 +421,11 @@
421421
422422
You can start this Tcl script as a daemon automatically on most Unix and
423423
Unix-like systems by adding the following line to the `/etc/rc.local`
424424
file of the server that hosts the repository sending email alerts:
425425
426
- /usr/bin/tclsh /home/www/fossil/email-sender.tcl &
426
+ /usr/bin/tclsh /home/www/fossil/email-sender.tcl &
427427
428428
[cj]: https://en.wikipedia.org/wiki/Chroot
429429
[rdbc]: https://www.sqlite.org/howtocorrupt.html#_filesystems_with_broken_or_missing_lock_implementations
430430
431431
@@ -680,11 +680,11 @@
680680
far as I can see.
681681
682682
If the `subscriberCodes` for a Fossil repository are ever compromised,
683683
new ones can be generated as follows:
684684
685
- UPDATE subscriber SET subscriberCode=randomblob(32);
685
+ UPDATE subscriber SET subscriberCode=randomblob(32);
686686
687687
Since this then affects all new email alerts going out from Fossil, your
688688
end users may never even realize that they're getting new codes, as long
689689
as they don't click on the URLs in the footer of old alert messages.
690690
691691
--- www/alerts.md
+++ www/alerts.md
@@ -91,15 +91,15 @@
91
92 Save your changes.
93
94 At the command line, say
95
96 $ fossil set email-send-command
97
98 If that gives a blank value instead of `sendmail -ti`, say
99
100 $ fossil set email-send-command "sendmail -ti"
101
102 to force the setting. That works around a [known
103 bug](https://fossil-scm.org/forum/forumpost/840b676410) which may be
104 squished by the time you read this.
105
@@ -113,13 +113,13 @@
113
114 <a id="status"></a>
115 If you reload the Admin → Notification page, the Status section at the
116 top should show:
117
118 Outgoing Email: Piped to command "sendmail -ti"
119 Pending Alerts: 0 normal, 0 digest
120 Subscribers: 0 active, 0 total
121
122 Before you move on to the next section, you might like to read up on
123 [some subtleties](#pipe) with the "pipe to a command" method that we did
124 not cover above.
125
@@ -211,11 +211,11 @@
211 message below, then press "Send Message" to verify that outgoing email
212 is working.
213
214 Another method is from the command line:
215
216 $ fossil alerts test-message [email protected] --body README.md --subject Test
217
218 That should send you an email with "Test" in the subject line and the
219 contents of your project's `README.md` file in the body.
220
221 That command assumes that your project contains a "readme" file, but of
@@ -261,38 +261,38 @@
261 If email alerts aren't working, there are several useful commands you
262 can give to figure out why.
263
264 (Be sure to [`cd` into a repo checkout directory](#cd) first!)
265
266 $ fossil alerts status
267
268 This should give much the same information as you saw [above](#status).
269 One difference is that, since you've created a forum post, the
270 `pending-alerts` value should only be zero if you did in fact get the
271 requested email alert. If it's zero, check your mailer's spam folder. If
272 it's nonzero, continue with these troubleshooting steps.
273
274 $ fossil backoffice
275
276 That forces Fossil to run its ["back office" process](./backoffice.md).
277 Its only purpose at the time of this writing is to push out alert
278 emails, but it might do other things later. Sometimes it can get stuck
279 and needs to be kicked. For that reason, you might want to set up a
280 crontab entry to make sure it runs occasionally.
281
282 $ fossil alerts send
283
284 This should also kick off the backoffice processing, if there are any
285 pending alerts to send out.
286
287 $ fossil alert pending
288
289 Show any pending alerts. The number of lines output here should equal
290 the [status output above](#status).
291
292 $ fossil test-add-alerts f5900
293 $ fossil alert send
294
295 Manually create an email alert and push it out immediately.
296
297 The `f` in the first command's final parameter means you're scheduling a
298 "forum" alert. The integer is the ID of a forum post, which you can find
@@ -299,11 +299,11 @@
299 by visiting `/timeline?showid` on your Fossil instance.
300
301 The second command above is necessary because the `test-add-alerts`
302 command doesn't kick off a backoffice run.
303
304 $ fossil ale send
305
306 This only does the same thing as the final command above, rather than
307 send you an ale, as you might be hoping. Sorry.
308
309
@@ -421,11 +421,11 @@
421
422 You can start this Tcl script as a daemon automatically on most Unix and
423 Unix-like systems by adding the following line to the `/etc/rc.local`
424 file of the server that hosts the repository sending email alerts:
425
426 /usr/bin/tclsh /home/www/fossil/email-sender.tcl &
427
428 [cj]: https://en.wikipedia.org/wiki/Chroot
429 [rdbc]: https://www.sqlite.org/howtocorrupt.html#_filesystems_with_broken_or_missing_lock_implementations
430
431
@@ -680,11 +680,11 @@
680 far as I can see.
681
682 If the `subscriberCodes` for a Fossil repository are ever compromised,
683 new ones can be generated as follows:
684
685 UPDATE subscriber SET subscriberCode=randomblob(32);
686
687 Since this then affects all new email alerts going out from Fossil, your
688 end users may never even realize that they're getting new codes, as long
689 as they don't click on the URLs in the footer of old alert messages.
690
691
--- www/alerts.md
+++ www/alerts.md
@@ -91,15 +91,15 @@
91
92 Save your changes.
93
94 At the command line, say
95
96 $ fossil set email-send-command
97
98 If that gives a blank value instead of `sendmail -ti`, say
99
100 $ fossil set email-send-command "sendmail -ti"
101
102 to force the setting. That works around a [known
103 bug](https://fossil-scm.org/forum/forumpost/840b676410) which may be
104 squished by the time you read this.
105
@@ -113,13 +113,13 @@
113
114 <a id="status"></a>
115 If you reload the Admin → Notification page, the Status section at the
116 top should show:
117
118 Outgoing Email: Piped to command "sendmail -ti"
119 Pending Alerts: 0 normal, 0 digest
120 Subscribers: 0 active, 0 total
121
122 Before you move on to the next section, you might like to read up on
123 [some subtleties](#pipe) with the "pipe to a command" method that we did
124 not cover above.
125
@@ -211,11 +211,11 @@
211 message below, then press "Send Message" to verify that outgoing email
212 is working.
213
214 Another method is from the command line:
215
216 $ fossil alerts test-message [email protected] --body README.md --subject Test
217
218 That should send you an email with "Test" in the subject line and the
219 contents of your project's `README.md` file in the body.
220
221 That command assumes that your project contains a "readme" file, but of
@@ -261,38 +261,38 @@
261 If email alerts aren't working, there are several useful commands you
262 can give to figure out why.
263
264 (Be sure to [`cd` into a repo checkout directory](#cd) first!)
265
266 $ fossil alerts status
267
268 This should give much the same information as you saw [above](#status).
269 One difference is that, since you've created a forum post, the
270 `pending-alerts` value should only be zero if you did in fact get the
271 requested email alert. If it's zero, check your mailer's spam folder. If
272 it's nonzero, continue with these troubleshooting steps.
273
274 $ fossil backoffice
275
276 That forces Fossil to run its ["back office" process](./backoffice.md).
277 Its only purpose at the time of this writing is to push out alert
278 emails, but it might do other things later. Sometimes it can get stuck
279 and needs to be kicked. For that reason, you might want to set up a
280 crontab entry to make sure it runs occasionally.
281
282 $ fossil alerts send
283
284 This should also kick off the backoffice processing, if there are any
285 pending alerts to send out.
286
287 $ fossil alert pending
288
289 Show any pending alerts. The number of lines output here should equal
290 the [status output above](#status).
291
292 $ fossil test-add-alerts f5900
293 $ fossil alert send
294
295 Manually create an email alert and push it out immediately.
296
297 The `f` in the first command's final parameter means you're scheduling a
298 "forum" alert. The integer is the ID of a forum post, which you can find
@@ -299,11 +299,11 @@
299 by visiting `/timeline?showid` on your Fossil instance.
300
301 The second command above is necessary because the `test-add-alerts`
302 command doesn't kick off a backoffice run.
303
304 $ fossil ale send
305
306 This only does the same thing as the final command above, rather than
307 send you an ale, as you might be hoping. Sorry.
308
309
@@ -421,11 +421,11 @@
421
422 You can start this Tcl script as a daemon automatically on most Unix and
423 Unix-like systems by adding the following line to the `/etc/rc.local`
424 file of the server that hosts the repository sending email alerts:
425
426 /usr/bin/tclsh /home/www/fossil/email-sender.tcl &
427
428 [cj]: https://en.wikipedia.org/wiki/Chroot
429 [rdbc]: https://www.sqlite.org/howtocorrupt.html#_filesystems_with_broken_or_missing_lock_implementations
430
431
@@ -680,11 +680,11 @@
680 far as I can see.
681
682 If the `subscriberCodes` for a Fossil repository are ever compromised,
683 new ones can be generated as follows:
684
685 UPDATE subscriber SET subscriberCode=randomblob(32);
686
687 Since this then affects all new email alerts going out from Fossil, your
688 end users may never even realize that they're getting new codes, as long
689 as they don't click on the URLs in the footer of old alert messages.
690
691
+2 -2
--- www/backup.md
+++ www/backup.md
@@ -262,12 +262,12 @@
262262
than give up on the security afforded by use of configurable-iteration
263263
PBKDF2. To avoid a conflict with the platform’s `openssl` binary,
264264
Homebrew’s installation is [unlinked][hbul] by default, so you have to
265265
give an explicit path to it, one of:
266266
267
- /usr/local/opt/openssl/bin/openssl ... # Intel x86 Macs
268
- /opt/homebrew/opt/openssl/bin/openssl ... # ARM Macs (“Apple silicon”)
267
+ /usr/local/opt/openssl/bin/openssl ... # Intel x86 Macs
268
+ /opt/homebrew/opt/openssl/bin/openssl ... # ARM Macs (“Apple silicon”)
269269
270270
[lssl]: https://www.libressl.org/
271271
272272
273273
## <a id="rest"></a> Restoring From An Encrypted Backup
274274
--- www/backup.md
+++ www/backup.md
@@ -262,12 +262,12 @@
262 than give up on the security afforded by use of configurable-iteration
263 PBKDF2. To avoid a conflict with the platform’s `openssl` binary,
264 Homebrew’s installation is [unlinked][hbul] by default, so you have to
265 give an explicit path to it, one of:
266
267 /usr/local/opt/openssl/bin/openssl ... # Intel x86 Macs
268 /opt/homebrew/opt/openssl/bin/openssl ... # ARM Macs (“Apple silicon”)
269
270 [lssl]: https://www.libressl.org/
271
272
273 ## <a id="rest"></a> Restoring From An Encrypted Backup
274
--- www/backup.md
+++ www/backup.md
@@ -262,12 +262,12 @@
262 than give up on the security afforded by use of configurable-iteration
263 PBKDF2. To avoid a conflict with the platform’s `openssl` binary,
264 Homebrew’s installation is [unlinked][hbul] by default, so you have to
265 give an explicit path to it, one of:
266
267 /usr/local/opt/openssl/bin/openssl ... # Intel x86 Macs
268 /opt/homebrew/opt/openssl/bin/openssl ... # ARM Macs (“Apple silicon”)
269
270 [lssl]: https://www.libressl.org/
271
272
273 ## <a id="rest"></a> Restoring From An Encrypted Backup
274
--- www/ckout-workflows.md
+++ www/ckout-workflows.md
@@ -10,32 +10,32 @@
1010
## <a id="mcw"></a> Multiple-Checkout Workflow
1111
1212
With Fossil, it is routine to have multiple check-outs from the same
1313
repository:
1414
15
- fossil clone https://example.com/repo /path/to/repo.fossil
16
-
17
- mkdir -p ~/src/my-project/trunk
18
- cd ~/src/my-project/trunk
19
- fossil open /path/to/repo.fossil # implicitly opens “trunk”
20
-
21
- mkdir ../release
22
- cd ../release
23
- fossil open /path/to/repo.fossil release
24
-
25
- mkdir ../my-other-branch
26
- cd ../my-other-branch
27
- fossil open /path/to/repo.fossil my-other-branch
28
-
29
- mkdir ../scratch
30
- cd ../scratch
31
- fossil open /path/to/repo.fossil abcd1234
32
-
33
- mkdir ../test
34
- cd ../test
35
- fossil open /path/to/repo.fossil 2019-04-01
36
-
15
+ fossil clone https://example.com/repo /path/to/repo.fossil
16
+
17
+ mkdir -p ~/src/my-project/trunk
18
+ cd ~/src/my-project/trunk
19
+ fossil open /path/to/repo.fossil # implicitly opens “trunk”
20
+
21
+ mkdir ../release
22
+ cd ../release
23
+ fossil open /path/to/repo.fossil release
24
+
25
+ mkdir ../my-other-branch
26
+ cd ../my-other-branch
27
+ fossil open /path/to/repo.fossil my-other-branch
28
+
29
+ mkdir ../scratch
30
+ cd ../scratch
31
+ fossil open /path/to/repo.fossil abcd1234
32
+
33
+ mkdir ../test
34
+ cd ../test
35
+ fossil open /path/to/repo.fossil 2019-04-01
36
+
3737
Now you have five separate check-out directories: one each for:
3838
3939
* trunk
4040
* the latest tagged public release
4141
* an alternate branch you’re working on
@@ -73,18 +73,18 @@
7373
7474
#### <a id="idiomatic"></a> The Idiomatic Fossil Way
7575
7676
The most idiomatic way is as follows:
7777
78
- fossil clone https://example.com/repo /path/to/repo.fossil
79
- mkdir work-dir
80
- cd work-dir
81
- fossil open /path/to/repo.fossil
82
- ...work on trunk...
83
-
84
- fossil update my-other-branch
85
- ...work on your other branch in the same directory...
78
+ fossil clone https://example.com/repo /path/to/repo.fossil
79
+ mkdir work-dir
80
+ cd work-dir
81
+ fossil open /path/to/repo.fossil
82
+ ...work on trunk...
83
+
84
+ fossil update my-other-branch
85
+ ...work on your other branch in the same directory...
8686
8787
Basically, you replace the `cd` commands in the multiple checkouts
8888
workflow above with `fossil up` commands.
8989
9090
@@ -91,13 +91,13 @@
9191
#### <a id="open"></a> Opening a Repository by URI
9292
9393
In Fossil 2.12, we added a feature to simplify the single-worktree use
9494
case:
9595
96
- mkdir work-dir
97
- cd work-dir
98
- fossil open https://example.com/repo
96
+ mkdir work-dir
97
+ cd work-dir
98
+ fossil open https://example.com/repo
9999
100100
Now you have “trunk” open in `work-dir`, with the repo file stored as
101101
`repo.fossil` in that same directory.
102102
103103
Users of Git may be surprised that it doesn’t create a directory for you
@@ -111,33 +111,33 @@
111111
112112
#### <a id="clone"></a> Git-Like Clone-and-Open
113113
114114
In Fossil 2.14, we added a more Git-like alternative:
115115
116
- fossil clone https://fossil-scm.org/fossil
117
- cd fossil
116
+ fossil clone https://fossil-scm.org/fossil
117
+ cd fossil
118118
119119
This results in a `fossil.fossil` repo DB file and a `fossil/` working
120120
directory.
121121
122122
Note that our `clone URI` behavior does not commingle the repo and
123123
check-out, solving our major problem with the Git design.
124124
125125
If you want the repo to be named something else, adjust the URL:
126126
127
- fossil clone https://fossil-scm.org/fossil/fsl
127
+ fossil clone https://fossil-scm.org/fossil/fsl
128128
129129
That gets you `fsl.fossil` checked out into `fsl/`.
130130
131131
For sites where the repo isn’t served from a subdirectory like this, you
132132
might need another form of the URL. For example, you might have your
133133
repo served from `dev.example.com` and want it cloned as `my-project`:
134134
135
- fossil clone https://dev.example.com/repo/my-project
135
+ fossil clone https://dev.example.com/repo/my-project
136136
137137
The `/repo` addition is the key: whatever comes after is used as the
138138
repository name. [See the docs][clone] for more details.
139139
140140
[caod]: https://fossil-scm.org/forum/forumpost/3f143cec74
141141
[clone]: /help?cmd=clone
142142
143143
<div style="height:50em" id="this-space-intentionally-left-blank"></div>
144144
--- www/ckout-workflows.md
+++ www/ckout-workflows.md
@@ -10,32 +10,32 @@
10 ## <a id="mcw"></a> Multiple-Checkout Workflow
11
12 With Fossil, it is routine to have multiple check-outs from the same
13 repository:
14
15 fossil clone https://example.com/repo /path/to/repo.fossil
16
17 mkdir -p ~/src/my-project/trunk
18 cd ~/src/my-project/trunk
19 fossil open /path/to/repo.fossil # implicitly opens “trunk”
20
21 mkdir ../release
22 cd ../release
23 fossil open /path/to/repo.fossil release
24
25 mkdir ../my-other-branch
26 cd ../my-other-branch
27 fossil open /path/to/repo.fossil my-other-branch
28
29 mkdir ../scratch
30 cd ../scratch
31 fossil open /path/to/repo.fossil abcd1234
32
33 mkdir ../test
34 cd ../test
35 fossil open /path/to/repo.fossil 2019-04-01
36
37 Now you have five separate check-out directories: one each for:
38
39 * trunk
40 * the latest tagged public release
41 * an alternate branch you’re working on
@@ -73,18 +73,18 @@
73
74 #### <a id="idiomatic"></a> The Idiomatic Fossil Way
75
76 The most idiomatic way is as follows:
77
78 fossil clone https://example.com/repo /path/to/repo.fossil
79 mkdir work-dir
80 cd work-dir
81 fossil open /path/to/repo.fossil
82 ...work on trunk...
83
84 fossil update my-other-branch
85 ...work on your other branch in the same directory...
86
87 Basically, you replace the `cd` commands in the multiple checkouts
88 workflow above with `fossil up` commands.
89
90
@@ -91,13 +91,13 @@
91 #### <a id="open"></a> Opening a Repository by URI
92
93 In Fossil 2.12, we added a feature to simplify the single-worktree use
94 case:
95
96 mkdir work-dir
97 cd work-dir
98 fossil open https://example.com/repo
99
100 Now you have “trunk” open in `work-dir`, with the repo file stored as
101 `repo.fossil` in that same directory.
102
103 Users of Git may be surprised that it doesn’t create a directory for you
@@ -111,33 +111,33 @@
111
112 #### <a id="clone"></a> Git-Like Clone-and-Open
113
114 In Fossil 2.14, we added a more Git-like alternative:
115
116 fossil clone https://fossil-scm.org/fossil
117 cd fossil
118
119 This results in a `fossil.fossil` repo DB file and a `fossil/` working
120 directory.
121
122 Note that our `clone URI` behavior does not commingle the repo and
123 check-out, solving our major problem with the Git design.
124
125 If you want the repo to be named something else, adjust the URL:
126
127 fossil clone https://fossil-scm.org/fossil/fsl
128
129 That gets you `fsl.fossil` checked out into `fsl/`.
130
131 For sites where the repo isn’t served from a subdirectory like this, you
132 might need another form of the URL. For example, you might have your
133 repo served from `dev.example.com` and want it cloned as `my-project`:
134
135 fossil clone https://dev.example.com/repo/my-project
136
137 The `/repo` addition is the key: whatever comes after is used as the
138 repository name. [See the docs][clone] for more details.
139
140 [caod]: https://fossil-scm.org/forum/forumpost/3f143cec74
141 [clone]: /help?cmd=clone
142
143 <div style="height:50em" id="this-space-intentionally-left-blank"></div>
144
--- www/ckout-workflows.md
+++ www/ckout-workflows.md
@@ -10,32 +10,32 @@
10 ## <a id="mcw"></a> Multiple-Checkout Workflow
11
12 With Fossil, it is routine to have multiple check-outs from the same
13 repository:
14
15 fossil clone https://example.com/repo /path/to/repo.fossil
16
17 mkdir -p ~/src/my-project/trunk
18 cd ~/src/my-project/trunk
19 fossil open /path/to/repo.fossil # implicitly opens “trunk”
20
21 mkdir ../release
22 cd ../release
23 fossil open /path/to/repo.fossil release
24
25 mkdir ../my-other-branch
26 cd ../my-other-branch
27 fossil open /path/to/repo.fossil my-other-branch
28
29 mkdir ../scratch
30 cd ../scratch
31 fossil open /path/to/repo.fossil abcd1234
32
33 mkdir ../test
34 cd ../test
35 fossil open /path/to/repo.fossil 2019-04-01
36
37 Now you have five separate check-out directories: one each for:
38
39 * trunk
40 * the latest tagged public release
41 * an alternate branch you’re working on
@@ -73,18 +73,18 @@
73
74 #### <a id="idiomatic"></a> The Idiomatic Fossil Way
75
76 The most idiomatic way is as follows:
77
78 fossil clone https://example.com/repo /path/to/repo.fossil
79 mkdir work-dir
80 cd work-dir
81 fossil open /path/to/repo.fossil
82 ...work on trunk...
83
84 fossil update my-other-branch
85 ...work on your other branch in the same directory...
86
87 Basically, you replace the `cd` commands in the multiple checkouts
88 workflow above with `fossil up` commands.
89
90
@@ -91,13 +91,13 @@
91 #### <a id="open"></a> Opening a Repository by URI
92
93 In Fossil 2.12, we added a feature to simplify the single-worktree use
94 case:
95
96 mkdir work-dir
97 cd work-dir
98 fossil open https://example.com/repo
99
100 Now you have “trunk” open in `work-dir`, with the repo file stored as
101 `repo.fossil` in that same directory.
102
103 Users of Git may be surprised that it doesn’t create a directory for you
@@ -111,33 +111,33 @@
111
112 #### <a id="clone"></a> Git-Like Clone-and-Open
113
114 In Fossil 2.14, we added a more Git-like alternative:
115
116 fossil clone https://fossil-scm.org/fossil
117 cd fossil
118
119 This results in a `fossil.fossil` repo DB file and a `fossil/` working
120 directory.
121
122 Note that our `clone URI` behavior does not commingle the repo and
123 check-out, solving our major problem with the Git design.
124
125 If you want the repo to be named something else, adjust the URL:
126
127 fossil clone https://fossil-scm.org/fossil/fsl
128
129 That gets you `fsl.fossil` checked out into `fsl/`.
130
131 For sites where the repo isn’t served from a subdirectory like this, you
132 might need another form of the URL. For example, you might have your
133 repo served from `dev.example.com` and want it cloned as `my-project`:
134
135 fossil clone https://dev.example.com/repo/my-project
136
137 The `/repo` addition is the key: whatever comes after is used as the
138 repository name. [See the docs][clone] for more details.
139
140 [caod]: https://fossil-scm.org/forum/forumpost/3f143cec74
141 [clone]: /help?cmd=clone
142
143 <div style="height:50em" id="this-space-intentionally-left-blank"></div>
144
+106 -166
--- www/containers.md
+++ www/containers.md
@@ -13,20 +13,16 @@
1313
## 1. Quick Start
1414
1515
Fossil ships a `Dockerfile` at the top of its source tree,
1616
[here][DF], which you can build like so:
1717
18
-```
19
- $ docker build -t fossil .
20
-```
18
+ $ docker build -t fossil .
2119
2220
If the image built successfully, you can create a container from it and
2321
test that it runs:
2422
25
-```
26
- $ docker run --name fossil -p 9999:8080/tcp fossil
27
-```
23
+ $ docker run --name fossil -p 9999:8080/tcp fossil
2824
2925
This shows us remapping the internal TCP listening port as 9999 on the
3026
host. This feature of OCI runtimes means there’s little point to using
3127
the “`fossil server --port`” feature inside the container. We can let
3228
Fossil default to 8080 internally, then remap it to wherever we want it
@@ -44,13 +40,11 @@
4440
with the `DCFLAGS` variable. (DB is short for “`docker build`”, and DC
4541
is short for “`docker create`”, a sub-step of the “run” target.)
4642
To get the custom port setting as in
4743
second command above, say:
4844
49
-```
50
- $ make container-run DCFLAGS='-p 9999:8080/tcp'
51
-```
45
+ $ make container-run DCFLAGS='-p 9999:8080/tcp'
5246
5347
Contrast the raw “`docker`” commands above, which create an
5448
_unversioned_ image called `fossil:latest` and from that a container
5549
simply called `fossil`. The unversioned names are more convenient for
5650
interactive use, while the versioned ones are good for CI/CD type
@@ -81,15 +75,13 @@
8175
### <a id="repo-inside"></a> 2.1 Storing the Repo Inside the Container
8276
8377
The simplest method is to stop the container if it was running, then
8478
say:
8579
86
-```
87
- $ docker cp /path/to/my-project.fossil fossil:/museum/repo.fossil
88
- $ docker start fossil
89
- $ docker exec fossil chown -R 499 /museum
90
-```
80
+ $ docker cp /path/to/my-project.fossil fossil:/museum/repo.fossil
81
+ $ docker start fossil
82
+ $ docker exec fossil chown -R 499 /museum
9183
9284
That copies the local Fossil repo into the container where the server
9385
expects to find it, so that the “start” command causes it to serve from
9486
that copied-in file instead. Since it lives atop the immutable base
9587
layers, it persists as part of the container proper, surviving restarts.
@@ -120,17 +112,15 @@
120112
designed to be killed off at the slightest cause, rebuilt, and
121113
redeployed. If you do that with the repo inside the container, it gets
122114
destroyed, too. The solution is to replace the “run” command above with
123115
the following:
124116
125
-```
126
- $ docker run \
127
- --publish 9999:8080 \
128
- --name fossil-bind-mount \
129
- --volume ~/museum:/museum \
130
- fossil
131
-```
117
+ $ docker run \
118
+ --publish 9999:8080 \
119
+ --name fossil-bind-mount \
120
+ --volume ~/museum:/museum \
121
+ fossil
132122
133123
Because this bind mount maps a host-side directory (`~/museum`) into the
134124
container, you don’t need to `docker cp` the repo into the container at
135125
all. It still expects to find the repository as `repo.fossil` under that
136126
directory, but now both the host and the container can see that repo DB.
@@ -151,13 +141,11 @@
151141
You might be aware that OCI containers allow mapping a single file into
152142
the repository rather than a whole directory. Since Fossil repositories
153143
are specially-formatted SQLite databases, you might be wondering why we
154144
don’t say things like:
155145
156
-```
157
- --volume ~/museum/my-project.fossil:/museum/repo.fossil
158
-```
146
+ --volume ~/museum/my-project.fossil:/museum/repo.fossil
159147
160148
That lets us have a convenient file name for the project outside the
161149
container while letting the configuration inside the container refer to
162150
the generic “`/museum/repo.fossil`” name. Why should we have to name
163151
the repo generically on the outside merely to placate the container?
@@ -292,21 +280,19 @@
292280
293281
All together, we recommend adding the following options to your
294282
“`docker run`” commands, as well as to any “`docker create`” command
295283
that will be followed by “`docker start`”:
296284
297
-```
298
- --cap-drop AUDIT_WRITE \
299
- --cap-drop CHOWN \
300
- --cap-drop FSETID \
301
- --cap-drop KILL \
302
- --cap-drop MKNOD \
303
- --cap-drop NET_BIND_SERVICE \
304
- --cap-drop NET_RAW \
305
- --cap-drop SETFCAP \
306
- --cap-drop SETPCAP
307
-```
285
+ --cap-drop AUDIT_WRITE \
286
+ --cap-drop CHOWN \
287
+ --cap-drop FSETID \
288
+ --cap-drop KILL \
289
+ --cap-drop MKNOD \
290
+ --cap-drop NET_BIND_SERVICE \
291
+ --cap-drop NET_RAW \
292
+ --cap-drop SETFCAP \
293
+ --cap-drop SETPCAP
308294
309295
In the next section, we’ll show a case where you create a container
310296
without ever running it, making these options pointless.
311297
312298
[backoffice]: ./backoffice.md
@@ -326,16 +312,14 @@
326312
modern Linux distros make this [surprisingly difficult][lsl], but Alpine’s
327313
back-to-basics nature makes static builds work the way they used to,
328314
back in the day. If that’s all you’re after, you can do so as easily as
329315
this:
330316
331
-```
332
- $ docker build -t fossil .
333
- $ docker create --name fossil-static-tmp fossil
334
- $ docker cp fossil-static-tmp:/bin/fossil .
335
- $ docker container rm fossil-static-tmp
336
-```
317
+ $ docker build -t fossil .
318
+ $ docker create --name fossil-static-tmp fossil
319
+ $ docker cp fossil-static-tmp:/bin/fossil .
320
+ $ docker container rm fossil-static-tmp
337321
338322
The result is six or seven megs, depending on the CPU architecture you
339323
build for. It’s built stripped.
340324
341325
[lsl]: https://stackoverflow.com/questions/3430400/linux-static-linking-is-dead
@@ -347,19 +331,15 @@
347331
348332
The default version of Fossil fetched in the build is the version in the
349333
checkout directory at the time you run it. You could override it to get
350334
a release build like so:
351335
352
-```
353
- $ docker build -t fossil --build-arg FSLVER=version-2.20 .
354
-```
336
+ $ docker build -t fossil --build-arg FSLVER=version-2.20 .
355337
356338
Or equivalently, using Fossil’s `Makefile` convenience target:
357339
358
-```
359
- $ make container-image DBFLAGS='--build-arg FSLVER=version-2.20'
360
-```
340
+ $ make container-image DBFLAGS='--build-arg FSLVER=version-2.20'
361341
362342
While you could instead use the generic
363343
“`release`” tag here, it’s better to use a specific version number
364344
since container builders cache downloaded files, hoping to
365345
reuse them across builds. If you ask for “`release`” before a new
@@ -384,13 +364,11 @@
384364
500 and went *down* one instead to reduce the chance of a conflict to as
385365
close to zero as we can manage.
386366
387367
To change it to something else, say:
388368
389
-```
390
- $ make container-image DBFLAGS='--build-arg UID=501'
391
-```
369
+ $ make container-image DBFLAGS='--build-arg UID=501'
392370
393371
This is particularly useful if you’re putting your repository on a
394372
separate volume since the IDs “leak” out into the host environment via
395373
file permissions. You may therefore wish them to mean something on both
396374
sides of the container barrier rather than have “499” appear on the host
@@ -403,25 +381,21 @@
403381
for use of any OCI container system that implements the same interfaces.
404382
We go into more details about this [below](#light), but
405383
for now, it suffices to point out that you can switch to Podman while
406384
using our `Makefile` convenience targets unchanged by saying:
407385
408
-```
409386
$ make CENGINE=podman container-run
410
-```
411387
412388
413389
### 5.4 <a id="config"></a>Fossil Configuration Options
414390
415391
You can use this same mechanism to enable non-default Fossil
416392
configuration options in your build. For instance, to turn on
417393
the JSON API and the TH1 docs extension:
418394
419
-```
420
- $ make container-image \
421
- DBFLAGS='--build-arg FSLCFG="--json --with-th1-docs"'
422
-```
395
+ $ make container-image \
396
+ DBFLAGS='--build-arg FSLCFG="--json --with-th1-docs"'
423397
424398
If you also wanted [the Tcl evaluation extension](./th1.md#tclEval),
425399
that brings us to [the next point](#run).
426400
427401
@@ -429,20 +403,20 @@
429403
430404
If you want a basic shell environment for temporary debugging of the
431405
running container, that’s easily added. Simply change this line in the
432406
`Dockerfile`…
433407
434
- FROM scratch AS run
408
+ FROM scratch AS run
435409
436410
…to this:
437411
438
- FROM busybox AS run
412
+ FROM busybox AS run
439413
440414
Rebuild and redeploy to give your Fossil container a [BusyBox]-based
441415
shell environment that you can get into via:
442416
443
- $ docker exec -it -u fossil $(make container-version) sh
417
+ $ docker exec -it -u fossil $(make container-version) sh
444418
445419
That command assumes you built it via “`make container`” and are
446420
therefore using its versioning scheme.
447421
448422
You will likely want to remove the `PATH` override in the “RUN” stage
@@ -463,11 +437,10 @@
463437
most popular programming languages in the world, we have many options
464438
for achieving this. For instance, there is a whole class of
465439
“[distroless]” images that will do this efficiently by changing
466440
“`STAGE 2`” in the `Dockefile` to this:
467441
468
-```
469442
## ---------------------------------------------------------------------
470443
## STAGE 2: Pare that back to the bare essentials, plus Python.
471444
## ---------------------------------------------------------------------
472445
FROM cgr.dev/chainguard/python:latest
473446
USER root
@@ -478,24 +451,21 @@
478451
RUN [ "/bin/busybox", "--install", "/bin" ]
479452
RUN set -x \
480453
&& echo "fossil:x:${UID}:${UID}:User:/museum:/false" >> /etc/passwd \
481454
&& echo "fossil:x:${UID}:fossil" >> /etc/group \
482455
&& install -d -m 700 -o fossil -g fossil log museum
483
-```
484456
485457
You will also have to add `busybox-static` to the APK package list in
486458
STAGE 1 for the `RUN` script at the end of that stage to work, since the
487459
[Chainguard Python image][cgimgs] lacks a shell, on purpose. The need to
488460
install root-level binaries is why we change `USER` temporarily here.
489461
490462
Build it and test that it works like so:
491463
492
-```
493464
$ make container-run &&
494465
docker exec -i $(make container-version) python --version
495466
3.11.2
496
-```
497467
498468
The compensation for the hassle of using Chainguard over something more
499469
general purpose like changing the `run` layer to Alpine and then adding
500470
a “`apk add python`” command to the `Dockerfile`
501471
is huge: we no longer leave a package manager sitting around inside the
@@ -555,11 +525,10 @@
555525
into this, [enable linger
556526
mode](https://www.freedesktop.org/software/systemd/man/loginctl.html).)
557527
so I was able to create a unit file called
558528
`~/.local/share/systemd/user/[email protected]` with these contents:
559529
560
-```
561530
[Unit]
562531
Description=Fossil email alert sender for %I
563532
564533
[Service]
565534
WorkingDirectory=/home/fossil/museum
@@ -567,20 +536,17 @@
567536
Restart=always
568537
RestartSec=3
569538
570539
[Install]
571540
WantedBy=default.target
572
-```
573541
574542
I was then able to enable email alert forwarding for select repositories
575543
after configuring them per [the docs](./alerts.md) by saying:
576544
577
-```
578545
$ systemctl --user daemon-reload
579546
$ systemctl --user enable alert-sender@myproject
580547
$ systemctl --user start alert-sender@myproject
581
-```
582548
583549
Because this is a parameterized script and we’ve set our repository
584550
paths predictably, you can do this for as many repositories as you need
585551
to by passing their names after the “`@`” sign in the commands above.
586552
@@ -606,13 +572,11 @@
606572
For the sake of simple examples in this section, we’ll assume you’re
607573
integrating Fossil into a larger web site, such as with our [Debian +
608574
nginx + TLS][DNT] plan. This is why all of the examples below create
609575
the container with this option:
610576
611
-```
612
- --publish 127.0.0.1:9999:8080
613
-```
577
+ --publish 127.0.0.1:9999:8080
614578
615579
The assumption is that there’s a reverse proxy running somewhere that
616580
redirects public web hits to localhost port 9999, which in turn goes to
617581
port 8080 inside the container. This use of port
618582
publishing effectively replaces the use of the
@@ -678,14 +642,12 @@
678642
tenth the size of Docker Engine.
679643
680644
For our purposes here, the only thing that changes relative to the
681645
examples at the top of this document are the initial command:
682646
683
-```
684
- $ podman build -t fossil .
685
- $ podman run --name fossil -p 9999:8080/tcp fossil
686
-```
647
+ $ podman build -t fossil .
648
+ $ podman run --name fossil -p 9999:8080/tcp fossil
687649
688650
Your Linux package repo may have a `podman-docker` package which
689651
provides a “`docker`” script that calls “`podman`” for you, eliminating
690652
even the command name difference. With that installed, the `make`
691653
commands above will work with Podman as-is.
@@ -692,23 +654,21 @@
692654
693655
The only difference that matters here is that Podman doesn’t have the
694656
same [default Linux kernel capability set](#caps) as Docker, which
695657
affects the `--cap-drop` flags recommended above to:
696658
697
-```
698
- $ podman create \
699
- --name fossil \
700
- --cap-drop CHOWN \
701
- --cap-drop FSETID \
702
- --cap-drop KILL \
703
- --cap-drop NET_BIND_SERVICE \
704
- --cap-drop SETFCAP \
705
- --cap-drop SETPCAP \
706
- --publish 127.0.0.1:9999:8080 \
707
- localhost/fossil
708
- $ podman start fossil
709
-```
659
+ $ podman create \
660
+ --name fossil \
661
+ --cap-drop CHOWN \
662
+ --cap-drop FSETID \
663
+ --cap-drop KILL \
664
+ --cap-drop NET_BIND_SERVICE \
665
+ --cap-drop SETFCAP \
666
+ --cap-drop SETPCAP \
667
+ --publish 127.0.0.1:9999:8080 \
668
+ localhost/fossil
669
+ $ podman start fossil
710670
711671
[pmmac]: https://podman.io/getting-started/installation.html#macos
712672
[pmwin]: https://github.com/containers/podman/blob/main/docs/tutorials/podman-for-windows.md
713673
[Podman]: https://podman.io/
714674
[rl]: https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md
@@ -720,13 +680,11 @@
720680
If even the Podman stack is too big for you, the next-best option I’m
721681
aware of is the `systemd-container` infrastructure on modern Linuxes,
722682
available since version 239 or so. Its runtime tooling requires only
723683
about 1.4 MiB of disk space:
724684
725
-```
726
- $ sudo apt install systemd-container btrfs-tools
727
-```
685
+ $ sudo apt install systemd-container btrfs-tools
728686
729687
That command assumes the primary test environment for
730688
this guide, Ubuntu 22.04 LTS with `systemd` 249. For best
731689
results, `/var/lib/machines` should be a btrfs volume, because
732690
[`$REASONS`][mcfad]. For CentOS Stream 9 and other Red Hattish
@@ -742,60 +700,54 @@
742700
If you use [the stock `Dockerfile`][DF] to generate your
743701
base image, `nspawn` won’t recognize it as containing an OS unless you
744702
change the “`FROM scratch AS os`” line at the top of the second stage
745703
to something like this:
746704
747
-```
748
- FROM gcr.io/distroless/static-debian11 AS os
749
-```
705
+ FROM gcr.io/distroless/static-debian11 AS os
750706
751707
Using that as a base image provides all the files `nspawn` checks for to
752708
determine whether the container is sufficiently close to a Linux VM for
753709
the following step to proceed:
754710
755
-```
756
- $ make container
757
- $ docker container export $(make container-version) |
758
- machinectl import-tar - myproject
759
-```
711
+ $ make container
712
+ $ docker container export $(make container-version) |
713
+ machinectl import-tar - myproject
760714
761715
Next, create `/etc/systemd/nspawn/myproject.nspawn`:
762716
763717
----
764718
765
-```
766
-[Exec]
767
-WorkingDirectory=/
768
-Parameters=bin/fossil server \
769
- --baseurl https://example.com/myproject \
770
- --create \
771
- --jsmode bundled \
772
- --localhost \
773
- --port 9000 \
774
- --scgi \
775
- --user admin \
776
- museum/repo.fossil
777
-DropCapability= \
778
- CAP_AUDIT_WRITE \
779
- CAP_CHOWN \
780
- CAP_FSETID \
781
- CAP_KILL \
782
- CAP_MKNOD \
783
- CAP_NET_BIND_SERVICE \
784
- CAP_NET_RAW \
785
- CAP_SETFCAP \
786
- CAP_SETPCAP
787
-ProcessTwo=yes
788
-LinkJournal=no
789
-Timezone=no
790
-
791
-[Files]
792
-Bind=/home/fossil/museum/myproject:/museum
793
-
794
-[Network]
795
-VirtualEthernet=no
796
-```
719
+ [Exec]
720
+ WorkingDirectory=/
721
+ Parameters=bin/fossil server \
722
+ --baseurl https://example.com/myproject \
723
+ --create \
724
+ --jsmode bundled \
725
+ --localhost \
726
+ --port 9000 \
727
+ --scgi \
728
+ --user admin \
729
+ museum/repo.fossil
730
+ DropCapability= \
731
+ CAP_AUDIT_WRITE \
732
+ CAP_CHOWN \
733
+ CAP_FSETID \
734
+ CAP_KILL \
735
+ CAP_MKNOD \
736
+ CAP_NET_BIND_SERVICE \
737
+ CAP_NET_RAW \
738
+ CAP_SETFCAP \
739
+ CAP_SETPCAP
740
+ ProcessTwo=yes
741
+ LinkJournal=no
742
+ Timezone=no
743
+
744
+ [Files]
745
+ Bind=/home/fossil/museum/myproject:/museum
746
+
747
+ [Network]
748
+ VirtualEthernet=no
797749
798750
----
799751
800752
If you recognize most of that from the `Dockerfile` discussion above,
801753
congratulations, you’ve been paying attention. The rest should also
@@ -819,22 +771,20 @@
819771
That being done, we also need a generic `systemd` unit file called
820772
`/etc/systemd/system/[email protected]`, containing:
821773
822774
----
823775
824
-```
825
-[Unit]
826
-Description=Fossil %i Repo Service
827
-[email protected] [email protected]
828
-After=network.target systemd-resolved.service [email protected] [email protected]
829
-
830
-[Service]
831
-ExecStart=systemd-nspawn --settings=override --read-only --machine=%i bin/fossil
832
-
833
-[Install]
834
-WantedBy=multi-user.target
835
-```
776
+ [Unit]
777
+ Description=Fossil %i Repo Service
778
+ [email protected] [email protected]
779
+ After=network.target systemd-resolved.service [email protected] [email protected]
780
+
781
+ [Service]
782
+ ExecStart=systemd-nspawn --settings=override --read-only --machine=%i bin/fossil
783
+
784
+ [Install]
785
+ WantedBy=multi-user.target
836786
837787
----
838788
839789
You shouldn’t have to change any of this because we’ve given the
840790
`--setting=override` flag, meaning any setting in the nspawn file
@@ -843,42 +793,36 @@
843793
share the base configuration, varying on a per-repo level through
844794
adjustments to their individual `*.nspawn` files.
845795
846796
You may then start the service in the normal way:
847797
848
-```
849
- $ sudo systemctl enable fossil@myproject
850
- $ sudo systemctl start fossil@myproject
851
-```
798
+ $ sudo systemctl enable fossil@myproject
799
+ $ sudo systemctl start fossil@myproject
852800
853801
You should then find it running on localhost port 9000 per the nspawn
854802
configuration file above, suitable for proxying Fossil out to the
855803
public using nginx via SCGI. If you aren’t using a front-end proxy
856804
and want Fossil exposed to the world via HTTPS, you might say this instead in
857805
the `*.nspawn` file:
858806
859
-```
860
-Parameters=bin/fossil server \
861
- --cert /path/to/cert.pem \
862
- --create \
863
- --jsmode bundled \
864
- --port 443 \
865
- --user admin \
866
- museum/repo.fossil
867
-```
807
+ Parameters=bin/fossil server \
808
+ --cert /path/to/cert.pem \
809
+ --create \
810
+ --jsmode bundled \
811
+ --port 443 \
812
+ --user admin \
813
+ museum/repo.fossil
868814
869815
You would also need to un-drop the `CAP_NET_BIND_SERVICE` capability
870816
to allow Fossil to bind to this low-numbered port.
871817
872818
We use the `systemd` template file feature to allow multiple Fossil
873819
servers running on a single machine, each on a different TCP port,
874820
as when proxying them out as subdirectories of a larger site.
875821
To add another project, you must first clone the base “machine” layer:
876822
877
-```
878
- $ sudo machinectl clone myproject otherthing
879
-```
823
+ $ sudo machinectl clone myproject otherthing
880824
881825
That will not only create a clone of `/var/lib/machines/myproject`
882826
as `../otherthing`, it will create a matching `otherthing.nspawn` file for you
883827
as a copy of the first one. Adjust its contents to suit, then enable
884828
and start it as above.
@@ -895,21 +839,17 @@
895839
896840
Fortunately, there are workarounds.
897841
898842
First, the `apt install` command above becomes:
899843
900
-```
901
- $ sudo dnf install systemd-container
902
-```
844
+ $ sudo dnf install systemd-container
903845
904846
Second, you have to hack around the lack of `machinectl import-tar`:
905847
906
-```
907
- $ rootfs=/var/lib/machines/fossil
908
- $ sudo mkdir -p $rootfs
909
- $ docker container export fossil | sudo tar -xf -C $rootfs -
910
-```
848
+ $ rootfs=/var/lib/machines/fossil
849
+ $ sudo mkdir -p $rootfs
850
+ $ docker container export fossil | sudo tar -xf -C $rootfs -
911851
912852
The parent directory path in the `rootfs` variable is important,
913853
because although we aren’t able to use `machinectl` on such systems, the
914854
`systemd-nspawn` developers assume you’re using them together; when you give
915855
`--machine`, it assumes the `machinectl` directory scheme. You could
916856
--- www/containers.md
+++ www/containers.md
@@ -13,20 +13,16 @@
13 ## 1. Quick Start
14
15 Fossil ships a `Dockerfile` at the top of its source tree,
16 [here][DF], which you can build like so:
17
18 ```
19 $ docker build -t fossil .
20 ```
21
22 If the image built successfully, you can create a container from it and
23 test that it runs:
24
25 ```
26 $ docker run --name fossil -p 9999:8080/tcp fossil
27 ```
28
29 This shows us remapping the internal TCP listening port as 9999 on the
30 host. This feature of OCI runtimes means there’s little point to using
31 the “`fossil server --port`” feature inside the container. We can let
32 Fossil default to 8080 internally, then remap it to wherever we want it
@@ -44,13 +40,11 @@
44 with the `DCFLAGS` variable. (DB is short for “`docker build`”, and DC
45 is short for “`docker create`”, a sub-step of the “run” target.)
46 To get the custom port setting as in
47 second command above, say:
48
49 ```
50 $ make container-run DCFLAGS='-p 9999:8080/tcp'
51 ```
52
53 Contrast the raw “`docker`” commands above, which create an
54 _unversioned_ image called `fossil:latest` and from that a container
55 simply called `fossil`. The unversioned names are more convenient for
56 interactive use, while the versioned ones are good for CI/CD type
@@ -81,15 +75,13 @@
81 ### <a id="repo-inside"></a> 2.1 Storing the Repo Inside the Container
82
83 The simplest method is to stop the container if it was running, then
84 say:
85
86 ```
87 $ docker cp /path/to/my-project.fossil fossil:/museum/repo.fossil
88 $ docker start fossil
89 $ docker exec fossil chown -R 499 /museum
90 ```
91
92 That copies the local Fossil repo into the container where the server
93 expects to find it, so that the “start” command causes it to serve from
94 that copied-in file instead. Since it lives atop the immutable base
95 layers, it persists as part of the container proper, surviving restarts.
@@ -120,17 +112,15 @@
120 designed to be killed off at the slightest cause, rebuilt, and
121 redeployed. If you do that with the repo inside the container, it gets
122 destroyed, too. The solution is to replace the “run” command above with
123 the following:
124
125 ```
126 $ docker run \
127 --publish 9999:8080 \
128 --name fossil-bind-mount \
129 --volume ~/museum:/museum \
130 fossil
131 ```
132
133 Because this bind mount maps a host-side directory (`~/museum`) into the
134 container, you don’t need to `docker cp` the repo into the container at
135 all. It still expects to find the repository as `repo.fossil` under that
136 directory, but now both the host and the container can see that repo DB.
@@ -151,13 +141,11 @@
151 You might be aware that OCI containers allow mapping a single file into
152 the repository rather than a whole directory. Since Fossil repositories
153 are specially-formatted SQLite databases, you might be wondering why we
154 don’t say things like:
155
156 ```
157 --volume ~/museum/my-project.fossil:/museum/repo.fossil
158 ```
159
160 That lets us have a convenient file name for the project outside the
161 container while letting the configuration inside the container refer to
162 the generic “`/museum/repo.fossil`” name. Why should we have to name
163 the repo generically on the outside merely to placate the container?
@@ -292,21 +280,19 @@
292
293 All together, we recommend adding the following options to your
294 “`docker run`” commands, as well as to any “`docker create`” command
295 that will be followed by “`docker start`”:
296
297 ```
298 --cap-drop AUDIT_WRITE \
299 --cap-drop CHOWN \
300 --cap-drop FSETID \
301 --cap-drop KILL \
302 --cap-drop MKNOD \
303 --cap-drop NET_BIND_SERVICE \
304 --cap-drop NET_RAW \
305 --cap-drop SETFCAP \
306 --cap-drop SETPCAP
307 ```
308
309 In the next section, we’ll show a case where you create a container
310 without ever running it, making these options pointless.
311
312 [backoffice]: ./backoffice.md
@@ -326,16 +312,14 @@
326 modern Linux distros make this [surprisingly difficult][lsl], but Alpine’s
327 back-to-basics nature makes static builds work the way they used to,
328 back in the day. If that’s all you’re after, you can do so as easily as
329 this:
330
331 ```
332 $ docker build -t fossil .
333 $ docker create --name fossil-static-tmp fossil
334 $ docker cp fossil-static-tmp:/bin/fossil .
335 $ docker container rm fossil-static-tmp
336 ```
337
338 The result is six or seven megs, depending on the CPU architecture you
339 build for. It’s built stripped.
340
341 [lsl]: https://stackoverflow.com/questions/3430400/linux-static-linking-is-dead
@@ -347,19 +331,15 @@
347
348 The default version of Fossil fetched in the build is the version in the
349 checkout directory at the time you run it. You could override it to get
350 a release build like so:
351
352 ```
353 $ docker build -t fossil --build-arg FSLVER=version-2.20 .
354 ```
355
356 Or equivalently, using Fossil’s `Makefile` convenience target:
357
358 ```
359 $ make container-image DBFLAGS='--build-arg FSLVER=version-2.20'
360 ```
361
362 While you could instead use the generic
363 “`release`” tag here, it’s better to use a specific version number
364 since container builders cache downloaded files, hoping to
365 reuse them across builds. If you ask for “`release`” before a new
@@ -384,13 +364,11 @@
384 500 and went *down* one instead to reduce the chance of a conflict to as
385 close to zero as we can manage.
386
387 To change it to something else, say:
388
389 ```
390 $ make container-image DBFLAGS='--build-arg UID=501'
391 ```
392
393 This is particularly useful if you’re putting your repository on a
394 separate volume since the IDs “leak” out into the host environment via
395 file permissions. You may therefore wish them to mean something on both
396 sides of the container barrier rather than have “499” appear on the host
@@ -403,25 +381,21 @@
403 for use of any OCI container system that implements the same interfaces.
404 We go into more details about this [below](#light), but
405 for now, it suffices to point out that you can switch to Podman while
406 using our `Makefile` convenience targets unchanged by saying:
407
408 ```
409 $ make CENGINE=podman container-run
410 ```
411
412
413 ### 5.4 <a id="config"></a>Fossil Configuration Options
414
415 You can use this same mechanism to enable non-default Fossil
416 configuration options in your build. For instance, to turn on
417 the JSON API and the TH1 docs extension:
418
419 ```
420 $ make container-image \
421 DBFLAGS='--build-arg FSLCFG="--json --with-th1-docs"'
422 ```
423
424 If you also wanted [the Tcl evaluation extension](./th1.md#tclEval),
425 that brings us to [the next point](#run).
426
427
@@ -429,20 +403,20 @@
429
430 If you want a basic shell environment for temporary debugging of the
431 running container, that’s easily added. Simply change this line in the
432 `Dockerfile`…
433
434 FROM scratch AS run
435
436 …to this:
437
438 FROM busybox AS run
439
440 Rebuild and redeploy to give your Fossil container a [BusyBox]-based
441 shell environment that you can get into via:
442
443 $ docker exec -it -u fossil $(make container-version) sh
444
445 That command assumes you built it via “`make container`” and are
446 therefore using its versioning scheme.
447
448 You will likely want to remove the `PATH` override in the “RUN” stage
@@ -463,11 +437,10 @@
463 most popular programming languages in the world, we have many options
464 for achieving this. For instance, there is a whole class of
465 “[distroless]” images that will do this efficiently by changing
466 “`STAGE 2`” in the `Dockefile` to this:
467
468 ```
469 ## ---------------------------------------------------------------------
470 ## STAGE 2: Pare that back to the bare essentials, plus Python.
471 ## ---------------------------------------------------------------------
472 FROM cgr.dev/chainguard/python:latest
473 USER root
@@ -478,24 +451,21 @@
478 RUN [ "/bin/busybox", "--install", "/bin" ]
479 RUN set -x \
480 && echo "fossil:x:${UID}:${UID}:User:/museum:/false" >> /etc/passwd \
481 && echo "fossil:x:${UID}:fossil" >> /etc/group \
482 && install -d -m 700 -o fossil -g fossil log museum
483 ```
484
485 You will also have to add `busybox-static` to the APK package list in
486 STAGE 1 for the `RUN` script at the end of that stage to work, since the
487 [Chainguard Python image][cgimgs] lacks a shell, on purpose. The need to
488 install root-level binaries is why we change `USER` temporarily here.
489
490 Build it and test that it works like so:
491
492 ```
493 $ make container-run &&
494 docker exec -i $(make container-version) python --version
495 3.11.2
496 ```
497
498 The compensation for the hassle of using Chainguard over something more
499 general purpose like changing the `run` layer to Alpine and then adding
500 a “`apk add python`” command to the `Dockerfile`
501 is huge: we no longer leave a package manager sitting around inside the
@@ -555,11 +525,10 @@
555 into this, [enable linger
556 mode](https://www.freedesktop.org/software/systemd/man/loginctl.html).)
557 so I was able to create a unit file called
558 `~/.local/share/systemd/user/[email protected]` with these contents:
559
560 ```
561 [Unit]
562 Description=Fossil email alert sender for %I
563
564 [Service]
565 WorkingDirectory=/home/fossil/museum
@@ -567,20 +536,17 @@
567 Restart=always
568 RestartSec=3
569
570 [Install]
571 WantedBy=default.target
572 ```
573
574 I was then able to enable email alert forwarding for select repositories
575 after configuring them per [the docs](./alerts.md) by saying:
576
577 ```
578 $ systemctl --user daemon-reload
579 $ systemctl --user enable alert-sender@myproject
580 $ systemctl --user start alert-sender@myproject
581 ```
582
583 Because this is a parameterized script and we’ve set our repository
584 paths predictably, you can do this for as many repositories as you need
585 to by passing their names after the “`@`” sign in the commands above.
586
@@ -606,13 +572,11 @@
606 For the sake of simple examples in this section, we’ll assume you’re
607 integrating Fossil into a larger web site, such as with our [Debian +
608 nginx + TLS][DNT] plan. This is why all of the examples below create
609 the container with this option:
610
611 ```
612 --publish 127.0.0.1:9999:8080
613 ```
614
615 The assumption is that there’s a reverse proxy running somewhere that
616 redirects public web hits to localhost port 9999, which in turn goes to
617 port 8080 inside the container. This use of port
618 publishing effectively replaces the use of the
@@ -678,14 +642,12 @@
678 tenth the size of Docker Engine.
679
680 For our purposes here, the only thing that changes relative to the
681 examples at the top of this document are the initial command:
682
683 ```
684 $ podman build -t fossil .
685 $ podman run --name fossil -p 9999:8080/tcp fossil
686 ```
687
688 Your Linux package repo may have a `podman-docker` package which
689 provides a “`docker`” script that calls “`podman`” for you, eliminating
690 even the command name difference. With that installed, the `make`
691 commands above will work with Podman as-is.
@@ -692,23 +654,21 @@
692
693 The only difference that matters here is that Podman doesn’t have the
694 same [default Linux kernel capability set](#caps) as Docker, which
695 affects the `--cap-drop` flags recommended above to:
696
697 ```
698 $ podman create \
699 --name fossil \
700 --cap-drop CHOWN \
701 --cap-drop FSETID \
702 --cap-drop KILL \
703 --cap-drop NET_BIND_SERVICE \
704 --cap-drop SETFCAP \
705 --cap-drop SETPCAP \
706 --publish 127.0.0.1:9999:8080 \
707 localhost/fossil
708 $ podman start fossil
709 ```
710
711 [pmmac]: https://podman.io/getting-started/installation.html#macos
712 [pmwin]: https://github.com/containers/podman/blob/main/docs/tutorials/podman-for-windows.md
713 [Podman]: https://podman.io/
714 [rl]: https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md
@@ -720,13 +680,11 @@
720 If even the Podman stack is too big for you, the next-best option I’m
721 aware of is the `systemd-container` infrastructure on modern Linuxes,
722 available since version 239 or so. Its runtime tooling requires only
723 about 1.4 MiB of disk space:
724
725 ```
726 $ sudo apt install systemd-container btrfs-tools
727 ```
728
729 That command assumes the primary test environment for
730 this guide, Ubuntu 22.04 LTS with `systemd` 249. For best
731 results, `/var/lib/machines` should be a btrfs volume, because
732 [`$REASONS`][mcfad]. For CentOS Stream 9 and other Red Hattish
@@ -742,60 +700,54 @@
742 If you use [the stock `Dockerfile`][DF] to generate your
743 base image, `nspawn` won’t recognize it as containing an OS unless you
744 change the “`FROM scratch AS os`” line at the top of the second stage
745 to something like this:
746
747 ```
748 FROM gcr.io/distroless/static-debian11 AS os
749 ```
750
751 Using that as a base image provides all the files `nspawn` checks for to
752 determine whether the container is sufficiently close to a Linux VM for
753 the following step to proceed:
754
755 ```
756 $ make container
757 $ docker container export $(make container-version) |
758 machinectl import-tar - myproject
759 ```
760
761 Next, create `/etc/systemd/nspawn/myproject.nspawn`:
762
763 ----
764
765 ```
766 [Exec]
767 WorkingDirectory=/
768 Parameters=bin/fossil server \
769 --baseurl https://example.com/myproject \
770 --create \
771 --jsmode bundled \
772 --localhost \
773 --port 9000 \
774 --scgi \
775 --user admin \
776 museum/repo.fossil
777 DropCapability= \
778 CAP_AUDIT_WRITE \
779 CAP_CHOWN \
780 CAP_FSETID \
781 CAP_KILL \
782 CAP_MKNOD \
783 CAP_NET_BIND_SERVICE \
784 CAP_NET_RAW \
785 CAP_SETFCAP \
786 CAP_SETPCAP
787 ProcessTwo=yes
788 LinkJournal=no
789 Timezone=no
790
791 [Files]
792 Bind=/home/fossil/museum/myproject:/museum
793
794 [Network]
795 VirtualEthernet=no
796 ```
797
798 ----
799
800 If you recognize most of that from the `Dockerfile` discussion above,
801 congratulations, you’ve been paying attention. The rest should also
@@ -819,22 +771,20 @@
819 That being done, we also need a generic `systemd` unit file called
820 `/etc/systemd/system/[email protected]`, containing:
821
822 ----
823
824 ```
825 [Unit]
826 Description=Fossil %i Repo Service
827 [email protected] [email protected]
828 After=network.target systemd-resolved.service [email protected] [email protected]
829
830 [Service]
831 ExecStart=systemd-nspawn --settings=override --read-only --machine=%i bin/fossil
832
833 [Install]
834 WantedBy=multi-user.target
835 ```
836
837 ----
838
839 You shouldn’t have to change any of this because we’ve given the
840 `--setting=override` flag, meaning any setting in the nspawn file
@@ -843,42 +793,36 @@
843 share the base configuration, varying on a per-repo level through
844 adjustments to their individual `*.nspawn` files.
845
846 You may then start the service in the normal way:
847
848 ```
849 $ sudo systemctl enable fossil@myproject
850 $ sudo systemctl start fossil@myproject
851 ```
852
853 You should then find it running on localhost port 9000 per the nspawn
854 configuration file above, suitable for proxying Fossil out to the
855 public using nginx via SCGI. If you aren’t using a front-end proxy
856 and want Fossil exposed to the world via HTTPS, you might say this instead in
857 the `*.nspawn` file:
858
859 ```
860 Parameters=bin/fossil server \
861 --cert /path/to/cert.pem \
862 --create \
863 --jsmode bundled \
864 --port 443 \
865 --user admin \
866 museum/repo.fossil
867 ```
868
869 You would also need to un-drop the `CAP_NET_BIND_SERVICE` capability
870 to allow Fossil to bind to this low-numbered port.
871
872 We use the `systemd` template file feature to allow multiple Fossil
873 servers running on a single machine, each on a different TCP port,
874 as when proxying them out as subdirectories of a larger site.
875 To add another project, you must first clone the base “machine” layer:
876
877 ```
878 $ sudo machinectl clone myproject otherthing
879 ```
880
881 That will not only create a clone of `/var/lib/machines/myproject`
882 as `../otherthing`, it will create a matching `otherthing.nspawn` file for you
883 as a copy of the first one. Adjust its contents to suit, then enable
884 and start it as above.
@@ -895,21 +839,17 @@
895
896 Fortunately, there are workarounds.
897
898 First, the `apt install` command above becomes:
899
900 ```
901 $ sudo dnf install systemd-container
902 ```
903
904 Second, you have to hack around the lack of `machinectl import-tar`:
905
906 ```
907 $ rootfs=/var/lib/machines/fossil
908 $ sudo mkdir -p $rootfs
909 $ docker container export fossil | sudo tar -xf -C $rootfs -
910 ```
911
912 The parent directory path in the `rootfs` variable is important,
913 because although we aren’t able to use `machinectl` on such systems, the
914 `systemd-nspawn` developers assume you’re using them together; when you give
915 `--machine`, it assumes the `machinectl` directory scheme. You could
916
--- www/containers.md
+++ www/containers.md
@@ -13,20 +13,16 @@
13 ## 1. Quick Start
14
15 Fossil ships a `Dockerfile` at the top of its source tree,
16 [here][DF], which you can build like so:
17
18 $ docker build -t fossil .
 
 
19
20 If the image built successfully, you can create a container from it and
21 test that it runs:
22
23 $ docker run --name fossil -p 9999:8080/tcp fossil
 
 
24
25 This shows us remapping the internal TCP listening port as 9999 on the
26 host. This feature of OCI runtimes means there’s little point to using
27 the “`fossil server --port`” feature inside the container. We can let
28 Fossil default to 8080 internally, then remap it to wherever we want it
@@ -44,13 +40,11 @@
40 with the `DCFLAGS` variable. (DB is short for “`docker build`”, and DC
41 is short for “`docker create`”, a sub-step of the “run” target.)
42 To get the custom port setting as in
43 second command above, say:
44
45 $ make container-run DCFLAGS='-p 9999:8080/tcp'
 
 
46
47 Contrast the raw “`docker`” commands above, which create an
48 _unversioned_ image called `fossil:latest` and from that a container
49 simply called `fossil`. The unversioned names are more convenient for
50 interactive use, while the versioned ones are good for CI/CD type
@@ -81,15 +75,13 @@
75 ### <a id="repo-inside"></a> 2.1 Storing the Repo Inside the Container
76
77 The simplest method is to stop the container if it was running, then
78 say:
79
80 $ docker cp /path/to/my-project.fossil fossil:/museum/repo.fossil
81 $ docker start fossil
82 $ docker exec fossil chown -R 499 /museum
 
 
83
84 That copies the local Fossil repo into the container where the server
85 expects to find it, so that the “start” command causes it to serve from
86 that copied-in file instead. Since it lives atop the immutable base
87 layers, it persists as part of the container proper, surviving restarts.
@@ -120,17 +112,15 @@
112 designed to be killed off at the slightest cause, rebuilt, and
113 redeployed. If you do that with the repo inside the container, it gets
114 destroyed, too. The solution is to replace the “run” command above with
115 the following:
116
117 $ docker run \
118 --publish 9999:8080 \
119 --name fossil-bind-mount \
120 --volume ~/museum:/museum \
121 fossil
 
 
122
123 Because this bind mount maps a host-side directory (`~/museum`) into the
124 container, you don’t need to `docker cp` the repo into the container at
125 all. It still expects to find the repository as `repo.fossil` under that
126 directory, but now both the host and the container can see that repo DB.
@@ -151,13 +141,11 @@
141 You might be aware that OCI containers allow mapping a single file into
142 the repository rather than a whole directory. Since Fossil repositories
143 are specially-formatted SQLite databases, you might be wondering why we
144 don’t say things like:
145
146 --volume ~/museum/my-project.fossil:/museum/repo.fossil
 
 
147
148 That lets us have a convenient file name for the project outside the
149 container while letting the configuration inside the container refer to
150 the generic “`/museum/repo.fossil`” name. Why should we have to name
151 the repo generically on the outside merely to placate the container?
@@ -292,21 +280,19 @@
280
281 All together, we recommend adding the following options to your
282 “`docker run`” commands, as well as to any “`docker create`” command
283 that will be followed by “`docker start`”:
284
285 --cap-drop AUDIT_WRITE \
286 --cap-drop CHOWN \
287 --cap-drop FSETID \
288 --cap-drop KILL \
289 --cap-drop MKNOD \
290 --cap-drop NET_BIND_SERVICE \
291 --cap-drop NET_RAW \
292 --cap-drop SETFCAP \
293 --cap-drop SETPCAP
 
 
294
295 In the next section, we’ll show a case where you create a container
296 without ever running it, making these options pointless.
297
298 [backoffice]: ./backoffice.md
@@ -326,16 +312,14 @@
312 modern Linux distros make this [surprisingly difficult][lsl], but Alpine’s
313 back-to-basics nature makes static builds work the way they used to,
314 back in the day. If that’s all you’re after, you can do so as easily as
315 this:
316
317 $ docker build -t fossil .
318 $ docker create --name fossil-static-tmp fossil
319 $ docker cp fossil-static-tmp:/bin/fossil .
320 $ docker container rm fossil-static-tmp
 
 
321
322 The result is six or seven megs, depending on the CPU architecture you
323 build for. It’s built stripped.
324
325 [lsl]: https://stackoverflow.com/questions/3430400/linux-static-linking-is-dead
@@ -347,19 +331,15 @@
331
332 The default version of Fossil fetched in the build is the version in the
333 checkout directory at the time you run it. You could override it to get
334 a release build like so:
335
336 $ docker build -t fossil --build-arg FSLVER=version-2.20 .
 
 
337
338 Or equivalently, using Fossil’s `Makefile` convenience target:
339
340 $ make container-image DBFLAGS='--build-arg FSLVER=version-2.20'
 
 
341
342 While you could instead use the generic
343 “`release`” tag here, it’s better to use a specific version number
344 since container builders cache downloaded files, hoping to
345 reuse them across builds. If you ask for “`release`” before a new
@@ -384,13 +364,11 @@
364 500 and went *down* one instead to reduce the chance of a conflict to as
365 close to zero as we can manage.
366
367 To change it to something else, say:
368
369 $ make container-image DBFLAGS='--build-arg UID=501'
 
 
370
371 This is particularly useful if you’re putting your repository on a
372 separate volume since the IDs “leak” out into the host environment via
373 file permissions. You may therefore wish them to mean something on both
374 sides of the container barrier rather than have “499” appear on the host
@@ -403,25 +381,21 @@
381 for use of any OCI container system that implements the same interfaces.
382 We go into more details about this [below](#light), but
383 for now, it suffices to point out that you can switch to Podman while
384 using our `Makefile` convenience targets unchanged by saying:
385
 
386 $ make CENGINE=podman container-run
 
387
388
389 ### 5.4 <a id="config"></a>Fossil Configuration Options
390
391 You can use this same mechanism to enable non-default Fossil
392 configuration options in your build. For instance, to turn on
393 the JSON API and the TH1 docs extension:
394
395 $ make container-image \
396 DBFLAGS='--build-arg FSLCFG="--json --with-th1-docs"'
 
 
397
398 If you also wanted [the Tcl evaluation extension](./th1.md#tclEval),
399 that brings us to [the next point](#run).
400
401
@@ -429,20 +403,20 @@
403
404 If you want a basic shell environment for temporary debugging of the
405 running container, that’s easily added. Simply change this line in the
406 `Dockerfile`…
407
408 FROM scratch AS run
409
410 …to this:
411
412 FROM busybox AS run
413
414 Rebuild and redeploy to give your Fossil container a [BusyBox]-based
415 shell environment that you can get into via:
416
417 $ docker exec -it -u fossil $(make container-version) sh
418
419 That command assumes you built it via “`make container`” and are
420 therefore using its versioning scheme.
421
422 You will likely want to remove the `PATH` override in the “RUN” stage
@@ -463,11 +437,10 @@
437 most popular programming languages in the world, we have many options
438 for achieving this. For instance, there is a whole class of
439 “[distroless]” images that will do this efficiently by changing
440 “`STAGE 2`” in the `Dockefile` to this:
441
 
442 ## ---------------------------------------------------------------------
443 ## STAGE 2: Pare that back to the bare essentials, plus Python.
444 ## ---------------------------------------------------------------------
445 FROM cgr.dev/chainguard/python:latest
446 USER root
@@ -478,24 +451,21 @@
451 RUN [ "/bin/busybox", "--install", "/bin" ]
452 RUN set -x \
453 && echo "fossil:x:${UID}:${UID}:User:/museum:/false" >> /etc/passwd \
454 && echo "fossil:x:${UID}:fossil" >> /etc/group \
455 && install -d -m 700 -o fossil -g fossil log museum
 
456
457 You will also have to add `busybox-static` to the APK package list in
458 STAGE 1 for the `RUN` script at the end of that stage to work, since the
459 [Chainguard Python image][cgimgs] lacks a shell, on purpose. The need to
460 install root-level binaries is why we change `USER` temporarily here.
461
462 Build it and test that it works like so:
463
 
464 $ make container-run &&
465 docker exec -i $(make container-version) python --version
466 3.11.2
 
467
468 The compensation for the hassle of using Chainguard over something more
469 general purpose like changing the `run` layer to Alpine and then adding
470 a “`apk add python`” command to the `Dockerfile`
471 is huge: we no longer leave a package manager sitting around inside the
@@ -555,11 +525,10 @@
525 into this, [enable linger
526 mode](https://www.freedesktop.org/software/systemd/man/loginctl.html).)
527 so I was able to create a unit file called
528 `~/.local/share/systemd/user/[email protected]` with these contents:
529
 
530 [Unit]
531 Description=Fossil email alert sender for %I
532
533 [Service]
534 WorkingDirectory=/home/fossil/museum
@@ -567,20 +536,17 @@
536 Restart=always
537 RestartSec=3
538
539 [Install]
540 WantedBy=default.target
 
541
542 I was then able to enable email alert forwarding for select repositories
543 after configuring them per [the docs](./alerts.md) by saying:
544
 
545 $ systemctl --user daemon-reload
546 $ systemctl --user enable alert-sender@myproject
547 $ systemctl --user start alert-sender@myproject
 
548
549 Because this is a parameterized script and we’ve set our repository
550 paths predictably, you can do this for as many repositories as you need
551 to by passing their names after the “`@`” sign in the commands above.
552
@@ -606,13 +572,11 @@
572 For the sake of simple examples in this section, we’ll assume you’re
573 integrating Fossil into a larger web site, such as with our [Debian +
574 nginx + TLS][DNT] plan. This is why all of the examples below create
575 the container with this option:
576
577 --publish 127.0.0.1:9999:8080
 
 
578
579 The assumption is that there’s a reverse proxy running somewhere that
580 redirects public web hits to localhost port 9999, which in turn goes to
581 port 8080 inside the container. This use of port
582 publishing effectively replaces the use of the
@@ -678,14 +642,12 @@
642 tenth the size of Docker Engine.
643
644 For our purposes here, the only thing that changes relative to the
645 examples at the top of this document are the initial command:
646
647 $ podman build -t fossil .
648 $ podman run --name fossil -p 9999:8080/tcp fossil
 
 
649
650 Your Linux package repo may have a `podman-docker` package which
651 provides a “`docker`” script that calls “`podman`” for you, eliminating
652 even the command name difference. With that installed, the `make`
653 commands above will work with Podman as-is.
@@ -692,23 +654,21 @@
654
655 The only difference that matters here is that Podman doesn’t have the
656 same [default Linux kernel capability set](#caps) as Docker, which
657 affects the `--cap-drop` flags recommended above to:
658
659 $ podman create \
660 --name fossil \
661 --cap-drop CHOWN \
662 --cap-drop FSETID \
663 --cap-drop KILL \
664 --cap-drop NET_BIND_SERVICE \
665 --cap-drop SETFCAP \
666 --cap-drop SETPCAP \
667 --publish 127.0.0.1:9999:8080 \
668 localhost/fossil
669 $ podman start fossil
 
 
670
671 [pmmac]: https://podman.io/getting-started/installation.html#macos
672 [pmwin]: https://github.com/containers/podman/blob/main/docs/tutorials/podman-for-windows.md
673 [Podman]: https://podman.io/
674 [rl]: https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md
@@ -720,13 +680,11 @@
680 If even the Podman stack is too big for you, the next-best option I’m
681 aware of is the `systemd-container` infrastructure on modern Linuxes,
682 available since version 239 or so. Its runtime tooling requires only
683 about 1.4 MiB of disk space:
684
685 $ sudo apt install systemd-container btrfs-tools
 
 
686
687 That command assumes the primary test environment for
688 this guide, Ubuntu 22.04 LTS with `systemd` 249. For best
689 results, `/var/lib/machines` should be a btrfs volume, because
690 [`$REASONS`][mcfad]. For CentOS Stream 9 and other Red Hattish
@@ -742,60 +700,54 @@
700 If you use [the stock `Dockerfile`][DF] to generate your
701 base image, `nspawn` won’t recognize it as containing an OS unless you
702 change the “`FROM scratch AS os`” line at the top of the second stage
703 to something like this:
704
705 FROM gcr.io/distroless/static-debian11 AS os
 
 
706
707 Using that as a base image provides all the files `nspawn` checks for to
708 determine whether the container is sufficiently close to a Linux VM for
709 the following step to proceed:
710
711 $ make container
712 $ docker container export $(make container-version) |
713 machinectl import-tar - myproject
 
 
714
715 Next, create `/etc/systemd/nspawn/myproject.nspawn`:
716
717 ----
718
719 [Exec]
720 WorkingDirectory=/
721 Parameters=bin/fossil server \
722 --baseurl https://example.com/myproject \
723 --create \
724 --jsmode bundled \
725 --localhost \
726 --port 9000 \
727 --scgi \
728 --user admin \
729 museum/repo.fossil
730 DropCapability= \
731 CAP_AUDIT_WRITE \
732 CAP_CHOWN \
733 CAP_FSETID \
734 CAP_KILL \
735 CAP_MKNOD \
736 CAP_NET_BIND_SERVICE \
737 CAP_NET_RAW \
738 CAP_SETFCAP \
739 CAP_SETPCAP
740 ProcessTwo=yes
741 LinkJournal=no
742 Timezone=no
743
744 [Files]
745 Bind=/home/fossil/museum/myproject:/museum
746
747 [Network]
748 VirtualEthernet=no
 
 
749
750 ----
751
752 If you recognize most of that from the `Dockerfile` discussion above,
753 congratulations, you’ve been paying attention. The rest should also
@@ -819,22 +771,20 @@
771 That being done, we also need a generic `systemd` unit file called
772 `/etc/systemd/system/[email protected]`, containing:
773
774 ----
775
776 [Unit]
777 Description=Fossil %i Repo Service
778 [email protected] [email protected]
779 After=network.target systemd-resolved.service [email protected] [email protected]
780
781 [Service]
782 ExecStart=systemd-nspawn --settings=override --read-only --machine=%i bin/fossil
783
784 [Install]
785 WantedBy=multi-user.target
 
 
786
787 ----
788
789 You shouldn’t have to change any of this because we’ve given the
790 `--setting=override` flag, meaning any setting in the nspawn file
@@ -843,42 +793,36 @@
793 share the base configuration, varying on a per-repo level through
794 adjustments to their individual `*.nspawn` files.
795
796 You may then start the service in the normal way:
797
798 $ sudo systemctl enable fossil@myproject
799 $ sudo systemctl start fossil@myproject
 
 
800
801 You should then find it running on localhost port 9000 per the nspawn
802 configuration file above, suitable for proxying Fossil out to the
803 public using nginx via SCGI. If you aren’t using a front-end proxy
804 and want Fossil exposed to the world via HTTPS, you might say this instead in
805 the `*.nspawn` file:
806
807 Parameters=bin/fossil server \
808 --cert /path/to/cert.pem \
809 --create \
810 --jsmode bundled \
811 --port 443 \
812 --user admin \
813 museum/repo.fossil
 
 
814
815 You would also need to un-drop the `CAP_NET_BIND_SERVICE` capability
816 to allow Fossil to bind to this low-numbered port.
817
818 We use the `systemd` template file feature to allow multiple Fossil
819 servers running on a single machine, each on a different TCP port,
820 as when proxying them out as subdirectories of a larger site.
821 To add another project, you must first clone the base “machine” layer:
822
823 $ sudo machinectl clone myproject otherthing
 
 
824
825 That will not only create a clone of `/var/lib/machines/myproject`
826 as `../otherthing`, it will create a matching `otherthing.nspawn` file for you
827 as a copy of the first one. Adjust its contents to suit, then enable
828 and start it as above.
@@ -895,21 +839,17 @@
839
840 Fortunately, there are workarounds.
841
842 First, the `apt install` command above becomes:
843
844 $ sudo dnf install systemd-container
 
 
845
846 Second, you have to hack around the lack of `machinectl import-tar`:
847
848 $ rootfs=/var/lib/machines/fossil
849 $ sudo mkdir -p $rootfs
850 $ docker container export fossil | sudo tar -xf -C $rootfs -
 
 
851
852 The parent directory path in the `rootfs` variable is important,
853 because although we aren’t able to use `machinectl` on such systems, the
854 `systemd-nspawn` developers assume you’re using them together; when you give
855 `--machine`, it assumes the `machinectl` directory scheme. You could
856
+13 -15
--- www/defcsp.md
+++ www/defcsp.md
@@ -23,43 +23,41 @@
2323
## The Default Restrictions
2424
2525
The default CSP used by Fossil is as follows:
2626
2727
<pre>
28
- default-src 'self' data:;
29
- script-src 'self' 'nonce-$nonce';
30
- style-src 'self' 'unsafe-inline';
31
- img-src * data:;
28
+default-src 'self' data:;
29
+script-src 'self' 'nonce-$nonce';
30
+style-src 'self' 'unsafe-inline';
31
+img-src * data:;
3232
</pre>
3333
3434
The default is recommended for most installations. However,
3535
the site administrators can overwrite this default CSP using the
3636
[default-csp setting](/help?cmd=default-csp). For example,
3737
CSP restrictions can be completely disabled by setting the default-csp to:
3838
39
-<pre>
40
- default-src *;
41
-</pre>
39
+ default-src *;
4240
4341
The following sections detail the maining of the default CSP setting.
4442
4543
### <a id="base"></a> default-src 'self' data:
4644
4745
This policy means mixed-origin content isn’t allowed, so you can’t refer
4846
to resources on other web domains. Browsers will ignore a link like the
4947
one in the following Markdown under our default CSP:
5048
51
- ![fancy 3D Fossil logotype](https://i.imgur.com/HalpMgt.png)
49
+ ![fancy 3D Fossil logotype](https://i.imgur.com/HalpMgt.png)
5250
5351
If you look in the browser’s developer console, you should see a CSP
5452
error when attempting to render such a page.
5553
5654
The default policy does allow inline `data:` URIs, which means you could
5755
[data-encode][de] your image content and put it inline within the
5856
document:
5957
60
- ![small inline image](data:image/gif;base64,R0lGODlh...)
58
+ ![small inline image](data:image/gif;base64,R0lGODlh...)
6159
6260
That method is best used for fairly small resources. Large `data:` URIs
6361
are hard to read and edit. There are secondary problems as well: if you
6462
put a large image into a Fossil forum post this way, anyone subscribed
6563
to email alerts will get a copy of the raw URI text, which can amount to
@@ -67,11 +65,11 @@
6765
6866
For inline images within [embedded documentation][ed], it suffices to
6967
store the referred-to files in the repo and then refer to them using
7068
repo-relative URLs:
7169
72
- ![large inline image](./inlineimage.jpg)
70
+ ![large inline image](./inlineimage.jpg)
7371
7472
This avoids bloating the doc text with `data:` URI blobs:
7573
7674
There are many other cases, [covered below](#serving).
7775
@@ -99,11 +97,11 @@
9997
`<style>` tags within the document text.
10098
10199
The `'unsafe-inline'` declaration allows CSS within individual HTML
102100
elements:
103101
104
- <p style="margin-left: 4em">Indented text.</p>
102
+ <p style="margin-left: 4em">Indented text.</p>
105103
106104
As the "`unsafe-`" prefix on the name implies, the `'unsafe-inline'`
107105
feature is suboptimal for security. However, there are
108106
a few places in the Fossil-generated HTML that benefit from this
109107
flexibility and the work-arounds are verbose and difficult to maintain.
@@ -174,11 +172,11 @@
174172
scheme. Any one of those hundreds of repositories could trick you into
175173
visiting their repository home page, set to [an HTML-formatted embedded
176174
doc page][hfed] via Admin → Configuration → Index&nbsp;Page, with this
177175
content:
178176
179
- <script src="/doc/trunk/bad.js"></script>
177
+ <script src="/doc/trunk/bad.js"></script>
180178
181179
That script can then do anything allowed in JavaScript to *any other*
182180
Chisel repository your browser can access. The possibilities for mischief
183181
are *vast*. For just one example, if you have login cookies on four
184182
different Chisel repositories, your attacker could harvest the login
@@ -198,11 +196,11 @@
198196
willingly run any JavaScript code they’ve provided, blind, you **must
199197
not** give the `--with-th1-docs` option when configuring Fossil, because
200198
that allows substitution of the [pre-defined `$nonce` TH1
201199
variable](./th1.md#nonce) into [HTML-formatted embedded docs][hfed]:
202200
203
- <script src="/doc/trunk/bad.js" nonce="$nonce"></script>
201
+ <script src="/doc/trunk/bad.js" nonce="$nonce"></script>
204202
205203
Even with this feature enabled, you cannot put `<script>` tags into
206204
Fossil Wiki or Markdown-formatted content, because our HTML generators
207205
for those formats purposely strip or disable such tags in the output.
208206
Therefore, if you trust those users with check-in rights to provide
@@ -331,11 +329,11 @@
331329
332330
Because a blank setting tells Fossil to use its hard-coded default CSP,
333331
you have to say something like the following to get a repository without
334332
content security policy restrictions:
335333
336
- $ fossil set -R /path/to/served/repo.fossil default-csp 'default-src *'
334
+ $ fossil set -R /path/to/served/repo.fossil default-csp 'default-src *'
337335
338336
We recommend that instead of using the command line to change this
339337
setting that you do it via the repository’s web interface, in
340338
Admin → Settings. Write your CSP rules in the edit box marked
341339
"`default-csp`". Do not add hard newlines in that box: the setting needs
@@ -366,11 +364,11 @@
366364
367365
This means that another way you can override this value is to use
368366
the [`th1-setup` hook script](./th1-hooks.md), which runs before TH1
369367
processing happens during skin processing:
370368
371
- $ fossil set th1-setup "set default_csp {default-src 'self'}"
369
+ $ fossil set th1-setup "set default_csp {default-src 'self'}"
372370
373371
After [the above](#admin-ui), this is the cleanest method.
374372
375373
[thvar]: ./customskin.md#vars
376374
377375
--- www/defcsp.md
+++ www/defcsp.md
@@ -23,43 +23,41 @@
23 ## The Default Restrictions
24
25 The default CSP used by Fossil is as follows:
26
27 <pre>
28 default-src 'self' data:;
29 script-src 'self' 'nonce-$nonce';
30 style-src 'self' 'unsafe-inline';
31 img-src * data:;
32 </pre>
33
34 The default is recommended for most installations. However,
35 the site administrators can overwrite this default CSP using the
36 [default-csp setting](/help?cmd=default-csp). For example,
37 CSP restrictions can be completely disabled by setting the default-csp to:
38
39 <pre>
40 default-src *;
41 </pre>
42
43 The following sections detail the maining of the default CSP setting.
44
45 ### <a id="base"></a> default-src 'self' data:
46
47 This policy means mixed-origin content isn’t allowed, so you can’t refer
48 to resources on other web domains. Browsers will ignore a link like the
49 one in the following Markdown under our default CSP:
50
51 ![fancy 3D Fossil logotype](https://i.imgur.com/HalpMgt.png)
52
53 If you look in the browser’s developer console, you should see a CSP
54 error when attempting to render such a page.
55
56 The default policy does allow inline `data:` URIs, which means you could
57 [data-encode][de] your image content and put it inline within the
58 document:
59
60 ![small inline image](data:image/gif;base64,R0lGODlh...)
61
62 That method is best used for fairly small resources. Large `data:` URIs
63 are hard to read and edit. There are secondary problems as well: if you
64 put a large image into a Fossil forum post this way, anyone subscribed
65 to email alerts will get a copy of the raw URI text, which can amount to
@@ -67,11 +65,11 @@
67
68 For inline images within [embedded documentation][ed], it suffices to
69 store the referred-to files in the repo and then refer to them using
70 repo-relative URLs:
71
72 ![large inline image](./inlineimage.jpg)
73
74 This avoids bloating the doc text with `data:` URI blobs:
75
76 There are many other cases, [covered below](#serving).
77
@@ -99,11 +97,11 @@
99 `<style>` tags within the document text.
100
101 The `'unsafe-inline'` declaration allows CSS within individual HTML
102 elements:
103
104 <p style="margin-left: 4em">Indented text.</p>
105
106 As the "`unsafe-`" prefix on the name implies, the `'unsafe-inline'`
107 feature is suboptimal for security. However, there are
108 a few places in the Fossil-generated HTML that benefit from this
109 flexibility and the work-arounds are verbose and difficult to maintain.
@@ -174,11 +172,11 @@
174 scheme. Any one of those hundreds of repositories could trick you into
175 visiting their repository home page, set to [an HTML-formatted embedded
176 doc page][hfed] via Admin → Configuration → Index&nbsp;Page, with this
177 content:
178
179 <script src="/doc/trunk/bad.js"></script>
180
181 That script can then do anything allowed in JavaScript to *any other*
182 Chisel repository your browser can access. The possibilities for mischief
183 are *vast*. For just one example, if you have login cookies on four
184 different Chisel repositories, your attacker could harvest the login
@@ -198,11 +196,11 @@
198 willingly run any JavaScript code they’ve provided, blind, you **must
199 not** give the `--with-th1-docs` option when configuring Fossil, because
200 that allows substitution of the [pre-defined `$nonce` TH1
201 variable](./th1.md#nonce) into [HTML-formatted embedded docs][hfed]:
202
203 <script src="/doc/trunk/bad.js" nonce="$nonce"></script>
204
205 Even with this feature enabled, you cannot put `<script>` tags into
206 Fossil Wiki or Markdown-formatted content, because our HTML generators
207 for those formats purposely strip or disable such tags in the output.
208 Therefore, if you trust those users with check-in rights to provide
@@ -331,11 +329,11 @@
331
332 Because a blank setting tells Fossil to use its hard-coded default CSP,
333 you have to say something like the following to get a repository without
334 content security policy restrictions:
335
336 $ fossil set -R /path/to/served/repo.fossil default-csp 'default-src *'
337
338 We recommend that instead of using the command line to change this
339 setting that you do it via the repository’s web interface, in
340 Admin → Settings. Write your CSP rules in the edit box marked
341 "`default-csp`". Do not add hard newlines in that box: the setting needs
@@ -366,11 +364,11 @@
366
367 This means that another way you can override this value is to use
368 the [`th1-setup` hook script](./th1-hooks.md), which runs before TH1
369 processing happens during skin processing:
370
371 $ fossil set th1-setup "set default_csp {default-src 'self'}"
372
373 After [the above](#admin-ui), this is the cleanest method.
374
375 [thvar]: ./customskin.md#vars
376
377
--- www/defcsp.md
+++ www/defcsp.md
@@ -23,43 +23,41 @@
23 ## The Default Restrictions
24
25 The default CSP used by Fossil is as follows:
26
27 <pre>
28 default-src 'self' data:;
29 script-src 'self' 'nonce-$nonce';
30 style-src 'self' 'unsafe-inline';
31 img-src * data:;
32 </pre>
33
34 The default is recommended for most installations. However,
35 the site administrators can overwrite this default CSP using the
36 [default-csp setting](/help?cmd=default-csp). For example,
37 CSP restrictions can be completely disabled by setting the default-csp to:
38
39 default-src *;
 
 
40
41 The following sections detail the maining of the default CSP setting.
42
43 ### <a id="base"></a> default-src 'self' data:
44
45 This policy means mixed-origin content isn’t allowed, so you can’t refer
46 to resources on other web domains. Browsers will ignore a link like the
47 one in the following Markdown under our default CSP:
48
49 ![fancy 3D Fossil logotype](https://i.imgur.com/HalpMgt.png)
50
51 If you look in the browser’s developer console, you should see a CSP
52 error when attempting to render such a page.
53
54 The default policy does allow inline `data:` URIs, which means you could
55 [data-encode][de] your image content and put it inline within the
56 document:
57
58 ![small inline image](data:image/gif;base64,R0lGODlh...)
59
60 That method is best used for fairly small resources. Large `data:` URIs
61 are hard to read and edit. There are secondary problems as well: if you
62 put a large image into a Fossil forum post this way, anyone subscribed
63 to email alerts will get a copy of the raw URI text, which can amount to
@@ -67,11 +65,11 @@
65
66 For inline images within [embedded documentation][ed], it suffices to
67 store the referred-to files in the repo and then refer to them using
68 repo-relative URLs:
69
70 ![large inline image](./inlineimage.jpg)
71
72 This avoids bloating the doc text with `data:` URI blobs:
73
74 There are many other cases, [covered below](#serving).
75
@@ -99,11 +97,11 @@
97 `<style>` tags within the document text.
98
99 The `'unsafe-inline'` declaration allows CSS within individual HTML
100 elements:
101
102 <p style="margin-left: 4em">Indented text.</p>
103
104 As the "`unsafe-`" prefix on the name implies, the `'unsafe-inline'`
105 feature is suboptimal for security. However, there are
106 a few places in the Fossil-generated HTML that benefit from this
107 flexibility and the work-arounds are verbose and difficult to maintain.
@@ -174,11 +172,11 @@
172 scheme. Any one of those hundreds of repositories could trick you into
173 visiting their repository home page, set to [an HTML-formatted embedded
174 doc page][hfed] via Admin → Configuration → Index&nbsp;Page, with this
175 content:
176
177 <script src="/doc/trunk/bad.js"></script>
178
179 That script can then do anything allowed in JavaScript to *any other*
180 Chisel repository your browser can access. The possibilities for mischief
181 are *vast*. For just one example, if you have login cookies on four
182 different Chisel repositories, your attacker could harvest the login
@@ -198,11 +196,11 @@
196 willingly run any JavaScript code they’ve provided, blind, you **must
197 not** give the `--with-th1-docs` option when configuring Fossil, because
198 that allows substitution of the [pre-defined `$nonce` TH1
199 variable](./th1.md#nonce) into [HTML-formatted embedded docs][hfed]:
200
201 <script src="/doc/trunk/bad.js" nonce="$nonce"></script>
202
203 Even with this feature enabled, you cannot put `<script>` tags into
204 Fossil Wiki or Markdown-formatted content, because our HTML generators
205 for those formats purposely strip or disable such tags in the output.
206 Therefore, if you trust those users with check-in rights to provide
@@ -331,11 +329,11 @@
329
330 Because a blank setting tells Fossil to use its hard-coded default CSP,
331 you have to say something like the following to get a repository without
332 content security policy restrictions:
333
334 $ fossil set -R /path/to/served/repo.fossil default-csp 'default-src *'
335
336 We recommend that instead of using the command line to change this
337 setting that you do it via the repository’s web interface, in
338 Admin → Settings. Write your CSP rules in the edit box marked
339 "`default-csp`". Do not add hard newlines in that box: the setting needs
@@ -366,11 +364,11 @@
364
365 This means that another way you can override this value is to use
366 the [`th1-setup` hook script](./th1-hooks.md), which runs before TH1
367 processing happens during skin processing:
368
369 $ fossil set th1-setup "set default_csp {default-src 'self'}"
370
371 After [the above](#admin-ui), this is the cleanest method.
372
373 [thvar]: ./customskin.md#vars
374
375
--- www/embeddeddoc.wiki
+++ www/embeddeddoc.wiki
@@ -138,21 +138,21 @@
138138
the root of the Fossil repository using the special text "$ROOT"
139139
at the beginning of a URL. For example, a Markdown hyperlink to
140140
the Markdown formatting rules might be
141141
written in the embedded document like this:
142142
143
-<nowiki><pre>
144
- [Markdown formatting rules]($ROOT/wiki_rules)
145
-</pre></nowiki>
143
+<verbatim>
144
+[Markdown formatting rules]($ROOT/wiki_rules)
145
+</verbatim>
146146
147147
Depending on how the how the Fossil server is configured, that hyperlink
148148
might be renderer like one of the following:
149149
150
-<nowiki><pre>
151
- &lt;a href="/wiki_rules"&gt;Wiki formatting rules&lt;/a&gt;
152
- &lt;a href="/cgi-bin/fossil/wiki_rules"&gt;Wiki formatting rules&lt;/a&gt;
153
-</pre></nowiki>
150
+<verbatim>
151
+<a href="/wiki_rules">Wiki formatting rule</a>
152
+<a href="/cgi-bin/fossil/wiki_rules">Wiki formatting rules</a>
153
+</verbatim>
154154
155155
So, in other words, the "$ROOT" text is converted into whatever
156156
the "&lt;baseurl&gt;" is for the document.
157157
158158
This substitution works for HTML and Markdown documents.
@@ -169,13 +169,13 @@
169169
170170
For example, if an embedded document documented wanted to reference
171171
some other document in a separate file named "www/otherdoc.md",
172172
it could use a URL like this:
173173
174
-<nowiki><pre>
175
- [Other Document]($ROOT/doc/$CURRENT/www/otherdoc.md)
176
-</pre></nowiki>
174
+<verbatim>
175
+[Other Document]($ROOT/doc/$CURRENT/www/otherdoc.md)
176
+</verbatim>
177177
178178
As with "$ROOT", this substitution only works for Markdown and HTML
179179
documents. For Wiki documents, you would need to use a relative URL.
180180
181181
<h2 id="th1">2.3 TH1 Documents</h2>
182182
--- www/embeddeddoc.wiki
+++ www/embeddeddoc.wiki
@@ -138,21 +138,21 @@
138 the root of the Fossil repository using the special text "$ROOT"
139 at the beginning of a URL. For example, a Markdown hyperlink to
140 the Markdown formatting rules might be
141 written in the embedded document like this:
142
143 <nowiki><pre>
144 [Markdown formatting rules]($ROOT/wiki_rules)
145 </pre></nowiki>
146
147 Depending on how the how the Fossil server is configured, that hyperlink
148 might be renderer like one of the following:
149
150 <nowiki><pre>
151 &lt;a href="/wiki_rules"&gt;Wiki formatting rules&lt;/a&gt;
152 &lt;a href="/cgi-bin/fossil/wiki_rules"&gt;Wiki formatting rules&lt;/a&gt;
153 </pre></nowiki>
154
155 So, in other words, the "$ROOT" text is converted into whatever
156 the "&lt;baseurl&gt;" is for the document.
157
158 This substitution works for HTML and Markdown documents.
@@ -169,13 +169,13 @@
169
170 For example, if an embedded document documented wanted to reference
171 some other document in a separate file named "www/otherdoc.md",
172 it could use a URL like this:
173
174 <nowiki><pre>
175 [Other Document]($ROOT/doc/$CURRENT/www/otherdoc.md)
176 </pre></nowiki>
177
178 As with "$ROOT", this substitution only works for Markdown and HTML
179 documents. For Wiki documents, you would need to use a relative URL.
180
181 <h2 id="th1">2.3 TH1 Documents</h2>
182
--- www/embeddeddoc.wiki
+++ www/embeddeddoc.wiki
@@ -138,21 +138,21 @@
138 the root of the Fossil repository using the special text "$ROOT"
139 at the beginning of a URL. For example, a Markdown hyperlink to
140 the Markdown formatting rules might be
141 written in the embedded document like this:
142
143 <verbatim>
144 [Markdown formatting rules]($ROOT/wiki_rules)
145 </verbatim>
146
147 Depending on how the how the Fossil server is configured, that hyperlink
148 might be renderer like one of the following:
149
150 <verbatim>
151 <a href="/wiki_rules">Wiki formatting rule</a>
152 <a href="/cgi-bin/fossil/wiki_rules">Wiki formatting rules</a>
153 </verbatim>
154
155 So, in other words, the "$ROOT" text is converted into whatever
156 the "&lt;baseurl&gt;" is for the document.
157
158 This substitution works for HTML and Markdown documents.
@@ -169,13 +169,13 @@
169
170 For example, if an embedded document documented wanted to reference
171 some other document in a separate file named "www/otherdoc.md",
172 it could use a URL like this:
173
174 <verbatim>
175 [Other Document]($ROOT/doc/$CURRENT/www/otherdoc.md)
176 </verbatim>
177
178 As with "$ROOT", this substitution only works for Markdown and HTML
179 documents. For Wiki documents, you would need to use a relative URL.
180
181 <h2 id="th1">2.3 TH1 Documents</h2>
182
--- www/image-format-vs-repo-size.md
+++ www/image-format-vs-repo-size.md
@@ -159,39 +159,39 @@
159159
uncompressed form, we want an automated method for producing the
160160
uncompressed form to make Fossil happy while still having the compressed
161161
form to keep our content creation applications happy. This `Makefile`
162162
should[^makefile] do that for BMP, PNG, SVG, and XLSX files:
163163
164
- .SUFFIXES: .bmp .png .svg .svgz
165
-
166
- .svgz.svg:
167
- gzip -dc < $< > $@
168
-
169
- .svg.svgz:
170
- gzip -9c < $< > $@
171
-
172
- .bmp.png:
173
- convert -quality 95 $< $@
174
-
175
- .png.bmp:
176
- convert $< $@
177
-
178
- SS_FILES := $(wildcard spreadsheet/*)
179
-
180
-
181
- all: $(SS_FILES) illus.svg image.bmp doc-big.pdf
182
-
183
- reconstitute: illus.svgz image.png
184
- ( cd spreadsheet ; zip -9 ../spreadsheet.xlsx) * )
185
- qpdf doc-big.pdf doc-small.pdf
186
-
187
-
188
- $(SS_FILES): spreadsheet.xlsx
189
- unzip $@ -d $<
190
-
191
- doc-big.pdf: doc-small.pdf
192
- qpdf --stream-data=uncompress $@ $<
164
+ .SUFFIXES: .bmp .png .svg .svgz
165
+
166
+ .svgz.svg:
167
+ gzip -dc < $< > $@
168
+
169
+ .svg.svgz:
170
+ gzip -9c < $< > $@
171
+
172
+ .bmp.png:
173
+ convert -quality 95 $< $@
174
+
175
+ .png.bmp:
176
+ convert $< $@
177
+
178
+ SS_FILES := $(wildcard spreadsheet/*)
179
+
180
+
181
+ all: $(SS_FILES) illus.svg image.bmp doc-big.pdf
182
+
183
+ reconstitute: illus.svgz image.png
184
+ ( cd spreadsheet ; zip -9 ../spreadsheet.xlsx) * )
185
+ qpdf doc-big.pdf doc-small.pdf
186
+
187
+
188
+ $(SS_FILES): spreadsheet.xlsx
189
+ unzip $@ -d $<
190
+
191
+ doc-big.pdf: doc-small.pdf
192
+ qpdf --stream-data=uncompress $@ $<
193193
194194
This `Makefile` allows you to treat the compressed version as the
195195
process input, but to actually check in only the changes against the
196196
uncompressed version by typing “`make`” before “`fossil ci`”. This is
197197
not actually an extra step in practice, since if you’ve got a
198198
--- www/image-format-vs-repo-size.md
+++ www/image-format-vs-repo-size.md
@@ -159,39 +159,39 @@
159 uncompressed form, we want an automated method for producing the
160 uncompressed form to make Fossil happy while still having the compressed
161 form to keep our content creation applications happy. This `Makefile`
162 should[^makefile] do that for BMP, PNG, SVG, and XLSX files:
163
164 .SUFFIXES: .bmp .png .svg .svgz
165
166 .svgz.svg:
167 gzip -dc < $< > $@
168
169 .svg.svgz:
170 gzip -9c < $< > $@
171
172 .bmp.png:
173 convert -quality 95 $< $@
174
175 .png.bmp:
176 convert $< $@
177
178 SS_FILES := $(wildcard spreadsheet/*)
179
180
181 all: $(SS_FILES) illus.svg image.bmp doc-big.pdf
182
183 reconstitute: illus.svgz image.png
184 ( cd spreadsheet ; zip -9 ../spreadsheet.xlsx) * )
185 qpdf doc-big.pdf doc-small.pdf
186
187
188 $(SS_FILES): spreadsheet.xlsx
189 unzip $@ -d $<
190
191 doc-big.pdf: doc-small.pdf
192 qpdf --stream-data=uncompress $@ $<
193
194 This `Makefile` allows you to treat the compressed version as the
195 process input, but to actually check in only the changes against the
196 uncompressed version by typing “`make`” before “`fossil ci`”. This is
197 not actually an extra step in practice, since if you’ve got a
198
--- www/image-format-vs-repo-size.md
+++ www/image-format-vs-repo-size.md
@@ -159,39 +159,39 @@
159 uncompressed form, we want an automated method for producing the
160 uncompressed form to make Fossil happy while still having the compressed
161 form to keep our content creation applications happy. This `Makefile`
162 should[^makefile] do that for BMP, PNG, SVG, and XLSX files:
163
164 .SUFFIXES: .bmp .png .svg .svgz
165
166 .svgz.svg:
167 gzip -dc < $< > $@
168
169 .svg.svgz:
170 gzip -9c < $< > $@
171
172 .bmp.png:
173 convert -quality 95 $< $@
174
175 .png.bmp:
176 convert $< $@
177
178 SS_FILES := $(wildcard spreadsheet/*)
179
180
181 all: $(SS_FILES) illus.svg image.bmp doc-big.pdf
182
183 reconstitute: illus.svgz image.png
184 ( cd spreadsheet ; zip -9 ../spreadsheet.xlsx) * )
185 qpdf doc-big.pdf doc-small.pdf
186
187
188 $(SS_FILES): spreadsheet.xlsx
189 unzip $@ -d $<
190
191 doc-big.pdf: doc-small.pdf
192 qpdf --stream-data=uncompress $@ $<
193
194 This `Makefile` allows you to treat the compressed version as the
195 process input, but to actually check in only the changes against the
196 uncompressed version by typing “`make`” before “`fossil ci`”. This is
197 not actually an extra step in practice, since if you’ve got a
198
+15 -15
--- www/javascript.md
+++ www/javascript.md
@@ -371,24 +371,24 @@
371371
maintain your repository’s wiki at all. Fossil’s [`wiki` command][fwc]
372372
lets you manipulate wiki documents from the command line. For example,
373373
consider this Vi based workflow:
374374
375375
```shell
376
- $ vi 'My Article.wiki' # begin work on new article
377
- ...write, write, write...
378
- :w # save changes to disk copy
379
- :!fossil wiki create 'My Article' '%' # current file (%) to new article
380
- ...write, write, write some more...
381
- :w # save again
382
- :!fossil wiki commit 'My Article' '%' # update article from disk
383
- :q # done writing for today
384
-
385
- ....days later...
386
- $ vi # work sans named file today
387
- :r !fossil wiki export 'My Article' - # pull article text into vi buffer
388
- ...write, write, write yet more...
389
- :w !fossil wiki commit - # vi buffer updates article
376
+$ vi 'My Article.wiki' # begin work on new article
377
+ ...write, write, write...
378
+:w # save changes to disk copy
379
+:!fossil wiki create 'My Article' '%' # current file (%) to new article
380
+ ...write, write, write some more...
381
+:w # save again
382
+:!fossil wiki commit 'My Article' '%' # update article from disk
383
+:q # done writing for today
384
+
385
+ ....days later...
386
+$ vi # work sans named file today
387
+:r !fossil wiki export 'My Article' - # pull article text into vi buffer
388
+ ...write, write, write yet more...
389
+:w !fossil wiki commit - # vi buffer updates article
390390
```
391391
392392
Extending this concept to other text editors is an exercise left to the
393393
reader.
394394
@@ -576,11 +576,11 @@
576576
sufficiently motivated to build a Fossil chat gateway, connecting to
577577
IRC, Jabber, etc. The messages are stored in the repository’s `chat`
578578
table with monotonically increasing IDs, so a poller that did something
579579
like
580580
581
- SELECT xfrom, xmsg FROM chat WHERE msgid > 1234;
581
+ SELECT xfrom, xmsg FROM chat WHERE msgid > 1234;
582582
583583
…would pull the messages submitted since the last poll. Making the
584584
gateway bidirectional should be possible as well, as long as it properly
585585
uses SQLite transactions.
586586
587587
--- www/javascript.md
+++ www/javascript.md
@@ -371,24 +371,24 @@
371 maintain your repository’s wiki at all. Fossil’s [`wiki` command][fwc]
372 lets you manipulate wiki documents from the command line. For example,
373 consider this Vi based workflow:
374
375 ```shell
376 $ vi 'My Article.wiki' # begin work on new article
377 ...write, write, write...
378 :w # save changes to disk copy
379 :!fossil wiki create 'My Article' '%' # current file (%) to new article
380 ...write, write, write some more...
381 :w # save again
382 :!fossil wiki commit 'My Article' '%' # update article from disk
383 :q # done writing for today
384
385 ....days later...
386 $ vi # work sans named file today
387 :r !fossil wiki export 'My Article' - # pull article text into vi buffer
388 ...write, write, write yet more...
389 :w !fossil wiki commit - # vi buffer updates article
390 ```
391
392 Extending this concept to other text editors is an exercise left to the
393 reader.
394
@@ -576,11 +576,11 @@
576 sufficiently motivated to build a Fossil chat gateway, connecting to
577 IRC, Jabber, etc. The messages are stored in the repository’s `chat`
578 table with monotonically increasing IDs, so a poller that did something
579 like
580
581 SELECT xfrom, xmsg FROM chat WHERE msgid > 1234;
582
583 …would pull the messages submitted since the last poll. Making the
584 gateway bidirectional should be possible as well, as long as it properly
585 uses SQLite transactions.
586
587
--- www/javascript.md
+++ www/javascript.md
@@ -371,24 +371,24 @@
371 maintain your repository’s wiki at all. Fossil’s [`wiki` command][fwc]
372 lets you manipulate wiki documents from the command line. For example,
373 consider this Vi based workflow:
374
375 ```shell
376 $ vi 'My Article.wiki' # begin work on new article
377 ...write, write, write...
378 :w # save changes to disk copy
379 :!fossil wiki create 'My Article' '%' # current file (%) to new article
380 ...write, write, write some more...
381 :w # save again
382 :!fossil wiki commit 'My Article' '%' # update article from disk
383 :q # done writing for today
384
385 ....days later...
386 $ vi # work sans named file today
387 :r !fossil wiki export 'My Article' - # pull article text into vi buffer
388 ...write, write, write yet more...
389 :w !fossil wiki commit - # vi buffer updates article
390 ```
391
392 Extending this concept to other text editors is an exercise left to the
393 reader.
394
@@ -576,11 +576,11 @@
576 sufficiently motivated to build a Fossil chat gateway, connecting to
577 IRC, Jabber, etc. The messages are stored in the repository’s `chat`
578 table with monotonically increasing IDs, so a poller that did something
579 like
580
581 SELECT xfrom, xmsg FROM chat WHERE msgid > 1234;
582
583 …would pull the messages submitted since the last poll. Making the
584 gateway bidirectional should be possible as well, as long as it properly
585 uses SQLite transactions.
586
587
+3 -3
--- www/loadmgmt.md
+++ www/loadmgmt.md
@@ -52,12 +52,12 @@
5252
easily set it higher on a multi-core server.
5353
5454
The maximum load average can also be set on the command line using
5555
commands like this:
5656
57
- fossil set max-loadavg 1.5
58
- fossil all set max-loadavg 1.5
57
+ fossil set max-loadavg 1.5
58
+ fossil all set max-loadavg 1.5
5959
6060
The second form is especially useful for changing the maximum load
6161
average simultaneously on a large number of repositories.
6262
6363
Note that this load-average limiting feature is only available on
@@ -71,11 +71,11 @@
7171
you are running a Fossil instance [inside a `chroot(2)`
7272
jail](./chroot.md) and you have not mounted the `/proc` virtual file
7373
system inside that jail. On the [self-hosting Fossil repositories][sh],
7474
this was accomplished by adding a line to the `/etc/fstab` file:
7575
76
- chroot_jail_proc /home/www/proc proc ro 0 0
76
+ chroot_jail_proc /home/www/proc proc ro 0 0
7777
7878
The `/home/www/proc` pathname should be adjusted so that the `/proc`
7979
component is at the root of the chroot jail, of course.
8080
8181
To see if the load-average limiter is functional, visit the
8282
--- www/loadmgmt.md
+++ www/loadmgmt.md
@@ -52,12 +52,12 @@
52 easily set it higher on a multi-core server.
53
54 The maximum load average can also be set on the command line using
55 commands like this:
56
57 fossil set max-loadavg 1.5
58 fossil all set max-loadavg 1.5
59
60 The second form is especially useful for changing the maximum load
61 average simultaneously on a large number of repositories.
62
63 Note that this load-average limiting feature is only available on
@@ -71,11 +71,11 @@
71 you are running a Fossil instance [inside a `chroot(2)`
72 jail](./chroot.md) and you have not mounted the `/proc` virtual file
73 system inside that jail. On the [self-hosting Fossil repositories][sh],
74 this was accomplished by adding a line to the `/etc/fstab` file:
75
76 chroot_jail_proc /home/www/proc proc ro 0 0
77
78 The `/home/www/proc` pathname should be adjusted so that the `/proc`
79 component is at the root of the chroot jail, of course.
80
81 To see if the load-average limiter is functional, visit the
82
--- www/loadmgmt.md
+++ www/loadmgmt.md
@@ -52,12 +52,12 @@
52 easily set it higher on a multi-core server.
53
54 The maximum load average can also be set on the command line using
55 commands like this:
56
57 fossil set max-loadavg 1.5
58 fossil all set max-loadavg 1.5
59
60 The second form is especially useful for changing the maximum load
61 average simultaneously on a large number of repositories.
62
63 Note that this load-average limiting feature is only available on
@@ -71,11 +71,11 @@
71 you are running a Fossil instance [inside a `chroot(2)`
72 jail](./chroot.md) and you have not mounted the `/proc` virtual file
73 system inside that jail. On the [self-hosting Fossil repositories][sh],
74 this was accomplished by adding a line to the `/etc/fstab` file:
75
76 chroot_jail_proc /home/www/proc proc ro 0 0
77
78 The `/home/www/proc` pathname should be adjusted so that the `/proc`
79 component is at the root of the chroot jail, of course.
80
81 To see if the load-average limiter is functional, visit the
82
--- www/server/any/cgi.md
+++ www/server/any/cgi.md
@@ -8,12 +8,12 @@
88
on the CGI protocol.
99
1010
To run Fossil as CGI, create a CGI script (here called "repo") in the
1111
CGI directory of your web server with content like this:
1212
13
- #!/usr/bin/fossil
14
- repository: /home/fossil/repo.fossil
13
+ #!/usr/bin/fossil
14
+ repository: /home/fossil/repo.fossil
1515
1616
Adjust the paths appropriately. It may be necessary to set certain
1717
permissions on this file or to modify an `.htaccess` file or make other
1818
server-specific changes. Consult the documentation for your particular
1919
web server. The following permissions are *normally* required, but,
@@ -57,13 +57,13 @@
5757
To serve multiple repositories from a directory using CGI, use the
5858
"directory:" tag in the CGI script rather than "repository:". You
5959
might also want to add a "notfound:" tag to tell where to redirect if
6060
the particular repository requested by the URL is not found:
6161
62
- #!/usr/bin/fossil
63
- directory: /home/fossil/repos
64
- notfound: http://url-to-go-to-if-repo-not-found/
62
+ #!/usr/bin/fossil
63
+ directory: /home/fossil/repos
64
+ notfound: http://url-to-go-to-if-repo-not-found/
6565
6666
Once deployed, a URL like: <b>http://mydomain.org/cgi-bin/repo/XYZ</b>
6767
will serve up the repository `/home/fossil/repos/XYZ.fossil` if it
6868
exists.
6969
@@ -79,14 +79,14 @@
7979
However, Fossil in CGI mode needs it in order to generate the correct links.
8080
8181
Apache can be instructed to pass this parameter further to the CGI scripts for
8282
TLS connections with a stanza like
8383
84
- SetEnvIf X-Forwarded-Proto "https" HTTPS=on
85
-
84
+ SetEnvIf X-Forwarded-Proto "https" HTTPS=on
85
+
8686
in its config file section for CGI, provided that
8787
88
- proxy_set_header X-Forwarded-Proto $scheme;
89
-
88
+ proxy_set_header X-Forwarded-Proto $scheme;
89
+
9090
has been be added in the relevant proxying section of the Nginx config file.
9191
9292
*[Return to the top-level Fossil server article.](../)*
9393
--- www/server/any/cgi.md
+++ www/server/any/cgi.md
@@ -8,12 +8,12 @@
8 on the CGI protocol.
9
10 To run Fossil as CGI, create a CGI script (here called "repo") in the
11 CGI directory of your web server with content like this:
12
13 #!/usr/bin/fossil
14 repository: /home/fossil/repo.fossil
15
16 Adjust the paths appropriately. It may be necessary to set certain
17 permissions on this file or to modify an `.htaccess` file or make other
18 server-specific changes. Consult the documentation for your particular
19 web server. The following permissions are *normally* required, but,
@@ -57,13 +57,13 @@
57 To serve multiple repositories from a directory using CGI, use the
58 "directory:" tag in the CGI script rather than "repository:". You
59 might also want to add a "notfound:" tag to tell where to redirect if
60 the particular repository requested by the URL is not found:
61
62 #!/usr/bin/fossil
63 directory: /home/fossil/repos
64 notfound: http://url-to-go-to-if-repo-not-found/
65
66 Once deployed, a URL like: <b>http://mydomain.org/cgi-bin/repo/XYZ</b>
67 will serve up the repository `/home/fossil/repos/XYZ.fossil` if it
68 exists.
69
@@ -79,14 +79,14 @@
79 However, Fossil in CGI mode needs it in order to generate the correct links.
80
81 Apache can be instructed to pass this parameter further to the CGI scripts for
82 TLS connections with a stanza like
83
84 SetEnvIf X-Forwarded-Proto "https" HTTPS=on
85
86 in its config file section for CGI, provided that
87
88 proxy_set_header X-Forwarded-Proto $scheme;
89
90 has been be added in the relevant proxying section of the Nginx config file.
91
92 *[Return to the top-level Fossil server article.](../)*
93
--- www/server/any/cgi.md
+++ www/server/any/cgi.md
@@ -8,12 +8,12 @@
8 on the CGI protocol.
9
10 To run Fossil as CGI, create a CGI script (here called "repo") in the
11 CGI directory of your web server with content like this:
12
13 #!/usr/bin/fossil
14 repository: /home/fossil/repo.fossil
15
16 Adjust the paths appropriately. It may be necessary to set certain
17 permissions on this file or to modify an `.htaccess` file or make other
18 server-specific changes. Consult the documentation for your particular
19 web server. The following permissions are *normally* required, but,
@@ -57,13 +57,13 @@
57 To serve multiple repositories from a directory using CGI, use the
58 "directory:" tag in the CGI script rather than "repository:". You
59 might also want to add a "notfound:" tag to tell where to redirect if
60 the particular repository requested by the URL is not found:
61
62 #!/usr/bin/fossil
63 directory: /home/fossil/repos
64 notfound: http://url-to-go-to-if-repo-not-found/
65
66 Once deployed, a URL like: <b>http://mydomain.org/cgi-bin/repo/XYZ</b>
67 will serve up the repository `/home/fossil/repos/XYZ.fossil` if it
68 exists.
69
@@ -79,14 +79,14 @@
79 However, Fossil in CGI mode needs it in order to generate the correct links.
80
81 Apache can be instructed to pass this parameter further to the CGI scripts for
82 TLS connections with a stanza like
83
84 SetEnvIf X-Forwarded-Proto "https" HTTPS=on
85
86 in its config file section for CGI, provided that
87
88 proxy_set_header X-Forwarded-Proto $scheme;
89
90 has been be added in the relevant proxying section of the Nginx config file.
91
92 *[Return to the top-level Fossil server article.](../)*
93
--- www/server/any/http-over-ssh.md
+++ www/server/any/http-over-ssh.md
@@ -15,15 +15,15 @@
1515
1616
Put something like the following into the `sshd_config` file on the
1717
Fossil repository server:
1818
1919
``` ssh-config
20
- Match Group fossil
21
- X11Forwarding no
22
- AllowTcpForwarding no
23
- AllowAgentForwarding no
24
- ForceCommand /home/fossil/bin/wrapper
20
+Match Group fossil
21
+ X11Forwarding no
22
+ AllowTcpForwarding no
23
+ AllowAgentForwarding no
24
+ ForceCommand /home/fossil/bin/wrapper
2525
```
2626
2727
This file is usually found in `/etc/ssh`, but some OSes put it
2828
elsewhere.
2929
@@ -30,11 +30,11 @@
3030
The first line presumes that we will put all users who need to use our
3131
Fossil repositories into the `fossil` group, as we will do
3232
[below](#perms). You could instead say something like:
3333
3434
``` ssh-config
35
- Match User alice,bob,carol,dave
35
+Match User alice,bob,carol,dave
3636
```
3737
3838
You have to list the users allowed to use Fossil in this case because
3939
your system likely has a system administrator that uses SSH for remote
4040
shell access, so you want to *exclude* that user from the list. For the
@@ -42,11 +42,11 @@
4242
a `Match` block of some sort.
4343
4444
You could instead list the exceptions:
4545
4646
``` ssh-config
47
- Match User !evi
47
+Match User !evi
4848
```
4949
5050
This would permit only [Evi the System Administrator][evi] to bypass this
5151
mechanism.
5252
@@ -68,16 +68,16 @@
6868
and rewrite other parts to make this work.
6969
7070
Here is a simpler variant of Andy’s original wrapper script:
7171
7272
``` sh
73
- #!/bin/bash
74
- set -- $SSH_ORIGINAL_COMMAND
75
- while [ $# -gt 1 ] ; do shift ; done
76
- export REMOTE_USER="$USER"
77
- ROOT=/home/fossil
78
- exec "$ROOT/bin/fossil" http "$ROOT/museum/$(/bin/basename "$1")"
73
+#!/bin/bash
74
+set -- $SSH_ORIGINAL_COMMAND
75
+while [ $# -gt 1 ] ; do shift ; done
76
+export REMOTE_USER="$USER"
77
+ROOT=/home/fossil
78
+exec "$ROOT/bin/fossil" http "$ROOT/museum/$(/bin/basename "$1")"
7979
```
8080
8181
The substantive changes are:
8282
8383
1. Move the command rewriting bits to the start.
@@ -104,11 +104,11 @@
104104
check the absolute paths for local correctness: is `/bin/basename`
105105
installed on your system, for example?
106106
107107
Under this scheme, you clone with a command like:
108108
109
- $ fossil clone ssh://HOST/repo.fossil
109
+ $ fossil clone ssh://HOST/repo.fossil
110110
111111
This will clone the remote `/home/fossil/museum/repo.fossil` repository
112112
to your local machine under the same name and open it into a “`repo/`”
113113
subdirectory. Notice that we didn’t have to give the `museum/` part of
114114
the path: it’s implicit per point #3 above.
@@ -129,20 +129,20 @@
129129
repositories are stored.
130130
131131
You can achieve all of this on a Linux box with:
132132
133133
``` shell
134
- sudo adduser fossil
135
- for u in alice bob carol dave ; do
136
- sudo adduser $u
137
- sudo gpasswd -a fossil $u
138
- done
139
- sudo -i -u fossil
140
- chmod 710 .
141
- mkdir -m 750 bin
142
- mkdir -m 770 museum
143
- ln -s /usr/local/bin/fossil bin
134
+sudo adduser fossil
135
+for u in alice bob carol dave ; do
136
+ sudo adduser $u
137
+ sudo gpasswd -a fossil $u
138
+done
139
+sudo -i -u fossil
140
+chmod 710 .
141
+mkdir -m 750 bin
142
+mkdir -m 770 museum
143
+ln -s /usr/local/bin/fossil bin
144144
```
145145
146146
You then need to copy the Fossil repositories into `~fossil/museum` and
147147
make them readable and writable by group `fossil`. These repositories
148148
presumably already have Fossil users configured, with the necessary
@@ -153,12 +153,12 @@
153153
Fossil only pays attention to this environment variable in certain
154154
contexts, of which “`fossil http`” is not one. Run this command against
155155
each repo to allow that:
156156
157157
``` shell
158
- echo "INSERT OR REPLACE INTO config VALUES ('remote_user_ok',1,strftime('%s','now'));" |
159
- fossil sql -R museum/repo.fossil
158
+echo "INSERT OR REPLACE INTO config VALUES ('remote_user_ok',1,strftime('%s','now'));" |
159
+fossil sql -R museum/repo.fossil
160160
```
161161
162162
Now you can configure SSH authentication for each user. Since Fossil’s
163163
password-saving feature doesn’t work in this case, I suggest setting up
164164
SSH keys via `~USER/.ssh/authorized_keys` since the SSH authentication
165165
--- www/server/any/http-over-ssh.md
+++ www/server/any/http-over-ssh.md
@@ -15,15 +15,15 @@
15
16 Put something like the following into the `sshd_config` file on the
17 Fossil repository server:
18
19 ``` ssh-config
20 Match Group fossil
21 X11Forwarding no
22 AllowTcpForwarding no
23 AllowAgentForwarding no
24 ForceCommand /home/fossil/bin/wrapper
25 ```
26
27 This file is usually found in `/etc/ssh`, but some OSes put it
28 elsewhere.
29
@@ -30,11 +30,11 @@
30 The first line presumes that we will put all users who need to use our
31 Fossil repositories into the `fossil` group, as we will do
32 [below](#perms). You could instead say something like:
33
34 ``` ssh-config
35 Match User alice,bob,carol,dave
36 ```
37
38 You have to list the users allowed to use Fossil in this case because
39 your system likely has a system administrator that uses SSH for remote
40 shell access, so you want to *exclude* that user from the list. For the
@@ -42,11 +42,11 @@
42 a `Match` block of some sort.
43
44 You could instead list the exceptions:
45
46 ``` ssh-config
47 Match User !evi
48 ```
49
50 This would permit only [Evi the System Administrator][evi] to bypass this
51 mechanism.
52
@@ -68,16 +68,16 @@
68 and rewrite other parts to make this work.
69
70 Here is a simpler variant of Andy’s original wrapper script:
71
72 ``` sh
73 #!/bin/bash
74 set -- $SSH_ORIGINAL_COMMAND
75 while [ $# -gt 1 ] ; do shift ; done
76 export REMOTE_USER="$USER"
77 ROOT=/home/fossil
78 exec "$ROOT/bin/fossil" http "$ROOT/museum/$(/bin/basename "$1")"
79 ```
80
81 The substantive changes are:
82
83 1. Move the command rewriting bits to the start.
@@ -104,11 +104,11 @@
104 check the absolute paths for local correctness: is `/bin/basename`
105 installed on your system, for example?
106
107 Under this scheme, you clone with a command like:
108
109 $ fossil clone ssh://HOST/repo.fossil
110
111 This will clone the remote `/home/fossil/museum/repo.fossil` repository
112 to your local machine under the same name and open it into a “`repo/`”
113 subdirectory. Notice that we didn’t have to give the `museum/` part of
114 the path: it’s implicit per point #3 above.
@@ -129,20 +129,20 @@
129 repositories are stored.
130
131 You can achieve all of this on a Linux box with:
132
133 ``` shell
134 sudo adduser fossil
135 for u in alice bob carol dave ; do
136 sudo adduser $u
137 sudo gpasswd -a fossil $u
138 done
139 sudo -i -u fossil
140 chmod 710 .
141 mkdir -m 750 bin
142 mkdir -m 770 museum
143 ln -s /usr/local/bin/fossil bin
144 ```
145
146 You then need to copy the Fossil repositories into `~fossil/museum` and
147 make them readable and writable by group `fossil`. These repositories
148 presumably already have Fossil users configured, with the necessary
@@ -153,12 +153,12 @@
153 Fossil only pays attention to this environment variable in certain
154 contexts, of which “`fossil http`” is not one. Run this command against
155 each repo to allow that:
156
157 ``` shell
158 echo "INSERT OR REPLACE INTO config VALUES ('remote_user_ok',1,strftime('%s','now'));" |
159 fossil sql -R museum/repo.fossil
160 ```
161
162 Now you can configure SSH authentication for each user. Since Fossil’s
163 password-saving feature doesn’t work in this case, I suggest setting up
164 SSH keys via `~USER/.ssh/authorized_keys` since the SSH authentication
165
--- www/server/any/http-over-ssh.md
+++ www/server/any/http-over-ssh.md
@@ -15,15 +15,15 @@
15
16 Put something like the following into the `sshd_config` file on the
17 Fossil repository server:
18
19 ``` ssh-config
20 Match Group fossil
21 X11Forwarding no
22 AllowTcpForwarding no
23 AllowAgentForwarding no
24 ForceCommand /home/fossil/bin/wrapper
25 ```
26
27 This file is usually found in `/etc/ssh`, but some OSes put it
28 elsewhere.
29
@@ -30,11 +30,11 @@
30 The first line presumes that we will put all users who need to use our
31 Fossil repositories into the `fossil` group, as we will do
32 [below](#perms). You could instead say something like:
33
34 ``` ssh-config
35 Match User alice,bob,carol,dave
36 ```
37
38 You have to list the users allowed to use Fossil in this case because
39 your system likely has a system administrator that uses SSH for remote
40 shell access, so you want to *exclude* that user from the list. For the
@@ -42,11 +42,11 @@
42 a `Match` block of some sort.
43
44 You could instead list the exceptions:
45
46 ``` ssh-config
47 Match User !evi
48 ```
49
50 This would permit only [Evi the System Administrator][evi] to bypass this
51 mechanism.
52
@@ -68,16 +68,16 @@
68 and rewrite other parts to make this work.
69
70 Here is a simpler variant of Andy’s original wrapper script:
71
72 ``` sh
73 #!/bin/bash
74 set -- $SSH_ORIGINAL_COMMAND
75 while [ $# -gt 1 ] ; do shift ; done
76 export REMOTE_USER="$USER"
77 ROOT=/home/fossil
78 exec "$ROOT/bin/fossil" http "$ROOT/museum/$(/bin/basename "$1")"
79 ```
80
81 The substantive changes are:
82
83 1. Move the command rewriting bits to the start.
@@ -104,11 +104,11 @@
104 check the absolute paths for local correctness: is `/bin/basename`
105 installed on your system, for example?
106
107 Under this scheme, you clone with a command like:
108
109 $ fossil clone ssh://HOST/repo.fossil
110
111 This will clone the remote `/home/fossil/museum/repo.fossil` repository
112 to your local machine under the same name and open it into a “`repo/`”
113 subdirectory. Notice that we didn’t have to give the `museum/` part of
114 the path: it’s implicit per point #3 above.
@@ -129,20 +129,20 @@
129 repositories are stored.
130
131 You can achieve all of this on a Linux box with:
132
133 ``` shell
134 sudo adduser fossil
135 for u in alice bob carol dave ; do
136 sudo adduser $u
137 sudo gpasswd -a fossil $u
138 done
139 sudo -i -u fossil
140 chmod 710 .
141 mkdir -m 750 bin
142 mkdir -m 770 museum
143 ln -s /usr/local/bin/fossil bin
144 ```
145
146 You then need to copy the Fossil repositories into `~fossil/museum` and
147 make them readable and writable by group `fossil`. These repositories
148 presumably already have Fossil users configured, with the necessary
@@ -153,12 +153,12 @@
153 Fossil only pays attention to this environment variable in certain
154 contexts, of which “`fossil http`” is not one. Run this command against
155 each repo to allow that:
156
157 ``` shell
158 echo "INSERT OR REPLACE INTO config VALUES ('remote_user_ok',1,strftime('%s','now'));" |
159 fossil sql -R museum/repo.fossil
160 ```
161
162 Now you can configure SSH authentication for each user. Since Fossil’s
163 password-saving feature doesn’t work in this case, I suggest setting up
164 SSH keys via `~USER/.ssh/authorized_keys` since the SSH authentication
165
--- www/server/any/inetd.md
+++ www/server/any/inetd.md
@@ -2,11 +2,11 @@
22
33
A Fossil server can be launched on-demand by `inetd` by using the
44
[`fossil http`](/help/http) command. To do so, add a line like the
55
following to its configuration file, typically `/etc/inetd.conf`:
66
7
- 80 stream tcp nowait.1000 root /usr/bin/fossil /usr/bin/fossil http /home/fossil/repo.fossil
7
+ 80 stream tcp nowait.1000 root /usr/bin/fossil /usr/bin/fossil http /home/fossil/repo.fossil
88
99
In this example, you are telling `inetd` that when an incoming
1010
connection appears on TCP port 80 that it should launch the program
1111
`/usr/bin/fossil` with the arguments shown. Obviously you will need to
1212
modify the pathnames for your particular setup. The final argument is
@@ -17,11 +17,11 @@
1717
specification must be a symbolic name and cannot be numeric, add the
1818
desired name and port to `/etc/services`. For example, if you want your
1919
Fossil server running on TCP port 12345 instead of 80, you will need to
2020
add:
2121
22
- fossil 12345/tcp # fossil server
22
+ fossil 12345/tcp # fossil server
2323
2424
and use the symbolic name “`fossil`” instead of the numeric TCP port
2525
number (“12345” in the above example) in `inetd.conf`.
2626
2727
Notice that we configured `inetd` to launch Fossil as root. See the
2828
--- www/server/any/inetd.md
+++ www/server/any/inetd.md
@@ -2,11 +2,11 @@
2
3 A Fossil server can be launched on-demand by `inetd` by using the
4 [`fossil http`](/help/http) command. To do so, add a line like the
5 following to its configuration file, typically `/etc/inetd.conf`:
6
7 80 stream tcp nowait.1000 root /usr/bin/fossil /usr/bin/fossil http /home/fossil/repo.fossil
8
9 In this example, you are telling `inetd` that when an incoming
10 connection appears on TCP port 80 that it should launch the program
11 `/usr/bin/fossil` with the arguments shown. Obviously you will need to
12 modify the pathnames for your particular setup. The final argument is
@@ -17,11 +17,11 @@
17 specification must be a symbolic name and cannot be numeric, add the
18 desired name and port to `/etc/services`. For example, if you want your
19 Fossil server running on TCP port 12345 instead of 80, you will need to
20 add:
21
22 fossil 12345/tcp # fossil server
23
24 and use the symbolic name “`fossil`” instead of the numeric TCP port
25 number (“12345” in the above example) in `inetd.conf`.
26
27 Notice that we configured `inetd` to launch Fossil as root. See the
28
--- www/server/any/inetd.md
+++ www/server/any/inetd.md
@@ -2,11 +2,11 @@
2
3 A Fossil server can be launched on-demand by `inetd` by using the
4 [`fossil http`](/help/http) command. To do so, add a line like the
5 following to its configuration file, typically `/etc/inetd.conf`:
6
7 80 stream tcp nowait.1000 root /usr/bin/fossil /usr/bin/fossil http /home/fossil/repo.fossil
8
9 In this example, you are telling `inetd` that when an incoming
10 connection appears on TCP port 80 that it should launch the program
11 `/usr/bin/fossil` with the arguments shown. Obviously you will need to
12 modify the pathnames for your particular setup. The final argument is
@@ -17,11 +17,11 @@
17 specification must be a symbolic name and cannot be numeric, add the
18 desired name and port to `/etc/services`. For example, if you want your
19 Fossil server running on TCP port 12345 instead of 80, you will need to
20 add:
21
22 fossil 12345/tcp # fossil server
23
24 and use the symbolic name “`fossil`” instead of the numeric TCP port
25 number (“12345” in the above example) in `inetd.conf`.
26
27 Notice that we configured `inetd` to launch Fossil as root. See the
28
--- www/server/any/none.md
+++ www/server/any/none.md
@@ -28,19 +28,19 @@
2828
2929
You can omit the _REPOSITORY_ argument if you run one of the above
3030
commands from within a Fossil checkout directory to serve that
3131
repository:
3232
33
- $ fossil ui # or...
34
- $ fossil server
33
+ $ fossil ui # or...
34
+ $ fossil server
3535
3636
You can abbreviate Fossil sub-commands as long as they are unambiguous.
3737
“`server`” can currently be as short as “`ser`”.
3838
3939
You can serve a directory containing multiple `*.fossil` files like so:
4040
41
- $ fossil server --port 9000 --repolist /path/to/repo/dir
41
+ $ fossil server --port 9000 --repolist /path/to/repo/dir
4242
4343
There is an [example script](/file/tools/fslsrv) in the Fossil
4444
distribution that wraps `fossil server` to produce more complicated
4545
effects. Feel free to take it, study it, and modify it to suit your
4646
local needs.
4747
--- www/server/any/none.md
+++ www/server/any/none.md
@@ -28,19 +28,19 @@
28
29 You can omit the _REPOSITORY_ argument if you run one of the above
30 commands from within a Fossil checkout directory to serve that
31 repository:
32
33 $ fossil ui # or...
34 $ fossil server
35
36 You can abbreviate Fossil sub-commands as long as they are unambiguous.
37 “`server`” can currently be as short as “`ser`”.
38
39 You can serve a directory containing multiple `*.fossil` files like so:
40
41 $ fossil server --port 9000 --repolist /path/to/repo/dir
42
43 There is an [example script](/file/tools/fslsrv) in the Fossil
44 distribution that wraps `fossil server` to produce more complicated
45 effects. Feel free to take it, study it, and modify it to suit your
46 local needs.
47
--- www/server/any/none.md
+++ www/server/any/none.md
@@ -28,19 +28,19 @@
28
29 You can omit the _REPOSITORY_ argument if you run one of the above
30 commands from within a Fossil checkout directory to serve that
31 repository:
32
33 $ fossil ui # or...
34 $ fossil server
35
36 You can abbreviate Fossil sub-commands as long as they are unambiguous.
37 “`server`” can currently be as short as “`ser`”.
38
39 You can serve a directory containing multiple `*.fossil` files like so:
40
41 $ fossil server --port 9000 --repolist /path/to/repo/dir
42
43 There is an [example script](/file/tools/fslsrv) in the Fossil
44 distribution that wraps `fossil server` to produce more complicated
45 effects. Feel free to take it, study it, and modify it to suit your
46 local needs.
47
--- www/server/any/scgi.md
+++ www/server/any/scgi.md
@@ -9,15 +9,15 @@
99
This can be used with a web server such as [nginx](http://nginx.org)
1010
which does not support [Fossil’s CGI mode](./cgi.md).
1111
1212
A basic nginx configuration to support SCGI with Fossil looks like this:
1313
14
- location /code/ {
15
- include scgi_params;
16
- scgi_param SCRIPT_NAME "/code";
17
- scgi_pass localhost:9000;
18
- }
14
+ location /code/ {
15
+ include scgi_params;
16
+ scgi_param SCRIPT_NAME "/code";
17
+ scgi_pass localhost:9000;
18
+ }
1919
2020
The `scgi_params` file comes with nginx, and it simply translates nginx
2121
internal variables to `scgi_param` directives to create SCGI environment
2222
variables for the proxied program; in this case, Fossil. Our explicit
2323
`scgi_param` call to define `SCRIPT_NAME` adds one more variable to this
@@ -28,11 +28,11 @@
2828
2929
The final directive simply tells nginx to proxy all calls to URLs under
3030
`/code` down to an SCGI program on TCP port 9000. We can temporarily
3131
set Fossil up as a server on that port like so:
3232
33
- $ fossil server /path/to/repo.fossil --scgi --localhost --port 9000 &
33
+ $ fossil server /path/to/repo.fossil --scgi --localhost --port 9000 &
3434
3535
The `--scgi` option switches Fossil into SCGI mode from its default,
3636
which is [stand-alone HTTP server mode](./none.md). All of the other
3737
options discussed in that linked document — such as the ability to serve
3838
a directory full of Fossil repositories rather than just a single
3939
--- www/server/any/scgi.md
+++ www/server/any/scgi.md
@@ -9,15 +9,15 @@
9 This can be used with a web server such as [nginx](http://nginx.org)
10 which does not support [Fossil’s CGI mode](./cgi.md).
11
12 A basic nginx configuration to support SCGI with Fossil looks like this:
13
14 location /code/ {
15 include scgi_params;
16 scgi_param SCRIPT_NAME "/code";
17 scgi_pass localhost:9000;
18 }
19
20 The `scgi_params` file comes with nginx, and it simply translates nginx
21 internal variables to `scgi_param` directives to create SCGI environment
22 variables for the proxied program; in this case, Fossil. Our explicit
23 `scgi_param` call to define `SCRIPT_NAME` adds one more variable to this
@@ -28,11 +28,11 @@
28
29 The final directive simply tells nginx to proxy all calls to URLs under
30 `/code` down to an SCGI program on TCP port 9000. We can temporarily
31 set Fossil up as a server on that port like so:
32
33 $ fossil server /path/to/repo.fossil --scgi --localhost --port 9000 &
34
35 The `--scgi` option switches Fossil into SCGI mode from its default,
36 which is [stand-alone HTTP server mode](./none.md). All of the other
37 options discussed in that linked document — such as the ability to serve
38 a directory full of Fossil repositories rather than just a single
39
--- www/server/any/scgi.md
+++ www/server/any/scgi.md
@@ -9,15 +9,15 @@
9 This can be used with a web server such as [nginx](http://nginx.org)
10 which does not support [Fossil’s CGI mode](./cgi.md).
11
12 A basic nginx configuration to support SCGI with Fossil looks like this:
13
14 location /code/ {
15 include scgi_params;
16 scgi_param SCRIPT_NAME "/code";
17 scgi_pass localhost:9000;
18 }
19
20 The `scgi_params` file comes with nginx, and it simply translates nginx
21 internal variables to `scgi_param` directives to create SCGI environment
22 variables for the proxied program; in this case, Fossil. Our explicit
23 `scgi_param` call to define `SCRIPT_NAME` adds one more variable to this
@@ -28,11 +28,11 @@
28
29 The final directive simply tells nginx to proxy all calls to URLs under
30 `/code` down to an SCGI program on TCP port 9000. We can temporarily
31 set Fossil up as a server on that port like so:
32
33 $ fossil server /path/to/repo.fossil --scgi --localhost --port 9000 &
34
35 The `--scgi` option switches Fossil into SCGI mode from its default,
36 which is [stand-alone HTTP server mode](./none.md). All of the other
37 options discussed in that linked document — such as the ability to serve
38 a directory full of Fossil repositories rather than just a single
39
--- www/server/any/xinetd.md
+++ www/server/any/xinetd.md
@@ -6,19 +6,19 @@
66
77
The typical configuration file is either `/etc/xinetd.conf` or a subfile
88
in the `/etc/xinetd.d` directory. You need a configuration something
99
like this for Fossil:
1010
11
- service http
12
- {
13
- port = 80
14
- socket_type = stream
15
- wait = no
16
- user = root
17
- server = /usr/bin/fossil
18
- server_args = http /home/fossil/repos/
19
- }
11
+ service http
12
+ {
13
+ port = 80
14
+ socket_type = stream
15
+ wait = no
16
+ user = root
17
+ server = /usr/bin/fossil
18
+ server_args = http /home/fossil/repos/
19
+ }
2020
2121
This example configures Fossil to serve multiple repositories under the
2222
`/home/fossil/repos/` directory.
2323
2424
Beyond this, see the general commentary in our article on [the `inetd`
2525
--- www/server/any/xinetd.md
+++ www/server/any/xinetd.md
@@ -6,19 +6,19 @@
6
7 The typical configuration file is either `/etc/xinetd.conf` or a subfile
8 in the `/etc/xinetd.d` directory. You need a configuration something
9 like this for Fossil:
10
11 service http
12 {
13 port = 80
14 socket_type = stream
15 wait = no
16 user = root
17 server = /usr/bin/fossil
18 server_args = http /home/fossil/repos/
19 }
20
21 This example configures Fossil to serve multiple repositories under the
22 `/home/fossil/repos/` directory.
23
24 Beyond this, see the general commentary in our article on [the `inetd`
25
--- www/server/any/xinetd.md
+++ www/server/any/xinetd.md
@@ -6,19 +6,19 @@
6
7 The typical configuration file is either `/etc/xinetd.conf` or a subfile
8 in the `/etc/xinetd.d` directory. You need a configuration something
9 like this for Fossil:
10
11 service http
12 {
13 port = 80
14 socket_type = stream
15 wait = no
16 user = root
17 server = /usr/bin/fossil
18 server_args = http /home/fossil/repos/
19 }
20
21 This example configures Fossil to serve multiple repositories under the
22 `/home/fossil/repos/` directory.
23
24 Beyond this, see the general commentary in our article on [the `inetd`
25
--- www/server/debian/nginx.md
+++ www/server/debian/nginx.md
@@ -101,11 +101,11 @@
101101
## <a id="deps"></a>Installing the Dependencies
102102
103103
The first step is to install some non-default packages we’ll need. SSH into
104104
your server, then say:
105105
106
- $ sudo apt install fossil nginx
106
+ $ sudo apt install fossil nginx
107107
108108
You can leave “`fossil`” out of that if you’re building Fossil from
109109
source to get a more up-to-date version than is shipped with the host
110110
OS.
111111
@@ -131,12 +131,12 @@
131131
On Debian and Ubuntu systems the primary user-level configuration file
132132
for nginx is `/etc/nginx/sites-enabled/default`. I recommend that this
133133
file contain only a list of include statements, one for each site that
134134
server hosts:
135135
136
- include local/example.com
137
- include local/foo.net
136
+ include local/example.com
137
+ include local/foo.net
138138
139139
Those files then each define one domain’s configuration. Here,
140140
`/etc/nginx/local/example.com` contains the configuration for
141141
`*.example.com` and its alias `*.example.net`; and `local/foo.net`
142142
contains the configuration for `*.foo.net`.
@@ -197,13 +197,13 @@
197197
configuration for SCGI][scgii], showing off a few ideas you might want to
198198
try on your own site, such as static asset proxying.
199199
200200
You also need a `local/code` file containing:
201201
202
- include scgi_params;
203
- scgi_pass 127.0.0.1:12345;
204
- scgi_param SCRIPT_NAME "/code";
202
+ include scgi_params;
203
+ scgi_pass 127.0.0.1:12345;
204
+ scgi_param SCRIPT_NAME "/code";
205205
206206
We separate that out because nginx refuses to inherit certain settings
207207
between nested location blocks, so rather than repeat them, we extract
208208
them to this separate file and include it from both locations where it’s
209209
needed. You see this above where we set far-future expiration dates on
@@ -213,16 +213,16 @@
213213
Fossil-based site considerably faster.
214214
215215
Similarly, the `local/generic` file referenced above helps us reduce unnecessary
216216
repetition among the multiple sites this configuration hosts:
217217
218
- root /var/www/$host;
218
+ root /var/www/$host;
219219
220
- listen 80;
221
- listen [::]:80;
220
+ listen 80;
221
+ listen [::]:80;
222222
223
- charset utf-8;
223
+ charset utf-8;
224224
225225
There are some configuration directives that nginx refuses to substitute
226226
variables into, citing performance considerations, so there is a limit
227227
to how much repetition you can squeeze out this way. One such example
228228
are the `access_log` and `error_log` directives, which follow an obvious
@@ -246,14 +246,14 @@
246246
247247
However, it is still worth showing the proper method of proxying
248248
Fossil’s HTTP server through nginx if only to make reading nginx
249249
documentation on other sites easier:
250250
251
- location /code {
252
- rewrite ^/code(/.*) $1 break;
253
- proxy_pass http://127.0.0.1:12345;
254
- }
251
+ location /code {
252
+ rewrite ^/code(/.*) $1 break;
253
+ proxy_pass http://127.0.0.1:12345;
254
+ }
255255
256256
The most common thing people get wrong when hand-rolling a configuration
257257
like this is to get the slashes wrong. Fossil is sensitive to this. For
258258
instance, Fossil will not collapse double slashes down to a single
259259
slash, as some other HTTP servers will.
@@ -267,12 +267,12 @@
267267
a problem, but when sending [unversioned content][uv], it uses a single
268268
message for the entire file. Therefore, if you will be storing files
269269
larger than this limit as unversioned content, you need to raise the
270270
limit. Within the `location` block:
271271
272
- # Allow large unversioned file uploads, such as PDFs
273
- client_max_body_size 20M;
272
+ # Allow large unversioned file uploads, such as PDFs
273
+ client_max_body_size 20M;
274274
275275
[uv]: ../../unvers.wiki
276276
277277
278278
## <a id="fail2ban"></a> Integrating `fail2ban`
@@ -285,32 +285,32 @@
285285
Fossil behind an nginx proxy, we convert these failures to log file
286286
form, which `fail2ban` is designed to handle.
287287
288288
First, install `fail2ban`, if you haven’t already:
289289
290
- sudo apt install fail2ban
290
+ sudo apt install fail2ban
291291
292292
We’d like `fail2ban` to react to Fossil `/login` failures. The stock
293293
configuration of `fail2ban` only detects a few common sorts of SSH
294294
attacks by default, and its included (but disabled) nginx attack
295295
detectors don’t include one that knows how to detect an attack on
296296
Fossil. We have to teach it by putting the following into
297297
`/etc/fail2ban/filter.d/nginx-fossil-login.conf`:
298298
299
- [Definition]
300
- failregex = ^<HOST> - .*POST .*/login HTTP/..." 401
299
+ [Definition]
300
+ failregex = ^<HOST> - .*POST .*/login HTTP/..." 401
301301
302302
That teaches `fail2ban` how to recognize the errors logged by Fossil
303303
[as of 2.14](/info/39d7eb0e22). (Earlier versions of Fossil returned
304304
HTTP status code 200 for this, so you couldn’t distinguish a successful
305305
login from a failure.)
306306
307307
Then in `/etc/fail2ban/jail.local`, add this section:
308308
309
- [nginx-fossil-login]
310
- enabled = true
311
- logpath = /var/log/nginx/*-https-access.log
309
+ [nginx-fossil-login]
310
+ enabled = true
311
+ logpath = /var/log/nginx/*-https-access.log
312312
313313
The last line is the key: it tells `fail2ban` where we’ve put all of our
314314
per-repo access logs in the nginx config above.
315315
316316
There’s a [lot more you can do][dof2b], but that gets us out of scope of
@@ -338,44 +338,42 @@
338338
339339
You may wish to include something like this from each `server { }`
340340
block in your configuration to enable TLS in a common, secure way:
341341
342342
```
343
- # Tell nginx to accept TLS-encrypted HTTPS on the standard TCP port.
344
- listen 443 ssl;
345
- listen [::]:443 ssl;
346
-
347
- # Reference the TLS cert files produced by Certbot.
348
- ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
349
- ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
350
-
351
- # Load the Let's Encrypt Diffie-Hellman parameters generated for
352
- # this server. Without this, the server is vulnerable to Logjam.
353
- ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
354
-
355
- # Tighten things down further, per Qualys’ and Certbot’s advice.
356
- ssl_session_cache shared:le_nginx_SSL:1m;
357
- ssl_protocols TLSv1.2 TLSv1.3;
358
- ssl_prefer_server_ciphers on;
359
- ssl_session_timeout 1440m;
360
-
361
- # Offer OCSP certificate stapling.
362
- ssl_stapling on;
363
- ssl_stapling_verify on;
364
-
365
- # Enable HSTS.
366
- include local/enable-hsts;
343
+# Tell nginx to accept TLS-encrypted HTTPS on the standard TCP port.
344
+listen 443 ssl;
345
+listen [::]:443 ssl;
346
+
347
+# Reference the TLS cert files produced by Certbot.
348
+ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
349
+ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
350
+
351
+# Load the Let's Encrypt Diffie-Hellman parameters generated for
352
+# this server. Without this, the server is vulnerable to Logjam.
353
+ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
354
+
355
+# Tighten things down further, per Qualys’ and Certbot’s advice.
356
+ssl_session_cache shared:le_nginx_SSL:1m;
357
+ssl_protocols TLSv1.2 TLSv1.3;
358
+ssl_prefer_server_ciphers on;
359
+ssl_session_timeout 1440m;
360
+
361
+# Offer OCSP certificate stapling.
362
+ssl_stapling on;
363
+ssl_stapling_verify on;
364
+
365
+# Enable HSTS.
366
+include local/enable-hsts;
367367
```
368368
369369
The [HSTS] step is optional and should be applied only after due
370370
consideration, since it has the potential to lock users out of your
371371
site if you later change your mind on the TLS configuration.
372372
The `local/enable-hsts` file it references is simply:
373373
374
-```
375374
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
376
-```
377375
378376
It’s a separate file because nginx requires that headers like this be
379377
applied separately for each `location { }` block. We’ve therefore
380378
factored this out so you can `include` it everywhere you need it.
381379
382380
--- www/server/debian/nginx.md
+++ www/server/debian/nginx.md
@@ -101,11 +101,11 @@
101 ## <a id="deps"></a>Installing the Dependencies
102
103 The first step is to install some non-default packages we’ll need. SSH into
104 your server, then say:
105
106 $ sudo apt install fossil nginx
107
108 You can leave “`fossil`” out of that if you’re building Fossil from
109 source to get a more up-to-date version than is shipped with the host
110 OS.
111
@@ -131,12 +131,12 @@
131 On Debian and Ubuntu systems the primary user-level configuration file
132 for nginx is `/etc/nginx/sites-enabled/default`. I recommend that this
133 file contain only a list of include statements, one for each site that
134 server hosts:
135
136 include local/example.com
137 include local/foo.net
138
139 Those files then each define one domain’s configuration. Here,
140 `/etc/nginx/local/example.com` contains the configuration for
141 `*.example.com` and its alias `*.example.net`; and `local/foo.net`
142 contains the configuration for `*.foo.net`.
@@ -197,13 +197,13 @@
197 configuration for SCGI][scgii], showing off a few ideas you might want to
198 try on your own site, such as static asset proxying.
199
200 You also need a `local/code` file containing:
201
202 include scgi_params;
203 scgi_pass 127.0.0.1:12345;
204 scgi_param SCRIPT_NAME "/code";
205
206 We separate that out because nginx refuses to inherit certain settings
207 between nested location blocks, so rather than repeat them, we extract
208 them to this separate file and include it from both locations where it’s
209 needed. You see this above where we set far-future expiration dates on
@@ -213,16 +213,16 @@
213 Fossil-based site considerably faster.
214
215 Similarly, the `local/generic` file referenced above helps us reduce unnecessary
216 repetition among the multiple sites this configuration hosts:
217
218 root /var/www/$host;
219
220 listen 80;
221 listen [::]:80;
222
223 charset utf-8;
224
225 There are some configuration directives that nginx refuses to substitute
226 variables into, citing performance considerations, so there is a limit
227 to how much repetition you can squeeze out this way. One such example
228 are the `access_log` and `error_log` directives, which follow an obvious
@@ -246,14 +246,14 @@
246
247 However, it is still worth showing the proper method of proxying
248 Fossil’s HTTP server through nginx if only to make reading nginx
249 documentation on other sites easier:
250
251 location /code {
252 rewrite ^/code(/.*) $1 break;
253 proxy_pass http://127.0.0.1:12345;
254 }
255
256 The most common thing people get wrong when hand-rolling a configuration
257 like this is to get the slashes wrong. Fossil is sensitive to this. For
258 instance, Fossil will not collapse double slashes down to a single
259 slash, as some other HTTP servers will.
@@ -267,12 +267,12 @@
267 a problem, but when sending [unversioned content][uv], it uses a single
268 message for the entire file. Therefore, if you will be storing files
269 larger than this limit as unversioned content, you need to raise the
270 limit. Within the `location` block:
271
272 # Allow large unversioned file uploads, such as PDFs
273 client_max_body_size 20M;
274
275 [uv]: ../../unvers.wiki
276
277
278 ## <a id="fail2ban"></a> Integrating `fail2ban`
@@ -285,32 +285,32 @@
285 Fossil behind an nginx proxy, we convert these failures to log file
286 form, which `fail2ban` is designed to handle.
287
288 First, install `fail2ban`, if you haven’t already:
289
290 sudo apt install fail2ban
291
292 We’d like `fail2ban` to react to Fossil `/login` failures. The stock
293 configuration of `fail2ban` only detects a few common sorts of SSH
294 attacks by default, and its included (but disabled) nginx attack
295 detectors don’t include one that knows how to detect an attack on
296 Fossil. We have to teach it by putting the following into
297 `/etc/fail2ban/filter.d/nginx-fossil-login.conf`:
298
299 [Definition]
300 failregex = ^<HOST> - .*POST .*/login HTTP/..." 401
301
302 That teaches `fail2ban` how to recognize the errors logged by Fossil
303 [as of 2.14](/info/39d7eb0e22). (Earlier versions of Fossil returned
304 HTTP status code 200 for this, so you couldn’t distinguish a successful
305 login from a failure.)
306
307 Then in `/etc/fail2ban/jail.local`, add this section:
308
309 [nginx-fossil-login]
310 enabled = true
311 logpath = /var/log/nginx/*-https-access.log
312
313 The last line is the key: it tells `fail2ban` where we’ve put all of our
314 per-repo access logs in the nginx config above.
315
316 There’s a [lot more you can do][dof2b], but that gets us out of scope of
@@ -338,44 +338,42 @@
338
339 You may wish to include something like this from each `server { }`
340 block in your configuration to enable TLS in a common, secure way:
341
342 ```
343 # Tell nginx to accept TLS-encrypted HTTPS on the standard TCP port.
344 listen 443 ssl;
345 listen [::]:443 ssl;
346
347 # Reference the TLS cert files produced by Certbot.
348 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
349 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
350
351 # Load the Let's Encrypt Diffie-Hellman parameters generated for
352 # this server. Without this, the server is vulnerable to Logjam.
353 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
354
355 # Tighten things down further, per Qualys’ and Certbot’s advice.
356 ssl_session_cache shared:le_nginx_SSL:1m;
357 ssl_protocols TLSv1.2 TLSv1.3;
358 ssl_prefer_server_ciphers on;
359 ssl_session_timeout 1440m;
360
361 # Offer OCSP certificate stapling.
362 ssl_stapling on;
363 ssl_stapling_verify on;
364
365 # Enable HSTS.
366 include local/enable-hsts;
367 ```
368
369 The [HSTS] step is optional and should be applied only after due
370 consideration, since it has the potential to lock users out of your
371 site if you later change your mind on the TLS configuration.
372 The `local/enable-hsts` file it references is simply:
373
374 ```
375 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
376 ```
377
378 It’s a separate file because nginx requires that headers like this be
379 applied separately for each `location { }` block. We’ve therefore
380 factored this out so you can `include` it everywhere you need it.
381
382
--- www/server/debian/nginx.md
+++ www/server/debian/nginx.md
@@ -101,11 +101,11 @@
101 ## <a id="deps"></a>Installing the Dependencies
102
103 The first step is to install some non-default packages we’ll need. SSH into
104 your server, then say:
105
106 $ sudo apt install fossil nginx
107
108 You can leave “`fossil`” out of that if you’re building Fossil from
109 source to get a more up-to-date version than is shipped with the host
110 OS.
111
@@ -131,12 +131,12 @@
131 On Debian and Ubuntu systems the primary user-level configuration file
132 for nginx is `/etc/nginx/sites-enabled/default`. I recommend that this
133 file contain only a list of include statements, one for each site that
134 server hosts:
135
136 include local/example.com
137 include local/foo.net
138
139 Those files then each define one domain’s configuration. Here,
140 `/etc/nginx/local/example.com` contains the configuration for
141 `*.example.com` and its alias `*.example.net`; and `local/foo.net`
142 contains the configuration for `*.foo.net`.
@@ -197,13 +197,13 @@
197 configuration for SCGI][scgii], showing off a few ideas you might want to
198 try on your own site, such as static asset proxying.
199
200 You also need a `local/code` file containing:
201
202 include scgi_params;
203 scgi_pass 127.0.0.1:12345;
204 scgi_param SCRIPT_NAME "/code";
205
206 We separate that out because nginx refuses to inherit certain settings
207 between nested location blocks, so rather than repeat them, we extract
208 them to this separate file and include it from both locations where it’s
209 needed. You see this above where we set far-future expiration dates on
@@ -213,16 +213,16 @@
213 Fossil-based site considerably faster.
214
215 Similarly, the `local/generic` file referenced above helps us reduce unnecessary
216 repetition among the multiple sites this configuration hosts:
217
218 root /var/www/$host;
219
220 listen 80;
221 listen [::]:80;
222
223 charset utf-8;
224
225 There are some configuration directives that nginx refuses to substitute
226 variables into, citing performance considerations, so there is a limit
227 to how much repetition you can squeeze out this way. One such example
228 are the `access_log` and `error_log` directives, which follow an obvious
@@ -246,14 +246,14 @@
246
247 However, it is still worth showing the proper method of proxying
248 Fossil’s HTTP server through nginx if only to make reading nginx
249 documentation on other sites easier:
250
251 location /code {
252 rewrite ^/code(/.*) $1 break;
253 proxy_pass http://127.0.0.1:12345;
254 }
255
256 The most common thing people get wrong when hand-rolling a configuration
257 like this is to get the slashes wrong. Fossil is sensitive to this. For
258 instance, Fossil will not collapse double slashes down to a single
259 slash, as some other HTTP servers will.
@@ -267,12 +267,12 @@
267 a problem, but when sending [unversioned content][uv], it uses a single
268 message for the entire file. Therefore, if you will be storing files
269 larger than this limit as unversioned content, you need to raise the
270 limit. Within the `location` block:
271
272 # Allow large unversioned file uploads, such as PDFs
273 client_max_body_size 20M;
274
275 [uv]: ../../unvers.wiki
276
277
278 ## <a id="fail2ban"></a> Integrating `fail2ban`
@@ -285,32 +285,32 @@
285 Fossil behind an nginx proxy, we convert these failures to log file
286 form, which `fail2ban` is designed to handle.
287
288 First, install `fail2ban`, if you haven’t already:
289
290 sudo apt install fail2ban
291
292 We’d like `fail2ban` to react to Fossil `/login` failures. The stock
293 configuration of `fail2ban` only detects a few common sorts of SSH
294 attacks by default, and its included (but disabled) nginx attack
295 detectors don’t include one that knows how to detect an attack on
296 Fossil. We have to teach it by putting the following into
297 `/etc/fail2ban/filter.d/nginx-fossil-login.conf`:
298
299 [Definition]
300 failregex = ^<HOST> - .*POST .*/login HTTP/..." 401
301
302 That teaches `fail2ban` how to recognize the errors logged by Fossil
303 [as of 2.14](/info/39d7eb0e22). (Earlier versions of Fossil returned
304 HTTP status code 200 for this, so you couldn’t distinguish a successful
305 login from a failure.)
306
307 Then in `/etc/fail2ban/jail.local`, add this section:
308
309 [nginx-fossil-login]
310 enabled = true
311 logpath = /var/log/nginx/*-https-access.log
312
313 The last line is the key: it tells `fail2ban` where we’ve put all of our
314 per-repo access logs in the nginx config above.
315
316 There’s a [lot more you can do][dof2b], but that gets us out of scope of
@@ -338,44 +338,42 @@
338
339 You may wish to include something like this from each `server { }`
340 block in your configuration to enable TLS in a common, secure way:
341
342 ```
343 # Tell nginx to accept TLS-encrypted HTTPS on the standard TCP port.
344 listen 443 ssl;
345 listen [::]:443 ssl;
346
347 # Reference the TLS cert files produced by Certbot.
348 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
349 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
350
351 # Load the Let's Encrypt Diffie-Hellman parameters generated for
352 # this server. Without this, the server is vulnerable to Logjam.
353 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
354
355 # Tighten things down further, per Qualys’ and Certbot’s advice.
356 ssl_session_cache shared:le_nginx_SSL:1m;
357 ssl_protocols TLSv1.2 TLSv1.3;
358 ssl_prefer_server_ciphers on;
359 ssl_session_timeout 1440m;
360
361 # Offer OCSP certificate stapling.
362 ssl_stapling on;
363 ssl_stapling_verify on;
364
365 # Enable HSTS.
366 include local/enable-hsts;
367 ```
368
369 The [HSTS] step is optional and should be applied only after due
370 consideration, since it has the potential to lock users out of your
371 site if you later change your mind on the TLS configuration.
372 The `local/enable-hsts` file it references is simply:
373
 
374 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
 
375
376 It’s a separate file because nginx requires that headers like this be
377 applied separately for each `location { }` block. We’ve therefore
378 factored this out so you can `include` it everywhere you need it.
379
380
--- www/server/debian/service.md
+++ www/server/debian/service.md
@@ -53,22 +53,22 @@
5353
5454
To do this, write the following in
5555
`~/.local/share/systemd/user/fossil.service`:
5656
5757
```dosini
58
- [Unit]
59
- Description=Fossil user server
60
- After=network-online.target
61
-
62
- [Service]
63
- WorkingDirectory=/home/fossil/museum
64
- ExecStart=/home/fossil/bin/fossil server --port 9000 repo.fossil
65
- Restart=always
66
- RestartSec=3
67
-
68
- [Install]
69
- WantedBy=multi-user.target
58
+[Unit]
59
+Description=Fossil user server
60
+After=network-online.target
61
+
62
+[Service]
63
+WorkingDirectory=/home/fossil/museum
64
+ExecStart=/home/fossil/bin/fossil server --port 9000 repo.fossil
65
+Restart=always
66
+RestartSec=3
67
+
68
+[Install]
69
+WantedBy=multi-user.target
7070
```
7171
7272
Unlike with `inetd` and `xinetd`, we don’t need to tell `systemd` which
7373
user and group to run this service as, because we’ve installed it
7474
under the account we’re logged into, which `systemd` will use as the
@@ -90,15 +90,15 @@
9090
9191
Because we’ve set this up as a user service, the commands you give to
9292
manipulate the service vary somewhat from the sort you’re more likely to
9393
find online:
9494
95
- $ systemctl --user daemon-reload
96
- $ systemctl --user enable fossil
97
- $ systemctl --user start fossil
98
- $ systemctl --user status fossil -l
99
- $ systemctl --user stop fossil
95
+ $ systemctl --user daemon-reload
96
+ $ systemctl --user enable fossil
97
+ $ systemctl --user start fossil
98
+ $ systemctl --user status fossil -l
99
+ $ systemctl --user stop fossil
100100
101101
That is, we don’t need to talk to `systemd` with `sudo` privileges, but
102102
we do need to tell it to look at the user configuration rather than the
103103
system-level configuration.
104104
@@ -109,11 +109,11 @@
109109
On some `systemd` based OSes, user services only run while that user is
110110
logged in interactively. This is common on systems aiming to provide
111111
desktop environments, where this is the behavior you often want. To
112112
allow background services to continue to run after logout, say:
113113
114
- $ sudo loginctl enable-linger $USER
114
+ $ sudo loginctl enable-linger $USER
115115
116116
You can paste the command just like that into your terminal, since
117117
`$USER` will expand to your login name.
118118
119119
[scgi]: ../any/scgi.md
@@ -165,20 +165,20 @@
165165
166166
We first need to define the privileged socket listener by writing
167167
`/etc/systemd/system/fossil.socket`:
168168
169169
```dosini
170
- [Unit]
171
- Description=Fossil socket
172
-
173
- [Socket]
174
- Accept=yes
175
- ListenStream=80
176
- NoDelay=true
177
-
178
- [Install]
179
- WantedBy=sockets.target
170
+[Unit]
171
+Description=Fossil socket
172
+
173
+[Socket]
174
+Accept=yes
175
+ListenStream=80
176
+NoDelay=true
177
+
178
+[Install]
179
+WantedBy=sockets.target
180180
```
181181
182182
Note the change of configuration directory from the `~/.local` directory
183183
to the system level. We need to start this socket listener at the root
184184
level because of the low-numbered TCP port restriction we brought up
@@ -190,21 +190,21 @@
190190
191191
Next, create the service definition file in that same directory as
192192
`[email protected]`:
193193
194194
```dosini
195
- [Unit]
196
- Description=Fossil socket server
197
- After=network-online.target
198
-
199
- [Service]
200
- WorkingDirectory=/home/fossil/museum
201
- ExecStart=/home/fossil/bin/fossil http repo.fossil
202
- StandardInput=socket
203
-
204
- [Install]
205
- WantedBy=multi-user.target
195
+[Unit]
196
+Description=Fossil socket server
197
+After=network-online.target
198
+
199
+[Service]
200
+WorkingDirectory=/home/fossil/museum
201
+ExecStart=/home/fossil/bin/fossil http repo.fossil
202
+StandardInput=socket
203
+
204
+[Install]
205
+WantedBy=multi-user.target
206206
```
207207
208208
Notice that we haven’t told `systemd` which user and group to run Fossil
209209
under. Since this is a system-level service definition, that means it
210210
will run as root, which then causes Fossil to [automatically drop into a
@@ -217,34 +217,34 @@
217217
handles that single client’s request and then immediately shuts down.
218218
219219
Next, you need to tell `systemd` to reload its system-level
220220
configuration files and enable the listening socket:
221221
222
- $ sudo systemctl daemon-reload
223
- $ sudo systemctl enable fossil.socket
222
+ $ sudo systemctl daemon-reload
223
+ $ sudo systemctl enable fossil.socket
224224
225225
And now you can manipulate the socket listener:
226226
227
- $ sudo systemctl start fossil.socket
228
- $ sudo systemctl status -l fossil.socket
229
- $ sudo systemctl stop fossil.socket
227
+ $ sudo systemctl start fossil.socket
228
+ $ sudo systemctl status -l fossil.socket
229
+ $ sudo systemctl stop fossil.socket
230230
231231
Notice that we’re working with the *socket*, not the *service*. The fact
232232
that we’ve given them the same base name and marked the service as an
233233
instantiated service with the “`@`” notation allows `systemd` to
234234
automatically start an instance of the service each time a hit comes in
235235
on the socket that `systemd` is monitoring on Fossil’s behalf. To see
236236
this service instantiation at work, visit a long-running Fossil page
237237
(e.g. `/tarball`) and then give a command like this:
238238
239
- $ sudo systemctl --full | grep fossil
239
+ $ sudo systemctl --full | grep fossil
240240
241241
This will show information about the `fossil` socket and service
242242
instances, which should show your `/tarball` hit handler, if it’s still
243243
running:
244244
245
- [email protected]:80-127.0.0.1:38304.service
245
+ [email protected]:80-127.0.0.1:38304.service
246246
247247
You can feed that service instance description to a `systemctl kill`
248248
command to stop that single instance without restarting the whole
249249
`fossil` service, for example.
250250
251251
--- www/server/debian/service.md
+++ www/server/debian/service.md
@@ -53,22 +53,22 @@
53
54 To do this, write the following in
55 `~/.local/share/systemd/user/fossil.service`:
56
57 ```dosini
58 [Unit]
59 Description=Fossil user server
60 After=network-online.target
61
62 [Service]
63 WorkingDirectory=/home/fossil/museum
64 ExecStart=/home/fossil/bin/fossil server --port 9000 repo.fossil
65 Restart=always
66 RestartSec=3
67
68 [Install]
69 WantedBy=multi-user.target
70 ```
71
72 Unlike with `inetd` and `xinetd`, we don’t need to tell `systemd` which
73 user and group to run this service as, because we’ve installed it
74 under the account we’re logged into, which `systemd` will use as the
@@ -90,15 +90,15 @@
90
91 Because we’ve set this up as a user service, the commands you give to
92 manipulate the service vary somewhat from the sort you’re more likely to
93 find online:
94
95 $ systemctl --user daemon-reload
96 $ systemctl --user enable fossil
97 $ systemctl --user start fossil
98 $ systemctl --user status fossil -l
99 $ systemctl --user stop fossil
100
101 That is, we don’t need to talk to `systemd` with `sudo` privileges, but
102 we do need to tell it to look at the user configuration rather than the
103 system-level configuration.
104
@@ -109,11 +109,11 @@
109 On some `systemd` based OSes, user services only run while that user is
110 logged in interactively. This is common on systems aiming to provide
111 desktop environments, where this is the behavior you often want. To
112 allow background services to continue to run after logout, say:
113
114 $ sudo loginctl enable-linger $USER
115
116 You can paste the command just like that into your terminal, since
117 `$USER` will expand to your login name.
118
119 [scgi]: ../any/scgi.md
@@ -165,20 +165,20 @@
165
166 We first need to define the privileged socket listener by writing
167 `/etc/systemd/system/fossil.socket`:
168
169 ```dosini
170 [Unit]
171 Description=Fossil socket
172
173 [Socket]
174 Accept=yes
175 ListenStream=80
176 NoDelay=true
177
178 [Install]
179 WantedBy=sockets.target
180 ```
181
182 Note the change of configuration directory from the `~/.local` directory
183 to the system level. We need to start this socket listener at the root
184 level because of the low-numbered TCP port restriction we brought up
@@ -190,21 +190,21 @@
190
191 Next, create the service definition file in that same directory as
192 `[email protected]`:
193
194 ```dosini
195 [Unit]
196 Description=Fossil socket server
197 After=network-online.target
198
199 [Service]
200 WorkingDirectory=/home/fossil/museum
201 ExecStart=/home/fossil/bin/fossil http repo.fossil
202 StandardInput=socket
203
204 [Install]
205 WantedBy=multi-user.target
206 ```
207
208 Notice that we haven’t told `systemd` which user and group to run Fossil
209 under. Since this is a system-level service definition, that means it
210 will run as root, which then causes Fossil to [automatically drop into a
@@ -217,34 +217,34 @@
217 handles that single client’s request and then immediately shuts down.
218
219 Next, you need to tell `systemd` to reload its system-level
220 configuration files and enable the listening socket:
221
222 $ sudo systemctl daemon-reload
223 $ sudo systemctl enable fossil.socket
224
225 And now you can manipulate the socket listener:
226
227 $ sudo systemctl start fossil.socket
228 $ sudo systemctl status -l fossil.socket
229 $ sudo systemctl stop fossil.socket
230
231 Notice that we’re working with the *socket*, not the *service*. The fact
232 that we’ve given them the same base name and marked the service as an
233 instantiated service with the “`@`” notation allows `systemd` to
234 automatically start an instance of the service each time a hit comes in
235 on the socket that `systemd` is monitoring on Fossil’s behalf. To see
236 this service instantiation at work, visit a long-running Fossil page
237 (e.g. `/tarball`) and then give a command like this:
238
239 $ sudo systemctl --full | grep fossil
240
241 This will show information about the `fossil` socket and service
242 instances, which should show your `/tarball` hit handler, if it’s still
243 running:
244
245 [email protected]:80-127.0.0.1:38304.service
246
247 You can feed that service instance description to a `systemctl kill`
248 command to stop that single instance without restarting the whole
249 `fossil` service, for example.
250
251
--- www/server/debian/service.md
+++ www/server/debian/service.md
@@ -53,22 +53,22 @@
53
54 To do this, write the following in
55 `~/.local/share/systemd/user/fossil.service`:
56
57 ```dosini
58 [Unit]
59 Description=Fossil user server
60 After=network-online.target
61
62 [Service]
63 WorkingDirectory=/home/fossil/museum
64 ExecStart=/home/fossil/bin/fossil server --port 9000 repo.fossil
65 Restart=always
66 RestartSec=3
67
68 [Install]
69 WantedBy=multi-user.target
70 ```
71
72 Unlike with `inetd` and `xinetd`, we don’t need to tell `systemd` which
73 user and group to run this service as, because we’ve installed it
74 under the account we’re logged into, which `systemd` will use as the
@@ -90,15 +90,15 @@
90
91 Because we’ve set this up as a user service, the commands you give to
92 manipulate the service vary somewhat from the sort you’re more likely to
93 find online:
94
95 $ systemctl --user daemon-reload
96 $ systemctl --user enable fossil
97 $ systemctl --user start fossil
98 $ systemctl --user status fossil -l
99 $ systemctl --user stop fossil
100
101 That is, we don’t need to talk to `systemd` with `sudo` privileges, but
102 we do need to tell it to look at the user configuration rather than the
103 system-level configuration.
104
@@ -109,11 +109,11 @@
109 On some `systemd` based OSes, user services only run while that user is
110 logged in interactively. This is common on systems aiming to provide
111 desktop environments, where this is the behavior you often want. To
112 allow background services to continue to run after logout, say:
113
114 $ sudo loginctl enable-linger $USER
115
116 You can paste the command just like that into your terminal, since
117 `$USER` will expand to your login name.
118
119 [scgi]: ../any/scgi.md
@@ -165,20 +165,20 @@
165
166 We first need to define the privileged socket listener by writing
167 `/etc/systemd/system/fossil.socket`:
168
169 ```dosini
170 [Unit]
171 Description=Fossil socket
172
173 [Socket]
174 Accept=yes
175 ListenStream=80
176 NoDelay=true
177
178 [Install]
179 WantedBy=sockets.target
180 ```
181
182 Note the change of configuration directory from the `~/.local` directory
183 to the system level. We need to start this socket listener at the root
184 level because of the low-numbered TCP port restriction we brought up
@@ -190,21 +190,21 @@
190
191 Next, create the service definition file in that same directory as
192 `[email protected]`:
193
194 ```dosini
195 [Unit]
196 Description=Fossil socket server
197 After=network-online.target
198
199 [Service]
200 WorkingDirectory=/home/fossil/museum
201 ExecStart=/home/fossil/bin/fossil http repo.fossil
202 StandardInput=socket
203
204 [Install]
205 WantedBy=multi-user.target
206 ```
207
208 Notice that we haven’t told `systemd` which user and group to run Fossil
209 under. Since this is a system-level service definition, that means it
210 will run as root, which then causes Fossil to [automatically drop into a
@@ -217,34 +217,34 @@
217 handles that single client’s request and then immediately shuts down.
218
219 Next, you need to tell `systemd` to reload its system-level
220 configuration files and enable the listening socket:
221
222 $ sudo systemctl daemon-reload
223 $ sudo systemctl enable fossil.socket
224
225 And now you can manipulate the socket listener:
226
227 $ sudo systemctl start fossil.socket
228 $ sudo systemctl status -l fossil.socket
229 $ sudo systemctl stop fossil.socket
230
231 Notice that we’re working with the *socket*, not the *service*. The fact
232 that we’ve given them the same base name and marked the service as an
233 instantiated service with the “`@`” notation allows `systemd` to
234 automatically start an instance of the service each time a hit comes in
235 on the socket that `systemd` is monitoring on Fossil’s behalf. To see
236 this service instantiation at work, visit a long-running Fossil page
237 (e.g. `/tarball`) and then give a command like this:
238
239 $ sudo systemctl --full | grep fossil
240
241 This will show information about the `fossil` socket and service
242 instances, which should show your `/tarball` hit handler, if it’s still
243 running:
244
245 [email protected]:80-127.0.0.1:38304.service
246
247 You can feed that service instance description to a `systemctl kill`
248 command to stop that single instance without restarting the whole
249 `fossil` service, for example.
250
251
--- www/server/macos/service.md
+++ www/server/macos/service.md
@@ -18,11 +18,11 @@
1818
socket activation.
1919
2020
For more information on `launchd`, the single best resource we’ve found
2121
is [launchd.info](https://launchd.info). The next best is:
2222
23
- $ man launchd.plist
23
+ $ man launchd.plist
2424
2525
[la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/
2626
[ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
2727
[wpa]: https://en.wikipedia.org/wiki/Launchd
2828
@@ -32,42 +32,43 @@
3232
3333
To configure `launchd` to start Fossil as a standalone HTTP server,
3434
write the following as `com.example.dev.FossilHTTP.plist`:
3535
3636
```xml
37
- <?xml version="1.0" encoding="UTF-8"?>
38
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
39
- <plist version="1.0">
40
- <dict>
41
- <key>Label</key>
42
- <string>com.example.dev.FossilHTTP</string>
43
- <key>ProgramArguments</key>
44
- <array>
45
- <string>/usr/local/bin/fossil</string>
46
- <string>server</string>
47
- <string>--port</string>
48
- <string>9000</string>
49
- <string>repo.fossil</string>
50
- </array>
51
- <key>WorkingDirectory</key>
52
- <string>/Users/you/museum</string>
53
- <key>KeepAlive</key>
54
- <true/>
55
- <key>RunAtLoad</key>
56
- <true/>
57
- <key>StandardErrorPath</key>
58
- <string>/tmp/fossil-error.log</string>
59
- <key>StandardOutPath</key>
60
- <string>/tmp/fossil-info.log</string>
61
- <key>UserName</key>
62
- <string>you</string>
63
- <key>GroupName</key>
64
- <string>staff</string>
65
- <key>InitGroups</key>
66
- <true/>
67
- </dict>
68
- </plist>
37
+<?xml version="1.0" encoding="UTF-8"?>
38
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
39
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
40
+<plist version="1.0">
41
+<dict>
42
+ <key>Label</key>
43
+ <string>com.example.dev.FossilHTTP</string>
44
+ <key>ProgramArguments</key>
45
+ <array>
46
+ <string>/usr/local/bin/fossil</string>
47
+ <string>server</string>
48
+ <string>--port</string>
49
+ <string>9000</string>
50
+ <string>repo.fossil</string>
51
+ </array>
52
+ <key>WorkingDirectory</key>
53
+ <string>/Users/you/museum</string>
54
+ <key>KeepAlive</key>
55
+ <true/>
56
+ <key>RunAtLoad</key>
57
+ <true/>
58
+ <key>StandardErrorPath</key>
59
+ <string>/tmp/fossil-error.log</string>
60
+ <key>StandardOutPath</key>
61
+ <string>/tmp/fossil-info.log</string>
62
+ <key>UserName</key>
63
+ <string>you</string>
64
+ <key>GroupName</key>
65
+ <string>staff</string>
66
+ <key>InitGroups</key>
67
+ <true/>
68
+</dict>
69
+</plist>
6970
```
7071
7172
In this example, we’re assuming your development organization uses the
7273
domain name “`dev.example.org`”, that your short macOS login name is
7374
“`you`”, and that you store your Fossils in “`~/museum`”. Adjust these
@@ -81,29 +82,30 @@
8182
if you leave the user and group configuration at the tail end of that
8283
plist file out, Fossil will remain running as root!
8384
8485
Install that file and set it to start with:
8586
86
- $ sudo install -o root -g wheel -m 644 com.example.dev.FossilHTTP.plist \
87
- /Library/LaunchDaemons/
88
- $ sudo launchctl load -w /Library/LaunchDaemons/com.example.dev.FossilHTTP.plist
87
+ $ sudo install -o root -g wheel -m 644 com.example.dev.FossilHTTP.plist \
88
+ /Library/LaunchDaemons/
89
+ $ sudo launchctl load -w /Library/LaunchDaemons/com.example.dev.FossilHTTP.plist
8990
9091
Because we set the `RunAtLoad` key, this will also launch the daemon.
9192
9293
Stop the daemon with:
9394
94
- $ sudo launchctl unload -w /Library/LaunchDaemons/com.example.dev.FossilHTTP.plist
95
+ $ sudo launchctl unload -w /Library/LaunchDaemons/com.example.dev.FossilHTTP.plist
9596
9697
9798
## Socket Listener
9899
99100
Another useful method to serve a Fossil repo via `launchd` is by setting
100101
up a socket listener:
101102
102103
```xml
103104
<?xml version="1.0" encoding="UTF-8"?>
104
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
105
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
106
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
105107
<plist version="1.0">
106108
<dict>
107109
<key>Label</key>
108110
<string>com.example.dev.FossilSocket</string>
109111
<key>ProgramArguments</key>
110112
--- www/server/macos/service.md
+++ www/server/macos/service.md
@@ -18,11 +18,11 @@
18 socket activation.
19
20 For more information on `launchd`, the single best resource we’ve found
21 is [launchd.info](https://launchd.info). The next best is:
22
23 $ man launchd.plist
24
25 [la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/
26 [ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
27 [wpa]: https://en.wikipedia.org/wiki/Launchd
28
@@ -32,42 +32,43 @@
32
33 To configure `launchd` to start Fossil as a standalone HTTP server,
34 write the following as `com.example.dev.FossilHTTP.plist`:
35
36 ```xml
37 <?xml version="1.0" encoding="UTF-8"?>
38 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
39 <plist version="1.0">
40 <dict>
41 <key>Label</key>
42 <string>com.example.dev.FossilHTTP</string>
43 <key>ProgramArguments</key>
44 <array>
45 <string>/usr/local/bin/fossil</string>
46 <string>server</string>
47 <string>--port</string>
48 <string>9000</string>
49 <string>repo.fossil</string>
50 </array>
51 <key>WorkingDirectory</key>
52 <string>/Users/you/museum</string>
53 <key>KeepAlive</key>
54 <true/>
55 <key>RunAtLoad</key>
56 <true/>
57 <key>StandardErrorPath</key>
58 <string>/tmp/fossil-error.log</string>
59 <key>StandardOutPath</key>
60 <string>/tmp/fossil-info.log</string>
61 <key>UserName</key>
62 <string>you</string>
63 <key>GroupName</key>
64 <string>staff</string>
65 <key>InitGroups</key>
66 <true/>
67 </dict>
68 </plist>
 
69 ```
70
71 In this example, we’re assuming your development organization uses the
72 domain name “`dev.example.org`”, that your short macOS login name is
73 “`you`”, and that you store your Fossils in “`~/museum`”. Adjust these
@@ -81,29 +82,30 @@
81 if you leave the user and group configuration at the tail end of that
82 plist file out, Fossil will remain running as root!
83
84 Install that file and set it to start with:
85
86 $ sudo install -o root -g wheel -m 644 com.example.dev.FossilHTTP.plist \
87 /Library/LaunchDaemons/
88 $ sudo launchctl load -w /Library/LaunchDaemons/com.example.dev.FossilHTTP.plist
89
90 Because we set the `RunAtLoad` key, this will also launch the daemon.
91
92 Stop the daemon with:
93
94 $ sudo launchctl unload -w /Library/LaunchDaemons/com.example.dev.FossilHTTP.plist
95
96
97 ## Socket Listener
98
99 Another useful method to serve a Fossil repo via `launchd` is by setting
100 up a socket listener:
101
102 ```xml
103 <?xml version="1.0" encoding="UTF-8"?>
104 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 
105 <plist version="1.0">
106 <dict>
107 <key>Label</key>
108 <string>com.example.dev.FossilSocket</string>
109 <key>ProgramArguments</key>
110
--- www/server/macos/service.md
+++ www/server/macos/service.md
@@ -18,11 +18,11 @@
18 socket activation.
19
20 For more information on `launchd`, the single best resource we’ve found
21 is [launchd.info](https://launchd.info). The next best is:
22
23 $ man launchd.plist
24
25 [la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/
26 [ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html
27 [wpa]: https://en.wikipedia.org/wiki/Launchd
28
@@ -32,42 +32,43 @@
32
33 To configure `launchd` to start Fossil as a standalone HTTP server,
34 write the following as `com.example.dev.FossilHTTP.plist`:
35
36 ```xml
37 <?xml version="1.0" encoding="UTF-8"?>
38 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
39 "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
40 <plist version="1.0">
41 <dict>
42 <key>Label</key>
43 <string>com.example.dev.FossilHTTP</string>
44 <key>ProgramArguments</key>
45 <array>
46 <string>/usr/local/bin/fossil</string>
47 <string>server</string>
48 <string>--port</string>
49 <string>9000</string>
50 <string>repo.fossil</string>
51 </array>
52 <key>WorkingDirectory</key>
53 <string>/Users/you/museum</string>
54 <key>KeepAlive</key>
55 <true/>
56 <key>RunAtLoad</key>
57 <true/>
58 <key>StandardErrorPath</key>
59 <string>/tmp/fossil-error.log</string>
60 <key>StandardOutPath</key>
61 <string>/tmp/fossil-info.log</string>
62 <key>UserName</key>
63 <string>you</string>
64 <key>GroupName</key>
65 <string>staff</string>
66 <key>InitGroups</key>
67 <true/>
68 </dict>
69 </plist>
70 ```
71
72 In this example, we’re assuming your development organization uses the
73 domain name “`dev.example.org`”, that your short macOS login name is
74 “`you`”, and that you store your Fossils in “`~/museum`”. Adjust these
@@ -81,29 +82,30 @@
82 if you leave the user and group configuration at the tail end of that
83 plist file out, Fossil will remain running as root!
84
85 Install that file and set it to start with:
86
87 $ sudo install -o root -g wheel -m 644 com.example.dev.FossilHTTP.plist \
88 /Library/LaunchDaemons/
89 $ sudo launchctl load -w /Library/LaunchDaemons/com.example.dev.FossilHTTP.plist
90
91 Because we set the `RunAtLoad` key, this will also launch the daemon.
92
93 Stop the daemon with:
94
95 $ sudo launchctl unload -w /Library/LaunchDaemons/com.example.dev.FossilHTTP.plist
96
97
98 ## Socket Listener
99
100 Another useful method to serve a Fossil repo via `launchd` is by setting
101 up a socket listener:
102
103 ```xml
104 <?xml version="1.0" encoding="UTF-8"?>
105 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
106 "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
107 <plist version="1.0">
108 <dict>
109 <key>Label</key>
110 <string>com.example.dev.FossilSocket</string>
111 <key>ProgramArguments</key>
112
--- www/server/openbsd/fastcgi.md
+++ www/server/openbsd/fastcgi.md
@@ -18,52 +18,52 @@
1818
1919
Use the OpenBSD package manager `pkg_add` to install Fossil, making sure
2020
to select the statically linked binary.
2121
2222
```console
23
- $ doas pkg_add fossil
24
- quirks-3.325 signed on 2020-06-12T06:24:53Z
25
- Ambiguous: choose package for fossil
26
- 0: <None>
27
- 1: fossil-2.10v0
28
- 2: fossil-2.10v0-static
29
- Your choice: 2
30
- fossil-2.10v0-static: ok
23
+$ doas pkg_add fossil
24
+quirks-3.325 signed on 2020-06-12T06:24:53Z
25
+Ambiguous: choose package for fossil
26
+ 0: <None>
27
+ 1: fossil-2.10v0
28
+ 2: fossil-2.10v0-static
29
+Your choice: 2
30
+fossil-2.10v0-static: ok
3131
```
3232
3333
This installs Fossil into the chroot. To facilitate local use, create a
3434
symbolic link of the fossil executable into `/usr/local/bin`.
3535
3636
```console
37
- $ doas ln -s /var/www/bin/fossil /usr/local/bin/fossil
37
+$ doas ln -s /var/www/bin/fossil /usr/local/bin/fossil
3838
```
3939
4040
As a privileged user, create the file `/var/www/cgi-bin/scm` with the
4141
following contents to make the CGI script that `httpd` will execute in
4242
response to `fsl.domain.tld` requests; all paths are relative to the
4343
`/var/www` chroot.
4444
4545
```sh
46
- #!/bin/fossil
47
- directory: /htdocs/fsl.domain.tld
48
- notfound: https://domain.tld
49
- repolist
50
- errorlog: /logs/fossil.log
46
+#!/bin/fossil
47
+directory: /htdocs/fsl.domain.tld
48
+notfound: https://domain.tld
49
+repolist
50
+errorlog: /logs/fossil.log
5151
```
5252
5353
The `directory` directive instructs Fossil to serve all repositories
5454
found in `/var/www/htdocs/fsl.domain.tld`, while `errorlog` sets logging
5555
to be saved to `/var/www/logs/fossil.log`; create the repository
5656
directory and log file—making the latter owned by the `www` user, and
5757
the script executable.
5858
5959
```console
60
- $ doas mkdir /var/www/htdocs/fsl.domain.tld
61
- $ doas touch /var/www/logs/fossil.log
62
- $ doas chown www /var/www/logs/fossil.log
63
- $ doas chmod 660 /var/www/logs/fossil.log
64
- $ doas chmod 755 /var/www/cgi-bin/scm
60
+$ doas mkdir /var/www/htdocs/fsl.domain.tld
61
+$ doas touch /var/www/logs/fossil.log
62
+$ doas chown www /var/www/logs/fossil.log
63
+$ doas chmod 660 /var/www/logs/fossil.log
64
+$ doas chmod 755 /var/www/cgi-bin/scm
6565
```
6666
6767
## <a id="chroot"></a>Setup chroot
6868
6969
Fossil needs both `/dev/random` and `/dev/null`, which aren't accessible
@@ -75,41 +75,41 @@
7575
startup script to recreate the device files at boot, create a template
7676
of the needed ``/dev`` tree to automatically populate the memory
7777
filesystem.
7878
7979
```console
80
- $ doas mkdir /var/www/dev
81
- $ doas install -d -g daemon /template/dev
82
- $ cd /template/dev
83
- $ doas /dev/MAKEDEV urandom
84
- $ doas mknod -m 666 null c 2 2
85
- $ doas mount_mfs -s 1M -P /template/dev /dev/sd0b /var/www/dev
86
- $ ls -l
87
- total 0
88
- crw-rw-rw- 1 root daemon 2, 2 Jun 20 08:56 null
89
- lrwxr-xr-x 1 root daemon 7 Jun 18 06:30 random@ -> urandom
90
- crw-r--r-- 1 root wheel 45, 0 Jun 18 06:30 urandom
80
+$ doas mkdir /var/www/dev
81
+$ doas install -d -g daemon /template/dev
82
+$ cd /template/dev
83
+$ doas /dev/MAKEDEV urandom
84
+$ doas mknod -m 666 null c 2 2
85
+$ doas mount_mfs -s 1M -P /template/dev /dev/sd0b /var/www/dev
86
+$ ls -l
87
+total 0
88
+crw-rw-rw- 1 root daemon 2, 2 Jun 20 08:56 null
89
+lrwxr-xr-x 1 root daemon 7 Jun 18 06:30 random@ -> urandom
90
+crw-r--r-- 1 root wheel 45, 0 Jun 18 06:30 urandom
9191
```
9292
9393
[mfs]: https://man.openbsd.org/mount_mfs.8
9494
9595
To make the mountable memory filesystem permanent, open `/etc/fstab` as
9696
a privileged user and add the following line to automate creation of the
9797
filesystem at startup:
9898
9999
```console
100
- swap /var/www/dev mfs rw,-s=1048576,-P=/template/dev 0 0
100
+swap /var/www/dev mfs rw,-s=1048576,-P=/template/dev 0 0
101101
```
102102
103103
The same user that executes the fossil binary must have writable access
104104
to the repository directory that resides within the chroot; on OpenBSD
105105
this is `www`. In addition, grant repository directory ownership to the
106106
user who will push to, pull from, and create repositories.
107107
108108
```console
109
- $ doas chown -R user:www /var/www/htdocs/fsl.domain.tld
110
- $ doas chmod 770 /var/www/htdocs/fsl.domain.tld
109
+$ doas chown -R user:www /var/www/htdocs/fsl.domain.tld
110
+$ doas chmod 770 /var/www/htdocs/fsl.domain.tld
111111
```
112112
113113
## <a id="httpdconfig"></a>Configure httpd
114114
115115
On OpenBSD, [httpd.conf(5)][httpd] is the configuration file for
@@ -123,46 +123,46 @@
123123
[LE]: https://letsencrypt.org
124124
[acme]: https://man.openbsd.org/acme-client.1
125125
[httpd.conf(5)]: https://man.openbsd.org/httpd.conf.5
126126
127127
```apache
128
- server "fsl.domain.tld" {
129
- listen on * port http
130
- root "/htdocs/fsl.domain.tld"
131
- location "/.well-known/acme-challenge/*" {
132
- root "/acme"
133
- request strip 2
134
- }
135
- location * {
136
- block return 301 "https://$HTTP_HOST$REQUEST_URI"
137
- }
138
- location "/*" {
139
- fastcgi { param SCRIPT_FILENAME "/cgi-bin/scm" }
140
- }
141
- }
142
-
143
- server "fsl.domain.tld" {
144
- listen on * tls port https
145
- root "/htdocs/fsl.domain.tld"
146
- tls {
147
- certificate "/etc/ssl/domain.tld.fullchain.pem"
148
- key "/etc/ssl/private/domain.tld.key"
149
- }
150
- hsts {
151
- max-age 15768000
152
- preload
153
- subdomains
154
- }
155
- connection max request body 104857600
156
- location "/*" {
157
- fastcgi { param SCRIPT_FILENAME "/cgi-bin/scm" }
158
- }
159
- location "/.well-known/acme-challenge/*" {
160
- root "/acme"
161
- request strip 2
162
- }
163
- }
128
+server "fsl.domain.tld" {
129
+ listen on * port http
130
+ root "/htdocs/fsl.domain.tld"
131
+ location "/.well-known/acme-challenge/*" {
132
+ root "/acme"
133
+ request strip 2
134
+ }
135
+ location * {
136
+ block return 301 "https://$HTTP_HOST$REQUEST_URI"
137
+ }
138
+ location "/*" {
139
+ fastcgi { param SCRIPT_FILENAME "/cgi-bin/scm" }
140
+ }
141
+}
142
+
143
+server "fsl.domain.tld" {
144
+ listen on * tls port https
145
+ root "/htdocs/fsl.domain.tld"
146
+ tls {
147
+ certificate "/etc/ssl/domain.tld.fullchain.pem"
148
+ key "/etc/ssl/private/domain.tld.key"
149
+ }
150
+ hsts {
151
+ max-age 15768000
152
+ preload
153
+ subdomains
154
+ }
155
+ connection max request body 104857600
156
+ location "/*" {
157
+ fastcgi { param SCRIPT_FILENAME "/cgi-bin/scm" }
158
+ }
159
+ location "/.well-known/acme-challenge/*" {
160
+ root "/acme"
161
+ request strip 2
162
+ }
163
+}
164164
```
165165
166166
[The default limit][dlim] for HTTP messages in OpenBSD’s `httpd` server
167167
is 1 MiB. Fossil chunks its sync protocol such that this is not
168168
normally a problem, but when sending [unversioned content][uv], it uses
@@ -187,57 +187,57 @@
187187
ensure you have a zone record for the subdomain with your registrar or
188188
nameserver. Then open `/etc/acme-client.conf` as a privileged user to
189189
configure the request.
190190
191191
```dosini
192
- authority letsencrypt {
193
- api url "https://acme-v02.api.letsencrypt.org/directory"
194
- account key "/etc/acme/letsencrypt-privkey.pem"
195
- }
196
-
197
- authority letsencrypt-staging {
198
- api url "https://acme-staging.api.letsencrypt.org/directory"
199
- account key "/etc/acme/letsencrypt-staging-privkey.pem"
200
- }
201
-
202
- domain domain.tld {
203
- alternative names { www.domain.tld fsl.domain.tld }
204
- domain key "/etc/ssl/private/domain.tld.key"
205
- domain certificate "/etc/ssl/domain.tld.crt"
206
- domain full chain certificate "/etc/ssl/domain.tld.fullchain.pem"
207
- sign with letsencrypt
208
- }
192
+authority letsencrypt {
193
+ api url "https://acme-v02.api.letsencrypt.org/directory"
194
+ account key "/etc/acme/letsencrypt-privkey.pem"
195
+}
196
+
197
+authority letsencrypt-staging {
198
+ api url "https://acme-staging.api.letsencrypt.org/directory"
199
+ account key "/etc/acme/letsencrypt-staging-privkey.pem"
200
+}
201
+
202
+domain domain.tld {
203
+ alternative names { www.domain.tld fsl.domain.tld }
204
+ domain key "/etc/ssl/private/domain.tld.key"
205
+ domain certificate "/etc/ssl/domain.tld.crt"
206
+ domain full chain certificate "/etc/ssl/domain.tld.fullchain.pem"
207
+ sign with letsencrypt
208
+}
209209
```
210210
211211
Start `httpd` with the new configuration file, and issue the certificate
212212
request.
213213
214214
```console
215
- $ doas rcctl start httpd
216
- $ doas acme-client -vv domain.tld
217
- acme-client: /etc/acme/letsencrypt-privkey.pem: account key exists (not creating)
218
- acme-client: /etc/acme/letsencrypt-privkey.pem: loaded RSA account key
219
- acme-client: /etc/ssl/private/domain.tld.key: generated RSA domain key
220
- acme-client: https://acme-v01.api.letsencrypt.org/directory: directories
221
- acme-client: acme-v01.api.letsencrypt.org: DNS: 172.65.32.248
222
- ...
223
- N(Q????Z???j?j?>W#????b???? H????eb??T??*? DNosz(???n{L}???D???4[?B] (1174 bytes)
224
- acme-client: /etc/ssl/domain.tld.crt: created
225
- acme-client: /etc/ssl/domain.tld.fullchain.pem: created
215
+$ doas rcctl start httpd
216
+$ doas acme-client -vv domain.tld
217
+acme-client: /etc/acme/letsencrypt-privkey.pem: account key exists (not creating)
218
+acme-client: /etc/acme/letsencrypt-privkey.pem: loaded RSA account key
219
+acme-client: /etc/ssl/private/domain.tld.key: generated RSA domain key
220
+acme-client: https://acme-v01.api.letsencrypt.org/directory: directories
221
+acme-client: acme-v01.api.letsencrypt.org: DNS: 172.65.32.248
222
+...
223
+N(Q????Z???j?j?>W#????b???? H????eb??T??*? DNosz(???n{L}???D???4[?B] (1174 bytes)
224
+acme-client: /etc/ssl/domain.tld.crt: created
225
+acme-client: /etc/ssl/domain.tld.fullchain.pem: created
226226
```
227227
228228
A successful result will output the public certificate, full chain of
229229
trust, and private key into the `/etc/ssl` directory as specified in
230230
`acme-client.conf`.
231231
232232
```console
233
- $ doas ls -lR /etc/ssl
234
- -r--r--r-- 1 root wheel 2.3K Mar 2 01:31:03 2018 domain.tld.crt
235
- -r--r--r-- 1 root wheel 3.9K Mar 2 01:31:03 2018 domain.tld.fullchain.pem
233
+$ doas ls -lR /etc/ssl
234
+-r--r--r-- 1 root wheel 2.3K Mar 2 01:31:03 2018 domain.tld.crt
235
+-r--r--r-- 1 root wheel 3.9K Mar 2 01:31:03 2018 domain.tld.fullchain.pem
236236
237
- /etc/ssl/private:
238
- -r-------- 1 root wheel 3.2K Mar 2 01:31:03 2018 domain.tld.key
237
+/etc/ssl/private:
238
+-r-------- 1 root wheel 3.2K Mar 2 01:31:03 2018 domain.tld.key
239239
```
240240
241241
Make sure to reopen `/etc/httpd.conf` to uncomment the second server
242242
block responsible for serving HTTPS requests before proceeding.
243243
@@ -249,36 +249,36 @@
249249
execute the above Fossil CGI script—before checking that the syntax of
250250
the `httpd.conf` configuration file is correct, and (re)starting the
251251
server (if still running from requesting a Let's Encrypt certificate).
252252
253253
```console
254
- $ doas rcctl enable slowcgi
255
- $ doas rcctl start slowcgi
256
- slowcgi(ok)
257
- $ doas httpd -vnf /etc/httpd.conf
258
- configuration OK
259
- $ doas rcctl start httpd
260
- httpd(ok)
254
+$ doas rcctl enable slowcgi
255
+$ doas rcctl start slowcgi
256
+slowcgi(ok)
257
+$ doas httpd -vnf /etc/httpd.conf
258
+configuration OK
259
+$ doas rcctl start httpd
260
+httpd(ok)
261261
```
262262
263263
## <a id="clientconfig"></a>Configure Client
264264
265265
To facilitate creating new repositories and pushing them to the server,
266266
add the following function to your `~/.cshrc` or `~/.zprofile` or the
267267
config file for whichever shell you are using on your development box.
268268
269269
```sh
270
- finit() {
271
- fossil init $1.fossil && \
272
- chmod 664 $1.fossil && \
273
- fossil open $1.fossil && \
274
- fossil user password $USER $PASSWD && \
275
- fossil remote-url https://$USER:[email protected]/$1 && \
276
- rsync --perms $1.fossil [email protected]:/var/www/htdocs/fsl.domain.tld/ >/dev/null && \
277
- chmod 644 $1.fossil && \
278
- fossil ui
279
- }
270
+finit() {
271
+ fossil init $1.fossil && \
272
+ chmod 664 $1.fossil && \
273
+ fossil open $1.fossil && \
274
+ fossil user password $USER $PASSWD && \
275
+ fossil remote-url https://$USER:[email protected]/$1 && \
276
+ rsync --perms $1.fossil [email protected]:/var/www/htdocs/fsl.domain.tld/ >/dev/null && \
277
+ chmod 644 $1.fossil && \
278
+ fossil ui
279
+}
280280
```
281281
282282
This enables a new repository to be made with `finit repo`, which will
283283
create the fossil repository file `repo.fossil` in the current working
284284
directory; by default, the repository user is set to the environment
285285
--- www/server/openbsd/fastcgi.md
+++ www/server/openbsd/fastcgi.md
@@ -18,52 +18,52 @@
18
19 Use the OpenBSD package manager `pkg_add` to install Fossil, making sure
20 to select the statically linked binary.
21
22 ```console
23 $ doas pkg_add fossil
24 quirks-3.325 signed on 2020-06-12T06:24:53Z
25 Ambiguous: choose package for fossil
26 0: <None>
27 1: fossil-2.10v0
28 2: fossil-2.10v0-static
29 Your choice: 2
30 fossil-2.10v0-static: ok
31 ```
32
33 This installs Fossil into the chroot. To facilitate local use, create a
34 symbolic link of the fossil executable into `/usr/local/bin`.
35
36 ```console
37 $ doas ln -s /var/www/bin/fossil /usr/local/bin/fossil
38 ```
39
40 As a privileged user, create the file `/var/www/cgi-bin/scm` with the
41 following contents to make the CGI script that `httpd` will execute in
42 response to `fsl.domain.tld` requests; all paths are relative to the
43 `/var/www` chroot.
44
45 ```sh
46 #!/bin/fossil
47 directory: /htdocs/fsl.domain.tld
48 notfound: https://domain.tld
49 repolist
50 errorlog: /logs/fossil.log
51 ```
52
53 The `directory` directive instructs Fossil to serve all repositories
54 found in `/var/www/htdocs/fsl.domain.tld`, while `errorlog` sets logging
55 to be saved to `/var/www/logs/fossil.log`; create the repository
56 directory and log file—making the latter owned by the `www` user, and
57 the script executable.
58
59 ```console
60 $ doas mkdir /var/www/htdocs/fsl.domain.tld
61 $ doas touch /var/www/logs/fossil.log
62 $ doas chown www /var/www/logs/fossil.log
63 $ doas chmod 660 /var/www/logs/fossil.log
64 $ doas chmod 755 /var/www/cgi-bin/scm
65 ```
66
67 ## <a id="chroot"></a>Setup chroot
68
69 Fossil needs both `/dev/random` and `/dev/null`, which aren't accessible
@@ -75,41 +75,41 @@
75 startup script to recreate the device files at boot, create a template
76 of the needed ``/dev`` tree to automatically populate the memory
77 filesystem.
78
79 ```console
80 $ doas mkdir /var/www/dev
81 $ doas install -d -g daemon /template/dev
82 $ cd /template/dev
83 $ doas /dev/MAKEDEV urandom
84 $ doas mknod -m 666 null c 2 2
85 $ doas mount_mfs -s 1M -P /template/dev /dev/sd0b /var/www/dev
86 $ ls -l
87 total 0
88 crw-rw-rw- 1 root daemon 2, 2 Jun 20 08:56 null
89 lrwxr-xr-x 1 root daemon 7 Jun 18 06:30 random@ -> urandom
90 crw-r--r-- 1 root wheel 45, 0 Jun 18 06:30 urandom
91 ```
92
93 [mfs]: https://man.openbsd.org/mount_mfs.8
94
95 To make the mountable memory filesystem permanent, open `/etc/fstab` as
96 a privileged user and add the following line to automate creation of the
97 filesystem at startup:
98
99 ```console
100 swap /var/www/dev mfs rw,-s=1048576,-P=/template/dev 0 0
101 ```
102
103 The same user that executes the fossil binary must have writable access
104 to the repository directory that resides within the chroot; on OpenBSD
105 this is `www`. In addition, grant repository directory ownership to the
106 user who will push to, pull from, and create repositories.
107
108 ```console
109 $ doas chown -R user:www /var/www/htdocs/fsl.domain.tld
110 $ doas chmod 770 /var/www/htdocs/fsl.domain.tld
111 ```
112
113 ## <a id="httpdconfig"></a>Configure httpd
114
115 On OpenBSD, [httpd.conf(5)][httpd] is the configuration file for
@@ -123,46 +123,46 @@
123 [LE]: https://letsencrypt.org
124 [acme]: https://man.openbsd.org/acme-client.1
125 [httpd.conf(5)]: https://man.openbsd.org/httpd.conf.5
126
127 ```apache
128 server "fsl.domain.tld" {
129 listen on * port http
130 root "/htdocs/fsl.domain.tld"
131 location "/.well-known/acme-challenge/*" {
132 root "/acme"
133 request strip 2
134 }
135 location * {
136 block return 301 "https://$HTTP_HOST$REQUEST_URI"
137 }
138 location "/*" {
139 fastcgi { param SCRIPT_FILENAME "/cgi-bin/scm" }
140 }
141 }
142
143 server "fsl.domain.tld" {
144 listen on * tls port https
145 root "/htdocs/fsl.domain.tld"
146 tls {
147 certificate "/etc/ssl/domain.tld.fullchain.pem"
148 key "/etc/ssl/private/domain.tld.key"
149 }
150 hsts {
151 max-age 15768000
152 preload
153 subdomains
154 }
155 connection max request body 104857600
156 location "/*" {
157 fastcgi { param SCRIPT_FILENAME "/cgi-bin/scm" }
158 }
159 location "/.well-known/acme-challenge/*" {
160 root "/acme"
161 request strip 2
162 }
163 }
164 ```
165
166 [The default limit][dlim] for HTTP messages in OpenBSD’s `httpd` server
167 is 1 MiB. Fossil chunks its sync protocol such that this is not
168 normally a problem, but when sending [unversioned content][uv], it uses
@@ -187,57 +187,57 @@
187 ensure you have a zone record for the subdomain with your registrar or
188 nameserver. Then open `/etc/acme-client.conf` as a privileged user to
189 configure the request.
190
191 ```dosini
192 authority letsencrypt {
193 api url "https://acme-v02.api.letsencrypt.org/directory"
194 account key "/etc/acme/letsencrypt-privkey.pem"
195 }
196
197 authority letsencrypt-staging {
198 api url "https://acme-staging.api.letsencrypt.org/directory"
199 account key "/etc/acme/letsencrypt-staging-privkey.pem"
200 }
201
202 domain domain.tld {
203 alternative names { www.domain.tld fsl.domain.tld }
204 domain key "/etc/ssl/private/domain.tld.key"
205 domain certificate "/etc/ssl/domain.tld.crt"
206 domain full chain certificate "/etc/ssl/domain.tld.fullchain.pem"
207 sign with letsencrypt
208 }
209 ```
210
211 Start `httpd` with the new configuration file, and issue the certificate
212 request.
213
214 ```console
215 $ doas rcctl start httpd
216 $ doas acme-client -vv domain.tld
217 acme-client: /etc/acme/letsencrypt-privkey.pem: account key exists (not creating)
218 acme-client: /etc/acme/letsencrypt-privkey.pem: loaded RSA account key
219 acme-client: /etc/ssl/private/domain.tld.key: generated RSA domain key
220 acme-client: https://acme-v01.api.letsencrypt.org/directory: directories
221 acme-client: acme-v01.api.letsencrypt.org: DNS: 172.65.32.248
222 ...
223 N(Q????Z???j?j?>W#????b???? H????eb??T??*? DNosz(???n{L}???D???4[?B] (1174 bytes)
224 acme-client: /etc/ssl/domain.tld.crt: created
225 acme-client: /etc/ssl/domain.tld.fullchain.pem: created
226 ```
227
228 A successful result will output the public certificate, full chain of
229 trust, and private key into the `/etc/ssl` directory as specified in
230 `acme-client.conf`.
231
232 ```console
233 $ doas ls -lR /etc/ssl
234 -r--r--r-- 1 root wheel 2.3K Mar 2 01:31:03 2018 domain.tld.crt
235 -r--r--r-- 1 root wheel 3.9K Mar 2 01:31:03 2018 domain.tld.fullchain.pem
236
237 /etc/ssl/private:
238 -r-------- 1 root wheel 3.2K Mar 2 01:31:03 2018 domain.tld.key
239 ```
240
241 Make sure to reopen `/etc/httpd.conf` to uncomment the second server
242 block responsible for serving HTTPS requests before proceeding.
243
@@ -249,36 +249,36 @@
249 execute the above Fossil CGI script—before checking that the syntax of
250 the `httpd.conf` configuration file is correct, and (re)starting the
251 server (if still running from requesting a Let's Encrypt certificate).
252
253 ```console
254 $ doas rcctl enable slowcgi
255 $ doas rcctl start slowcgi
256 slowcgi(ok)
257 $ doas httpd -vnf /etc/httpd.conf
258 configuration OK
259 $ doas rcctl start httpd
260 httpd(ok)
261 ```
262
263 ## <a id="clientconfig"></a>Configure Client
264
265 To facilitate creating new repositories and pushing them to the server,
266 add the following function to your `~/.cshrc` or `~/.zprofile` or the
267 config file for whichever shell you are using on your development box.
268
269 ```sh
270 finit() {
271 fossil init $1.fossil && \
272 chmod 664 $1.fossil && \
273 fossil open $1.fossil && \
274 fossil user password $USER $PASSWD && \
275 fossil remote-url https://$USER:[email protected]/$1 && \
276 rsync --perms $1.fossil [email protected]:/var/www/htdocs/fsl.domain.tld/ >/dev/null && \
277 chmod 644 $1.fossil && \
278 fossil ui
279 }
280 ```
281
282 This enables a new repository to be made with `finit repo`, which will
283 create the fossil repository file `repo.fossil` in the current working
284 directory; by default, the repository user is set to the environment
285
--- www/server/openbsd/fastcgi.md
+++ www/server/openbsd/fastcgi.md
@@ -18,52 +18,52 @@
18
19 Use the OpenBSD package manager `pkg_add` to install Fossil, making sure
20 to select the statically linked binary.
21
22 ```console
23 $ doas pkg_add fossil
24 quirks-3.325 signed on 2020-06-12T06:24:53Z
25 Ambiguous: choose package for fossil
26 0: <None>
27 1: fossil-2.10v0
28 2: fossil-2.10v0-static
29 Your choice: 2
30 fossil-2.10v0-static: ok
31 ```
32
33 This installs Fossil into the chroot. To facilitate local use, create a
34 symbolic link of the fossil executable into `/usr/local/bin`.
35
36 ```console
37 $ doas ln -s /var/www/bin/fossil /usr/local/bin/fossil
38 ```
39
40 As a privileged user, create the file `/var/www/cgi-bin/scm` with the
41 following contents to make the CGI script that `httpd` will execute in
42 response to `fsl.domain.tld` requests; all paths are relative to the
43 `/var/www` chroot.
44
45 ```sh
46 #!/bin/fossil
47 directory: /htdocs/fsl.domain.tld
48 notfound: https://domain.tld
49 repolist
50 errorlog: /logs/fossil.log
51 ```
52
53 The `directory` directive instructs Fossil to serve all repositories
54 found in `/var/www/htdocs/fsl.domain.tld`, while `errorlog` sets logging
55 to be saved to `/var/www/logs/fossil.log`; create the repository
56 directory and log file—making the latter owned by the `www` user, and
57 the script executable.
58
59 ```console
60 $ doas mkdir /var/www/htdocs/fsl.domain.tld
61 $ doas touch /var/www/logs/fossil.log
62 $ doas chown www /var/www/logs/fossil.log
63 $ doas chmod 660 /var/www/logs/fossil.log
64 $ doas chmod 755 /var/www/cgi-bin/scm
65 ```
66
67 ## <a id="chroot"></a>Setup chroot
68
69 Fossil needs both `/dev/random` and `/dev/null`, which aren't accessible
@@ -75,41 +75,41 @@
75 startup script to recreate the device files at boot, create a template
76 of the needed ``/dev`` tree to automatically populate the memory
77 filesystem.
78
79 ```console
80 $ doas mkdir /var/www/dev
81 $ doas install -d -g daemon /template/dev
82 $ cd /template/dev
83 $ doas /dev/MAKEDEV urandom
84 $ doas mknod -m 666 null c 2 2
85 $ doas mount_mfs -s 1M -P /template/dev /dev/sd0b /var/www/dev
86 $ ls -l
87 total 0
88 crw-rw-rw- 1 root daemon 2, 2 Jun 20 08:56 null
89 lrwxr-xr-x 1 root daemon 7 Jun 18 06:30 random@ -> urandom
90 crw-r--r-- 1 root wheel 45, 0 Jun 18 06:30 urandom
91 ```
92
93 [mfs]: https://man.openbsd.org/mount_mfs.8
94
95 To make the mountable memory filesystem permanent, open `/etc/fstab` as
96 a privileged user and add the following line to automate creation of the
97 filesystem at startup:
98
99 ```console
100 swap /var/www/dev mfs rw,-s=1048576,-P=/template/dev 0 0
101 ```
102
103 The same user that executes the fossil binary must have writable access
104 to the repository directory that resides within the chroot; on OpenBSD
105 this is `www`. In addition, grant repository directory ownership to the
106 user who will push to, pull from, and create repositories.
107
108 ```console
109 $ doas chown -R user:www /var/www/htdocs/fsl.domain.tld
110 $ doas chmod 770 /var/www/htdocs/fsl.domain.tld
111 ```
112
113 ## <a id="httpdconfig"></a>Configure httpd
114
115 On OpenBSD, [httpd.conf(5)][httpd] is the configuration file for
@@ -123,46 +123,46 @@
123 [LE]: https://letsencrypt.org
124 [acme]: https://man.openbsd.org/acme-client.1
125 [httpd.conf(5)]: https://man.openbsd.org/httpd.conf.5
126
127 ```apache
128 server "fsl.domain.tld" {
129 listen on * port http
130 root "/htdocs/fsl.domain.tld"
131 location "/.well-known/acme-challenge/*" {
132 root "/acme"
133 request strip 2
134 }
135 location * {
136 block return 301 "https://$HTTP_HOST$REQUEST_URI"
137 }
138 location "/*" {
139 fastcgi { param SCRIPT_FILENAME "/cgi-bin/scm" }
140 }
141 }
142
143 server "fsl.domain.tld" {
144 listen on * tls port https
145 root "/htdocs/fsl.domain.tld"
146 tls {
147 certificate "/etc/ssl/domain.tld.fullchain.pem"
148 key "/etc/ssl/private/domain.tld.key"
149 }
150 hsts {
151 max-age 15768000
152 preload
153 subdomains
154 }
155 connection max request body 104857600
156 location "/*" {
157 fastcgi { param SCRIPT_FILENAME "/cgi-bin/scm" }
158 }
159 location "/.well-known/acme-challenge/*" {
160 root "/acme"
161 request strip 2
162 }
163 }
164 ```
165
166 [The default limit][dlim] for HTTP messages in OpenBSD’s `httpd` server
167 is 1 MiB. Fossil chunks its sync protocol such that this is not
168 normally a problem, but when sending [unversioned content][uv], it uses
@@ -187,57 +187,57 @@
187 ensure you have a zone record for the subdomain with your registrar or
188 nameserver. Then open `/etc/acme-client.conf` as a privileged user to
189 configure the request.
190
191 ```dosini
192 authority letsencrypt {
193 api url "https://acme-v02.api.letsencrypt.org/directory"
194 account key "/etc/acme/letsencrypt-privkey.pem"
195 }
196
197 authority letsencrypt-staging {
198 api url "https://acme-staging.api.letsencrypt.org/directory"
199 account key "/etc/acme/letsencrypt-staging-privkey.pem"
200 }
201
202 domain domain.tld {
203 alternative names { www.domain.tld fsl.domain.tld }
204 domain key "/etc/ssl/private/domain.tld.key"
205 domain certificate "/etc/ssl/domain.tld.crt"
206 domain full chain certificate "/etc/ssl/domain.tld.fullchain.pem"
207 sign with letsencrypt
208 }
209 ```
210
211 Start `httpd` with the new configuration file, and issue the certificate
212 request.
213
214 ```console
215 $ doas rcctl start httpd
216 $ doas acme-client -vv domain.tld
217 acme-client: /etc/acme/letsencrypt-privkey.pem: account key exists (not creating)
218 acme-client: /etc/acme/letsencrypt-privkey.pem: loaded RSA account key
219 acme-client: /etc/ssl/private/domain.tld.key: generated RSA domain key
220 acme-client: https://acme-v01.api.letsencrypt.org/directory: directories
221 acme-client: acme-v01.api.letsencrypt.org: DNS: 172.65.32.248
222 ...
223 N(Q????Z???j?j?>W#????b???? H????eb??T??*? DNosz(???n{L}???D???4[?B] (1174 bytes)
224 acme-client: /etc/ssl/domain.tld.crt: created
225 acme-client: /etc/ssl/domain.tld.fullchain.pem: created
226 ```
227
228 A successful result will output the public certificate, full chain of
229 trust, and private key into the `/etc/ssl` directory as specified in
230 `acme-client.conf`.
231
232 ```console
233 $ doas ls -lR /etc/ssl
234 -r--r--r-- 1 root wheel 2.3K Mar 2 01:31:03 2018 domain.tld.crt
235 -r--r--r-- 1 root wheel 3.9K Mar 2 01:31:03 2018 domain.tld.fullchain.pem
236
237 /etc/ssl/private:
238 -r-------- 1 root wheel 3.2K Mar 2 01:31:03 2018 domain.tld.key
239 ```
240
241 Make sure to reopen `/etc/httpd.conf` to uncomment the second server
242 block responsible for serving HTTPS requests before proceeding.
243
@@ -249,36 +249,36 @@
249 execute the above Fossil CGI script—before checking that the syntax of
250 the `httpd.conf` configuration file is correct, and (re)starting the
251 server (if still running from requesting a Let's Encrypt certificate).
252
253 ```console
254 $ doas rcctl enable slowcgi
255 $ doas rcctl start slowcgi
256 slowcgi(ok)
257 $ doas httpd -vnf /etc/httpd.conf
258 configuration OK
259 $ doas rcctl start httpd
260 httpd(ok)
261 ```
262
263 ## <a id="clientconfig"></a>Configure Client
264
265 To facilitate creating new repositories and pushing them to the server,
266 add the following function to your `~/.cshrc` or `~/.zprofile` or the
267 config file for whichever shell you are using on your development box.
268
269 ```sh
270 finit() {
271 fossil init $1.fossil && \
272 chmod 664 $1.fossil && \
273 fossil open $1.fossil && \
274 fossil user password $USER $PASSWD && \
275 fossil remote-url https://$USER:[email protected]/$1 && \
276 rsync --perms $1.fossil [email protected]:/var/www/htdocs/fsl.domain.tld/ >/dev/null && \
277 chmod 644 $1.fossil && \
278 fossil ui
279 }
280 ```
281
282 This enables a new repository to be made with `finit repo`, which will
283 create the fossil repository file `repo.fossil` in the current working
284 directory; by default, the repository user is set to the environment
285
--- www/server/windows/iis.md
+++ www/server/windows/iis.md
@@ -32,11 +32,11 @@
3232
You will need to have the Fossil HTTP server running in the background,
3333
serving some local repository, bound to localhost on a fixed
3434
high-numbered TCP port. For the purposes of testing, simply start it by
3535
hand in your command shell of choice:
3636
37
- fossil serve --port 9000 --localhost repo.fossil
37
+ fossil serve --port 9000 --localhost repo.fossil
3838
3939
That command assumes you’ve got `fossil.exe` in your `%PATH%` and you’re
4040
in a directory holding `repo.fossil`. See [the platform-independent
4141
instructions](../any/none.md) for further details.
4242
4343
--- www/server/windows/iis.md
+++ www/server/windows/iis.md
@@ -32,11 +32,11 @@
32 You will need to have the Fossil HTTP server running in the background,
33 serving some local repository, bound to localhost on a fixed
34 high-numbered TCP port. For the purposes of testing, simply start it by
35 hand in your command shell of choice:
36
37 fossil serve --port 9000 --localhost repo.fossil
38
39 That command assumes you’ve got `fossil.exe` in your `%PATH%` and you’re
40 in a directory holding `repo.fossil`. See [the platform-independent
41 instructions](../any/none.md) for further details.
42
43
--- www/server/windows/iis.md
+++ www/server/windows/iis.md
@@ -32,11 +32,11 @@
32 You will need to have the Fossil HTTP server running in the background,
33 serving some local repository, bound to localhost on a fixed
34 high-numbered TCP port. For the purposes of testing, simply start it by
35 hand in your command shell of choice:
36
37 fossil serve --port 9000 --localhost repo.fossil
38
39 That command assumes you’ve got `fossil.exe` in your `%PATH%` and you’re
40 in a directory holding `repo.fossil`. See [the platform-independent
41 instructions](../any/none.md) for further details.
42
43
+22 -22
--- www/th1.md
+++ www/th1.md
@@ -54,15 +54,15 @@
5454
C/C++ programmers because TH1 does look a lot like C/C++, but the semantics
5555
of TH1 are closer to FORTH or Lisp than they are to C.
5656
5757
Consider the `if` command in TH1.
5858
59
- if {$current eq "dev"} {
60
- puts "hello"
61
- } else {
62
- puts "world"
63
- }
59
+ if {$current eq "dev"} {
60
+ puts "hello"
61
+ } else {
62
+ puts "world"
63
+ }
6464
6565
The example above is a single command. The first token, and the name
6666
of the command, is `if`.
6767
The second token is `$current eq "dev"` - an expression. (The outer {...}
6868
are removed from each token by the command parser.) The third token
@@ -83,16 +83,16 @@
8383
block delimiters as in C. This is how we can have a command that extends
8484
over multiple lines. It is also why the `else` keyword must be cuddled
8585
up with the closing brace for the `if` clause's scriptlet. The following
8686
is invalid Tcl/TH1:
8787
88
- if {$current eq "dev"} {
89
- puts "hello"
90
- }
91
- else {
92
- puts "world"
93
- }
88
+ if {$current eq "dev"} {
89
+ puts "hello"
90
+ }
91
+ else {
92
+ puts "world"
93
+ }
9494
9595
If you try to run this under either Tcl or TH1, the interpreter will
9696
tell you that there is no `else` command, because with the newline on
9797
the third line, you terminated the `if` command.
9898
@@ -99,13 +99,13 @@
9999
Occasionally in Tcl/TH1 scripts, you may need to use a backslash at the
100100
end of a line to allow a command to extend over multiple lines without
101101
being considered two separate commands. Here's an example from one of
102102
Fossil's test scripts:
103103
104
- return [lindex [regexp -line -inline -nocase -- \
105
- {^uuid:\s+([0-9A-F]{40}) } [eval [getFossilCommand \
106
- $repository "" info trunk]]] end]
104
+ return [lindex [regexp -line -inline -nocase -- \
105
+ {^uuid:\s+([0-9A-F]{40}) } [eval [getFossilCommand \
106
+ $repository "" info trunk]]] end]
107107
108108
Those backslashes allow the command to wrap nicely within a standard
109109
terminal width while telling the interpreter to consider those three
110110
lines as a single command.
111111
@@ -298,16 +298,16 @@
298298
always true.
299299
300300
Examples:
301301
302302
```
303
- capexpr {j o r} True if any one of j, o, or r are available
304
- capexpr {oh} True if both o and h are available
305
- capexpr {@2 @3 4 5 6} 2 or 3 available for anonymous or one of
306
- 4, 5 or 6 is available for the user
307
- capexpr L True if the user is logged in
308
- capexpr !L True if the user is not logged in
303
+capexpr {j o r} True if any one of j, o, or r are available
304
+capexpr {oh} True if both o and h are available
305
+capexpr {@2 @3 4 5 6} 2 or 3 available for anonymous or one of
306
+ 4, 5 or 6 is available for the user
307
+capexpr L True if the user is logged in
308
+capexpr !L True if the user is not logged in
309309
```
310310
311311
The `L` pseudo-capability is intended only to be used on its own or with
312312
the `!` prefix for implementing login/logout menus via the `mainmenu`
313313
site configuration option:
@@ -683,15 +683,15 @@
683683
To be clear, only one of the document classes identified by each STRING
684684
needs to be searchable in order for that argument to be true. But all
685685
arguments must be true for this routine to return true. Hence, to see
686686
if ALL document classes are searchable:
687687
688
- if {[searchable c d t w]} {...}
688
+ if {[searchable c d t w]} {...}
689689
690690
But to see if ANY document class is searchable:
691691
692
- if {[searchable cdtw]} {...}
692
+ if {[searchable cdtw]} {...}
693693
694694
This command is useful for enabling or disabling a "Search" entry on the
695695
menu bar.
696696
697697
<a id="setParameter"></a>TH1 setParameter Command
698698
--- www/th1.md
+++ www/th1.md
@@ -54,15 +54,15 @@
54 C/C++ programmers because TH1 does look a lot like C/C++, but the semantics
55 of TH1 are closer to FORTH or Lisp than they are to C.
56
57 Consider the `if` command in TH1.
58
59 if {$current eq "dev"} {
60 puts "hello"
61 } else {
62 puts "world"
63 }
64
65 The example above is a single command. The first token, and the name
66 of the command, is `if`.
67 The second token is `$current eq "dev"` - an expression. (The outer {...}
68 are removed from each token by the command parser.) The third token
@@ -83,16 +83,16 @@
83 block delimiters as in C. This is how we can have a command that extends
84 over multiple lines. It is also why the `else` keyword must be cuddled
85 up with the closing brace for the `if` clause's scriptlet. The following
86 is invalid Tcl/TH1:
87
88 if {$current eq "dev"} {
89 puts "hello"
90 }
91 else {
92 puts "world"
93 }
94
95 If you try to run this under either Tcl or TH1, the interpreter will
96 tell you that there is no `else` command, because with the newline on
97 the third line, you terminated the `if` command.
98
@@ -99,13 +99,13 @@
99 Occasionally in Tcl/TH1 scripts, you may need to use a backslash at the
100 end of a line to allow a command to extend over multiple lines without
101 being considered two separate commands. Here's an example from one of
102 Fossil's test scripts:
103
104 return [lindex [regexp -line -inline -nocase -- \
105 {^uuid:\s+([0-9A-F]{40}) } [eval [getFossilCommand \
106 $repository "" info trunk]]] end]
107
108 Those backslashes allow the command to wrap nicely within a standard
109 terminal width while telling the interpreter to consider those three
110 lines as a single command.
111
@@ -298,16 +298,16 @@
298 always true.
299
300 Examples:
301
302 ```
303 capexpr {j o r} True if any one of j, o, or r are available
304 capexpr {oh} True if both o and h are available
305 capexpr {@2 @3 4 5 6} 2 or 3 available for anonymous or one of
306 4, 5 or 6 is available for the user
307 capexpr L True if the user is logged in
308 capexpr !L True if the user is not logged in
309 ```
310
311 The `L` pseudo-capability is intended only to be used on its own or with
312 the `!` prefix for implementing login/logout menus via the `mainmenu`
313 site configuration option:
@@ -683,15 +683,15 @@
683 To be clear, only one of the document classes identified by each STRING
684 needs to be searchable in order for that argument to be true. But all
685 arguments must be true for this routine to return true. Hence, to see
686 if ALL document classes are searchable:
687
688 if {[searchable c d t w]} {...}
689
690 But to see if ANY document class is searchable:
691
692 if {[searchable cdtw]} {...}
693
694 This command is useful for enabling or disabling a "Search" entry on the
695 menu bar.
696
697 <a id="setParameter"></a>TH1 setParameter Command
698
--- www/th1.md
+++ www/th1.md
@@ -54,15 +54,15 @@
54 C/C++ programmers because TH1 does look a lot like C/C++, but the semantics
55 of TH1 are closer to FORTH or Lisp than they are to C.
56
57 Consider the `if` command in TH1.
58
59 if {$current eq "dev"} {
60 puts "hello"
61 } else {
62 puts "world"
63 }
64
65 The example above is a single command. The first token, and the name
66 of the command, is `if`.
67 The second token is `$current eq "dev"` - an expression. (The outer {...}
68 are removed from each token by the command parser.) The third token
@@ -83,16 +83,16 @@
83 block delimiters as in C. This is how we can have a command that extends
84 over multiple lines. It is also why the `else` keyword must be cuddled
85 up with the closing brace for the `if` clause's scriptlet. The following
86 is invalid Tcl/TH1:
87
88 if {$current eq "dev"} {
89 puts "hello"
90 }
91 else {
92 puts "world"
93 }
94
95 If you try to run this under either Tcl or TH1, the interpreter will
96 tell you that there is no `else` command, because with the newline on
97 the third line, you terminated the `if` command.
98
@@ -99,13 +99,13 @@
99 Occasionally in Tcl/TH1 scripts, you may need to use a backslash at the
100 end of a line to allow a command to extend over multiple lines without
101 being considered two separate commands. Here's an example from one of
102 Fossil's test scripts:
103
104 return [lindex [regexp -line -inline -nocase -- \
105 {^uuid:\s+([0-9A-F]{40}) } [eval [getFossilCommand \
106 $repository "" info trunk]]] end]
107
108 Those backslashes allow the command to wrap nicely within a standard
109 terminal width while telling the interpreter to consider those three
110 lines as a single command.
111
@@ -298,16 +298,16 @@
298 always true.
299
300 Examples:
301
302 ```
303 capexpr {j o r} True if any one of j, o, or r are available
304 capexpr {oh} True if both o and h are available
305 capexpr {@2 @3 4 5 6} 2 or 3 available for anonymous or one of
306 4, 5 or 6 is available for the user
307 capexpr L True if the user is logged in
308 capexpr !L True if the user is not logged in
309 ```
310
311 The `L` pseudo-capability is intended only to be used on its own or with
312 the `!` prefix for implementing login/logout menus via the `mainmenu`
313 site configuration option:
@@ -683,15 +683,15 @@
683 To be clear, only one of the document classes identified by each STRING
684 needs to be searchable in order for that argument to be true. But all
685 arguments must be true for this routine to return true. Hence, to see
686 if ALL document classes are searchable:
687
688 if {[searchable c d t w]} {...}
689
690 But to see if ANY document class is searchable:
691
692 if {[searchable cdtw]} {...}
693
694 This command is useful for enabling or disabling a "Search" entry on the
695 menu bar.
696
697 <a id="setParameter"></a>TH1 setParameter Command
698

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button