Fossil SCM

fossil-scm / www / server / debian / service.md
1
# Serving via systemd on Debian and Ubuntu
2
3
[`systemd`][sdhome] is the service management framework in all major
4
in-support versions of Linux. There are multiple ways to run Fossil
5
under `systemd`.
6
7
[sdhome]: https://www.freedesktop.org/wiki/Software/systemd/
8
[wpa]: https://en.wikipedia.org/wiki/Systemd#Adoption
9
10
11
## Containerized Service
12
13
Two of the methods for running [containerized Fossil][cntdoc] integrate
14
with `systemd`, potentially obviating the more direct methods below:
15
16
* If you take [the Podman method][podman] of running containerized
17
Fossil, it opens the `podman generate systemd` option for you, as
18
exemplified in [the `fslsrv` script][fslsrv] used on this author’s
19
public Fossil-based web site. That script pulls its container images
20
from [my Docker Hub repo][dhrepo] to avoid the need for my public
21
Fossil server to have build tools and a copy of the Fossil source
22
tree. You’re welcome to use my images as-is, or you may use these
23
tools to bounce custom builds up through a separate container image
24
repo you manage.
25
26
* If you’re willing to give up [a lot of features][nsweak] relative to
27
Podman, and you’re willing to tolerate a lot more manual
28
administrivia, [the nspawn method][nspawn] has a lot less overhead,
29
being a direct feature of `systemd` itself.
30
31
Both of these options provide [better security][cntsec] than running
32
Fossil directly under `systemd`, among [other benefits][cntdoc].
33
34
[cntdoc]: ../../containers.md
35
[cntsec]: ../../containers.md#security
36
[dhrepo]: https://hub.docker.com/r/tangentsoft/fossil
37
[fslsrv]: https://tangentsoft.com/fossil/dir?name=bin
38
[nspawn]: ../../containers.md#nspawn
39
[nsweak]: ../../containers.md#nspawn-weaknesses
40
[podman]: ../../containers.md#podman
41
42
43
## User Service
44
45
A fun thing you can easily do with `systemd` that you can’t directly do
46
with older technologies like `inetd` and `xinetd` is to set a server up
47
as a “user” service.
48
49
You can’t listen on TCP port 80 with this method due to security
50
restrictions on TCP ports in every OS where `systemd` runs, but you can
51
create a listener socket on a high-numbered (≥ 1024) TCP port,
52
suitable for sharing a Fossil repo to a workgroup on a private LAN.
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
75
service’s owner.
76
77
The result is essentially [the standalone server method](../any/none.md)
78
coupled with an intelligent service manager that will start it
79
automatically in the background on system boot, perform automatic
80
service restarts with back-off logic, and more, making this much more
81
robust than the by-hand launches of `fossil` in the platform-independent
82
Fossil server instructions. The service will stay up until we
83
explicitly tell it to shut down.
84
85
This scheme couples well with [the generic SCGI instructions][scgi] as
86
it requires a way to run the underlying repository server in the
87
background. Given that its service port is then proxied by SCGI, it
88
follows that it doesn’t need to run as a system service. A user service
89
works perfectly well for this.
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
105
This scheme isolates the permissions needed by the Fossil server, which
106
reduces the amount of damage it can do if there is ever a
107
remotely-triggerable security flaw found in Fossil.
108
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
120
121
122
123
### System Service Alternative
124
125
There are some common reasons that you’d have good cause to install
126
Fossil as a system-level service rather than the prior user-level one:
127
128
* You’re using [the new `fossil server --cert` feature][sslsrv] to get
129
TLS service and want it to listen directly on port 443, rather than be
130
proxied, as one had to do before Fossil got the ability to act as a
131
TLS server itself. That requires root privileges, so you can’t run
132
it as a user-level service.
133
134
* You’re proxying Fossil with [nginx](./nginx.md) or similar, allowing
135
it to bind to high-numbered ports, but because it starts as a system
136
service, you can’t get Fossil into the same dependency chain to
137
ensure things start up and shut down in the proper order unless it
138
*also* runs as a system service.
139
140
* You want to make use of Fossil’s [chroot jail feature][cjail], which
141
requires the server to start as root.
142
143
There are just a small set of changes required:
144
145
1. Install the unit file to one of the persistent system-level unit
146
file directories. Typically, these are:
147
148
/etc/systemd/system
149
/lib/systemd/system
150
151
2. Add `User` and `Group` directives to the `[Service]` section so
152
Fossil runs as a normal user, preferably one with access only to
153
the Fossil repo files, rather than running as `root`.
154
155
[sslsrv]: ../../ssl-server.md
156
[cjail]: ../../chroot.md
157
158
159
## Socket Activation
160
161
Another useful method to serve a Fossil repo via `systemd` is via a
162
socket listener, which `systemd` calls “[socket activation][sa],”
163
roughly equivalent to [the ancient `inetd` method](../any/inetd.md).
164
It’s more complicated, but it has some nice properties.
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
185
above.
186
187
This configuration says more or less the same thing as the socket part
188
of an `inetd` entry [exemplified elsewhere in this
189
documentation](../any/inetd.md).
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
211
`chroot(2)` jail](../../chroot.md) rooted at the `WorkingDirectory`
212
we’ve configured above, shortly after each `fossil http` call starts.
213
214
The `Restart*` directives we had in the user service configuration above
215
are unnecessary for this method, since Fossil isn’t supposed to remain
216
running under it. Each HTTP hit starts one Fossil instance, which
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
In all of this, realize that we’re able to manipulate a single socket
252
listener or single service instance at a time, rather than reload the
253
whole externally-facing network configuration as with the far more
254
primitive `inetd` service.
255
256
[sa]: http://0pointer.de/blog/projects/socket-activation.html
257
258
259
*[Return to the top-level Fossil server article.](../)*
260

Keyboard Shortcuts

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