114 lines
4.3 KiB
Desktop File
114 lines
4.3 KiB
Desktop File
# ─────────────────────────────────────────────────────────────────────
|
|
# Morphit — daily DB backup service.
|
|
#
|
|
# Runs once when triggered by morphit-backup.timer (next directory
|
|
# over). See ops/backup/morphit-backup.sh for what the script
|
|
# actually does.
|
|
#
|
|
# Why oneshot:
|
|
# - The script runs to completion in a few seconds (small DB)
|
|
# to a few minutes (large DB), then exits. oneshot is the
|
|
# correct service type for a finite-duration job triggered
|
|
# by a timer.
|
|
#
|
|
# Why User=morphit:
|
|
# - The script needs to read pg credentials. Two common
|
|
# patterns:
|
|
# (a) peer auth: postgres trusts the local UNIX user
|
|
# when their name matches the DB user. Operator
|
|
# creates the morphit system user with `useradd
|
|
# --system morphit`; postgres role `morphit_indexer`
|
|
# grants USAGE to the morphit user via
|
|
# `host morphit_indexer morphit ::1/128 peer`.
|
|
# (b) ~/.pgpass: the morphit system user keeps a
|
|
# password file at /home/morphit/.pgpass with
|
|
# 600 perms.
|
|
# Either way, running as `morphit` is right.
|
|
#
|
|
# Hardening directives:
|
|
# - PrivateTmp=true → the dump never touches /tmp shared
|
|
# space.
|
|
# - ProtectSystem=strict → script can only write to
|
|
# ReadWritePaths (the backup dir + /var/log).
|
|
# - NoNewPrivileges=true → can't escalate via setuid bins.
|
|
# - ProtectHome=read-only → can read ~/.pgpass but can't
|
|
# write home dirs of other users.
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
|
|
[Unit]
|
|
Description=Morphit indexer daily DB backup
|
|
Documentation=file:///home/morphit/morphit/docs/RUN-A-MORPHIT-NODE.md
|
|
# Backups should run AFTER the indexer has had a chance to
|
|
# settle from any maintenance restart, so the DB isn't being
|
|
# heavily written during the dump. postgres reaching ready
|
|
# state is the strict prerequisite.
|
|
After=postgresql.service
|
|
Wants=postgresql.service
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
User=morphit
|
|
Group=morphit
|
|
|
|
# The wizard writes BACKUP_ENV to /etc/morphit/backup.env.
|
|
# Manual installs that put it elsewhere can override here.
|
|
Environment=BACKUP_ENV=/etc/morphit/backup.env
|
|
|
|
# The script lives at a stable system path AFTER `sudo install`.
|
|
# The repo copy at ops/backup/morphit-backup.sh is the source;
|
|
# the install command in the operator post-setup checklist
|
|
# copies it to /usr/local/lib/morphit/. This decoupling means
|
|
# the systemd unit doesn't need to know where the operator
|
|
# checked out the repo (could be /home/morphit/morphit, could
|
|
# be /opt/morphit, could be /srv/morphit-deploy).
|
|
ExecStart=/usr/local/lib/morphit/morphit-backup.sh
|
|
|
|
# ─── Hardening ───
|
|
PrivateTmp=true
|
|
ProtectSystem=strict
|
|
ProtectHome=read-only
|
|
NoNewPrivileges=true
|
|
ProtectKernelTunables=true
|
|
ProtectKernelModules=true
|
|
RestrictNamespaces=true
|
|
LockPersonality=true
|
|
RestrictRealtime=true
|
|
RestrictSUIDSGID=true
|
|
|
|
# Where the script is allowed to write. The default matches the
|
|
# wizard's default BACKUP_DIR.
|
|
#
|
|
# IF YOU CHANGED BACKUP_DIR in /etc/morphit/backup.env to a
|
|
# different path, this directive needs to match — otherwise the
|
|
# script will be killed by ProtectSystem=strict the first time
|
|
# it tries to mkdir that path. Override without editing this
|
|
# shipped unit:
|
|
#
|
|
# sudo systemctl edit morphit-backup.service
|
|
#
|
|
# and add:
|
|
#
|
|
# [Service]
|
|
# ReadWritePaths=
|
|
# ReadWritePaths=/your/actual/backup/dir
|
|
#
|
|
# (The empty `ReadWritePaths=` resets the default before adding
|
|
# your override; without it, both paths end up writable, which
|
|
# is also fine but slightly less tidy.)
|
|
ReadWritePaths=/home/morphit/backups
|
|
|
|
# Don't restart on failure. A failed backup should be visible
|
|
# in `journalctl -u morphit-backup.service`; the next timer
|
|
# tick will retry. Auto-restart of a dump that's failing
|
|
# (auth issue, disk full) just spams logs without making
|
|
# anything better.
|
|
Restart=no
|
|
|
|
# Log identification — shows up as `morphit-backup` in
|
|
# journalctl rather than the script's PID.
|
|
SyslogIdentifier=morphit-backup
|
|
|
|
[Install]
|
|
# The timer triggers this — no separate Install wanted by the
|
|
# service itself. The timer's [Install] section is what gets
|
|
# enabled.
|