Add a systemd service file
svenstaro opened this issue · 10 comments
Hey, I think it would make sense to have a systemd service file upstream. It should source environment variables from /etc/default/atuin
.
I think something like this could work:
[Unit]
Description=Start the atuin sync service
[Service]
ExecStart=atuin server start
Restart=on-failure
User=atuin
EnvironmentFile=/etc/default/atuin
PrivateTmp=yes
PrivateUsers=yes
PrivateDevices=yes
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=yes
ProtectClock=yes
ProtectControlGroups=yes
ProtectKernelLogs=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
ProtectProc=invisible
[Install]
WantedBy=multi-user.target
If you like this, I could make an MR for this along with a sysusers file to create the atuin
user.
Sounds good to me! I'd also really appreciate it if you could update the docs with information on how to use this 🙏
I tried to do that for Arch Linux package and had issues with atuin server searching for configuration in hardcoded $HOME variable and wanted write access to it. Also it would be nice for DB_URI to support (passwordless) socket in linux - couldnt' figure out how to set this up in sqlx.
For reference my work in progress files:
atuin.env
ATUIN_CONFIG_DIR=/var/lib/atuin
ATUIN_HOST="127.0.0.1"
ATUIN_PORT=8888
ATUIN_OPEN_REGISTRATION=true
ATUIN_DB_URI="postgres://username:password@localhost/atuin" # socket how?
atuin.service
[Unit]
Description=Atuin server
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
[Service]
User=atuin
Group=atuin
ExecStart=/usr/bin/atuin server start
ReadOnlyPaths=/etc/atuin
EnvironmentFile=/etc/atuin/atuin.env
ReadWritePaths=/var/lib/atuin
# Hardening options
CapabilityBoundingSet=
AmbientCapabilities=
NoNewPrivileges=true
ProtectHome=true
ProtectSystem=strict
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
PrivateTmp=true
PrivateDevices=true
LockPersonality=true
[Install]
WantedBy=multi-user.target
atuin.sysusers
u atuin - "Atuin user" - -
atuin.tmpfiles
d %L/atuin 750 atuin atuin - -
d %t/atuin 750 atuin atuin - -
d %S/atuin 750 atuin atuin - -
@inglor Wouldn't it be fine to give it ReadWrite access to its own home, then? It has its own user anyway. My question is though: What is actually stored there, given that all data should be put into the DB?
I opened up drafts in both repos. Happy for reviews/tests/contributions.
What is actually stored there, given that all data should be put into the DB?
I think when the server starts if the server.toml
is not there it copies the default. In Arch at least normally we would put the server.toml
in /etc/atuin/server.toml
and link to /usr/share/atuin/server.toml
with /usr/share/atuin/
being set as the "home" directory of the atuin
user.
Wouldn't it be fine to give it ReadWrite access to its own home, then?
I mean sure, it should have ReadWrite access to /usr/share/atuin/
but altering it's own server configuration on runtime seems slightly weird and even wrong for some patterns.
Generally reading through the code it seems to me that it was not considered to be executed as a systemd daemon and all my attempts above feels a bit like hacks to make it work, but could be wrong :)
As another data point, I'm currently running a server like this:
# /etc/systemd/system/atuin.service
[Unit]
Description=Atuin shell history server
Requires=postgresql.service
After=postgresql.service
[Service]
User=atuin
WorkingDirectory=/srv/atuin
ExecStart=/usr/bin/atuin server start
Environment=ATUIN_CONFIG_DIR=. TZ=UTC RUST_LOG=atuin::api=info
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
# /etc/sysusers.d/atuin.conf
u atuin - "Atuin shell history server" /srv/atuin
# /etc/tmpfiles.d/atuin.conf
d /srv/atuin 0770 atuin atuin
# /srv/atuin/server.toml
host = "::"
port = 585
open_registration = false
db_uri = "postgres://?host=/run/postgresql&dbname=atuin&user=atuin"
The problem is that it is not possible to run atuin under a service user that does not have a home dir, because it tries to write a server.toml
and abends if it can't.
I solved this by settting the HOME
env var in systemd to the directory where the server config is located.
[Unit]
Description=atuin
After=network.target postgresql.service
Requires=postgresql.service
# Remove postgresql.service above, if database is remote
[Service]
Type=simple
User=atuin
Group=atuin
EnvironmentFile=/etc/atuin/atuin.cfg
WorkingDirectory=/etc/atuin
Environment=HOME="/etc/atuin"
ExecStart=/usr/sbin/atuin server start
StandardOutput=append:/var/log/atuin/atuin.log
StandardError=append:/var/log/atuin/atuin.log
Restart=on-failure
RestartSec=3
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
configuration in hardcoded $HOME
it is not possible to run atuin under a service user that does not have a home dir
Neither of the above are quite true. If you look at what @heftig has shared, the docs, or the code, you'll see ATUIN_CONFIG_DIR
.
This can be set to something other than $HOME, to solve exactly the problems you raise.
The only time it writes to that directory is to set the default config file. I guess we could have an option to disable this, though it won't do it if the file already exists.
Ah, I missed that, even though I read the docs. I hid my previous comment, since it doesn't add any useful info. Thanks for letting me know about the ATUIN_CONFIG_DIR
env var.
I'll update the guide on the forum accodingly, or better yet a note. It does not matter whether HOME
or ATUIN_CONFIG_DIR
is set in the unit file.