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)).
|
[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
|
||||||
Configuration is read from, in increasing priority:
|
Configuration is read from, in increasing priority:
|
||||||
1. Built-in defaults
|
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/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` |
|
| `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)) |
|
| `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
|
## 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"
|
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
|
if [[ $DO_RELEASE -eq 1 ]]; then
|
||||||
install -DT $BUILD_DIR/job-search-$VERSION $RELEASE_DIR/job-search
|
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`
|
ARCH=`dpkg --print-architecture`
|
||||||
tar -czf $RELEASE_DIR/job-search-$VERSION-$ARCH.tar.gz \
|
tar -czf $RELEASE_DIR/job-search-$VERSION-$ARCH.tar.gz \
|
||||||
--transform "s,^$RELEASE_DIR/,job-search-$VERSION-$ARCH/," \
|
--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"
|
echo "Installed $RELEASE_DIR/job-search"
|
||||||
fi
|
fi
|
||||||
Reference in new issue
Block a user