Added a systemd unit and logrotate configuration, packaged in the release
This commit is contained in:
1 parent
1e3acaeff3
commit
2aeb2993b0
4 files changed
+137
-2
No files matched your search
@@ -39,6 +39,37 @@ The `sqlite_fts5` tag is needed for the database's title search (see
|
||||
[Testing](#testing)).
|
||||
|
||||
|
||||
## Running as a service
|
||||
`deploy/job-search.service` is a systemd unit running `job-search serve`
|
||||
(the server and every enabled source's fetcher) as a `job-search` system
|
||||
user, from `/usr/local/bin/job-search` with `/etc/job-search/config.yaml`.
|
||||
Its comments give the install steps. It keeps its data in
|
||||
`/var/lib/job-search` and its log in `/var/log/job-search`, the only places
|
||||
it can write, so set `database.file` and `logging.file` there.
|
||||
|
||||
- The database isn't migrated on start: run `job-search migrate up`
|
||||
(`--create` the first time) as the `job-search` user before the first
|
||||
start and after each upgrade.
|
||||
- A failing source stops `serve` on purpose; the unit restarts it after
|
||||
30s.
|
||||
|
||||
### Rotating the logs
|
||||
`job-search` opens its log file once and has no signal to reopen it, so
|
||||
logrotate must copy the file and truncate it in place (`copytruncate`); a
|
||||
line written between the two is lost. `deploy/job-search.logrotate` does
|
||||
this weekly for every `*.log` in `/var/log/job-search` (the log and, if
|
||||
`server.access_log` is set there, the access log), keeping 8 weeks,
|
||||
compressed. `/var/log/job-search` belongs to the service user, so it rotates
|
||||
as that user (`su job-search job-search`); logrotate refuses otherwise.
|
||||
|
||||
```bash
|
||||
# from the release tarball's directory (deploy/job-search.logrotate in the repo)
|
||||
sudo install -m 644 job-search.logrotate /etc/logrotate.d/job-search
|
||||
sudo logrotate --debug /etc/logrotate.d/job-search # dry run: what it would do
|
||||
sudo logrotate --force /etc/logrotate.d/job-search # rotate now, to check
|
||||
```
|
||||
|
||||
|
||||
## Configuration
|
||||
Configuration is read from, in increasing priority:
|
||||
1. Built-in defaults
|
||||
@@ -212,6 +243,7 @@ second one fails with "address already in use".
|
||||
| `internal/version` | Version information set at build time |
|
||||
| `internal/frontend` | Serves the frontend's build output; embeds `dist/`, copied there from `web/dist` by `npm run sync` |
|
||||
| `web` | The frontend (see [web](web/README.md)) |
|
||||
| `deploy` | The systemd unit and logrotate configuration (see [Running as a service](#running-as-a-service)) |
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# logrotate configuration for job-search's logs (see README.md, "Rotating
|
||||
# the logs"). Install as /etc/logrotate.d/job-search; it is in the release
|
||||
# tarball next to the binary.
|
||||
#
|
||||
# job-search opens its log file once and has no signal to reopen it, so the
|
||||
# file is copied and then truncated in place (copytruncate). A line written
|
||||
# between the copy and the truncation is lost.
|
||||
/var/log/job-search/*.log {
|
||||
weekly
|
||||
rotate 8
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
copytruncate
|
||||
# /var/log/job-search belongs to the service user, so rotate as it.
|
||||
su job-search job-search
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
# job-search: serves the API and frontend, and runs the enabled sources'
|
||||
# fetchers (job-search serve). See README.md, "Running as a service".
|
||||
#
|
||||
# Install, from the release tarball's directory (job-search-<version>-<arch>):
|
||||
# sudo useradd --system --home-dir /var/lib/job-search --shell /usr/sbin/nologin job-search
|
||||
# sudo install -m 755 job-search /usr/local/bin/job-search
|
||||
# sudo install -d -m 750 -o root -g job-search /etc/job-search
|
||||
# sudo install -m 640 -o root -g job-search config.yaml /etc/job-search/config.yaml
|
||||
# sudo install -d -m 750 -o job-search -g job-search /var/lib/job-search /var/log/job-search
|
||||
# sudo -u job-search /usr/local/bin/job-search --config /etc/job-search/config.yaml migrate up --create
|
||||
# sudo install -m 644 job-search.service /etc/systemd/system/
|
||||
# sudo systemctl daemon-reload
|
||||
# sudo systemctl enable --now job-search
|
||||
#
|
||||
# /etc/job-search/config.yaml should set at least:
|
||||
# database:
|
||||
# file: /var/lib/job-search/jobsearch.db
|
||||
# logging:
|
||||
# file: /var/log/job-search/job-search.log
|
||||
# Without logging.file, logs go to the journal (as coloured text). Rotate the
|
||||
# log file with job-search.logrotate:
|
||||
# sudo install -m 644 job-search.logrotate /etc/logrotate.d/job-search
|
||||
#
|
||||
# After each upgrade, migrate the database before restarting:
|
||||
# sudo -u job-search /usr/local/bin/job-search --config /etc/job-search/config.yaml migrate up
|
||||
# sudo systemctl restart job-search
|
||||
|
||||
[Unit]
|
||||
Description=Job Search: procurement opportunities server and fetcher
|
||||
Documentation=https://git.avsdev.uk/Go/job-search
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=job-search
|
||||
Group=job-search
|
||||
# /var/lib/job-search and /var/log/job-search, created and owned by the
|
||||
# service user; the only places it can write.
|
||||
StateDirectory=job-search
|
||||
StateDirectoryMode=0750
|
||||
LogsDirectory=job-search
|
||||
LogsDirectoryMode=0750
|
||||
WorkingDirectory=/var/lib/job-search
|
||||
ExecStart=/usr/local/bin/job-search --config /etc/job-search/config.yaml serve
|
||||
# serve shuts down cleanly on SIGTERM: the HTTP server drains and in-flight
|
||||
# fetches get up to 10s.
|
||||
KillSignal=SIGTERM
|
||||
TimeoutStopSec=30
|
||||
# A failing source stops serve on purpose; restart to retry it.
|
||||
Restart=on-failure
|
||||
RestartSec=30
|
||||
UMask=0027
|
||||
|
||||
# Hardening
|
||||
NoNewPrivileges=yes
|
||||
CapabilityBoundingSet=
|
||||
AmbientCapabilities=
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
PrivateTmp=yes
|
||||
PrivateDevices=yes
|
||||
ProtectKernelTunables=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectKernelLogs=yes
|
||||
ProtectControlGroups=yes
|
||||
ProtectClock=yes
|
||||
ProtectHostname=yes
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||||
RestrictNamespaces=yes
|
||||
RestrictRealtime=yes
|
||||
RestrictSUIDSGID=yes
|
||||
LockPersonality=yes
|
||||
MemoryDenyWriteExecute=yes
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallFilter=~@privileged @resources
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
+7
-2
@@ -62,12 +62,17 @@ go build \
|
||||
|
||||
echo "Built $BUILD_DIR/job-search-$VERSION"
|
||||
|
||||
# If proper release, copy to output directory for packaging
|
||||
# If proper release, copy to output directory for packaging, with the
|
||||
# systemd unit and logrotate configuration (see README.md, "Running as a
|
||||
# service")
|
||||
if [[ $DO_RELEASE -eq 1 ]]; then
|
||||
install -DT $BUILD_DIR/job-search-$VERSION $RELEASE_DIR/job-search
|
||||
install -DT -m 644 deploy/job-search.service $RELEASE_DIR/job-search.service
|
||||
install -DT -m 644 deploy/job-search.logrotate $RELEASE_DIR/job-search.logrotate
|
||||
ARCH=`dpkg --print-architecture`
|
||||
tar -czf $RELEASE_DIR/job-search-$VERSION-$ARCH.tar.gz \
|
||||
--transform "s,^$RELEASE_DIR/,job-search-$VERSION-$ARCH/," \
|
||||
$RELEASE_DIR/job-search
|
||||
$RELEASE_DIR/job-search $RELEASE_DIR/job-search.service \
|
||||
$RELEASE_DIR/job-search.logrotate
|
||||
echo "Installed $RELEASE_DIR/job-search"
|
||||
fi
|
||||
Reference in new issue
Block a user