Native VM install kit: systemd units, launcher, install and upgrade scripts; backups, restore and doctor without docker exec; DEPLOY.md VM, NPM and NFS sections
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# Packet Station: the web app (uvicorn on port 8000, the API and the built frontend).
|
||||
# Installed by deploy/vm/install.sh into /etc/systemd/system. See docs/DEPLOY.md, "Native VM install".
|
||||
# NPM on docker-1 is the only client allowed on port 8000 (packetstation-firewall.service).
|
||||
[Unit]
|
||||
Description=Packet Station web app
|
||||
Documentation=file:///opt/packetstation/current/docs/DEPLOY.md
|
||||
Requires=packetstation-migrate.service
|
||||
# Wants, not Requires: a restart of nftables.service must not restart the app. ExecStartPre checks the table.
|
||||
Wants=packetstation-firewall.service
|
||||
After=packetstation-migrate.service packetstation-firewall.service [email protected] network-online.target
|
||||
Wants=[email protected] network-online.target
|
||||
StartLimitIntervalSec=300
|
||||
StartLimitBurst=5
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=packetstation
|
||||
Group=packetstation
|
||||
EnvironmentFile=/etc/packetstation/packetstation.env
|
||||
# The app's secrets only. It never gets the VISUAL or M-Files password.
|
||||
LoadCredential=postgres_app_password:/etc/packetstation/secrets/postgres_app_password
|
||||
LoadCredential=ldap_bind_password:/etc/packetstation/secrets/ldap_bind_password
|
||||
LoadCredential=session_key:/etc/packetstation/secrets/session_key
|
||||
LoadCredential=seal_key:/etc/packetstation/secrets/seal_key
|
||||
# The app never listens without the firewall table in place ("+": this check runs as root).
|
||||
ExecStartPre=+/usr/sbin/nft list table inet packetstation
|
||||
ExecStart=/opt/packetstation/current/deploy/vm/ps-launch.sh app
|
||||
SyslogIdentifier=packetstation-app
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
TimeoutStopSec=30s
|
||||
WorkingDirectory=/
|
||||
UMask=0027
|
||||
MemoryMax=1G
|
||||
LimitNOFILE=16384
|
||||
|
||||
# Sandbox. Read-only file system except the assets and the archive mount.
|
||||
# The leading "-" lets the app start while the archive is not mounted (ARCHIVE_ROOT unset).
|
||||
ReadWritePaths=/var/lib/packetstation/assets
|
||||
ReadWritePaths=-/mnt/packetstation-archive
|
||||
InaccessiblePaths=/etc/packetstation/secrets
|
||||
NoNewPrivileges=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
PrivateTmp=yes
|
||||
PrivateDevices=yes
|
||||
ProtectKernelTunables=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectKernelLogs=yes
|
||||
ProtectControlGroups=yes
|
||||
ProtectClock=yes
|
||||
ProtectHostname=yes
|
||||
ProtectProc=invisible
|
||||
# AF_NETLINK: glibc's getaddrinfo asks the kernel for the local addresses through it.
|
||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK
|
||||
RestrictNamespaces=yes
|
||||
RestrictRealtime=yes
|
||||
RestrictSUIDSGID=yes
|
||||
LockPersonality=yes
|
||||
RemoveIPC=yes
|
||||
CapabilityBoundingSet=
|
||||
AmbientCapabilities=
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallErrorNumber=EPERM
|
||||
# Not set: MemoryDenyWriteExecute. pypdfium2 goes through ctypes, whose callbacks may need
|
||||
# writable and executable memory. Turn it on only after a filing and a print pass on the test VM.
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user