Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: add systemd chapter #142282

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft

Conversation

happysalada
Copy link
Contributor

Motivation for this change

Systemd has many features, some useful to create modules, but most features are hard to discover and use if you don't already know about them. This is an attempt at covering the basics that are useful in nixpkgs
see #102397 for more details.

Please note that this is still an overview, I would like feedback on

  • Potential secctions that you think are important but you feel are missing
  • Better order of the section to create a more natural flow.
  • Better place to put that documentation ?

I will populate each sections shortly, ideally there is consensus on the sections and their order before that.

Things done
  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • 21.11 Release Notes (or backporting 21.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

@github-actions github-actions bot added the 8.has: documentation This PR adds or changes documentation label Oct 20, 2021
@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux labels Oct 20, 2021
@rnhmjoj
Copy link
Contributor

rnhmjoj commented Oct 20, 2021

Note that there are already a couple chapters about systemd in the manual. So, you may want to merge or move them.

@jtojnar
Copy link
Member

jtojnar commented Oct 20, 2021

Should not this rather go to NixOS manual?

@davidak
Copy link
Member

davidak commented Oct 20, 2021

@happysalada thanks for starting this!

Can you make the PR a draft until it is ready to merge?

@happysalada happysalada marked this pull request as draft October 20, 2021 16:41
@happysalada
Copy link
Contributor Author

This should indeed go to nixos manual.
let me also have a look at merging existing docs on it.
ryan also mentioned adding a chapter on tmpfiles on matrix.


From the [project's webpage](https://systemd.io/)
```
systemd is a suite of basic building blocks for a Linux system. It provides a system and service manager that runs as PID 1 and starts the rest of the system.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess, quoting (i.e. > systemd is [...]) is more correct here semantically, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh instead of a triple backtick, sure, works for me.

- Initialisation of state and dependents (e.g. database)
Talk about adding a systemd service to handle database initialisation
- Database management
Talk about connection via a unix socket for more performance and reduced secret management
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you should link these to the actual resource, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about adding links to examples in nixpkgs. What do you mean by actual resource ? Perhaps the article that explains why that is ? I don't think I've ever seen it explained all together, more like pieces of the puzzles everywhere. Some place tells you about default authentication method on postgres, and then I've seen somewhere the fact that performances are actually improved with a unix socket. I can probably find 2 references for each of those phenomenon.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by actual resource

Anything where I can read up how to use the mentioned features :)

Also, while I appreciated the overall idea, a general suggestion: we shouldn't duplicate too much systemd docs here because we'll risk having outdated information here in that case, but for now this document seems quite OK (just thought I'd mention this) :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed on this. I'm going to try to just describe how things should be used, without giving too much details. Please comment if you see things that you think can potentially rot. It's important to not have documentation that requires too much maintenance.

@github-actions github-actions bot added the 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS label Oct 26, 2021
@happysalada
Copy link
Contributor Author

happysalada commented Oct 26, 2021

I implemented changes in a separate commit, but it's just for people involved in the PR to track changes more easily.
I'll squash all the commits when this is ready to merge.

I've moved the systemd chapter under nixos/doc/manual/development and put the systemd chapter right after the module chapter.

I've only populated 2 chapters and a half. The style is a little clumsy, I've tried to add the content I want to describe. Feel free to suggest better sentences, or just signal if you feel a section deserves more attention.

I tried to add examples to each section, but all the example basically refer to the one module that I wrote. I'm sure there are better examples, feel free to suggest any if a better modules comes to mind.

I've left the original section on systemd in the manual and added a little it. Basically the original section was describing how to do service management, so on the point of view of the cli. I added the logs section. I'm hoping that this section is more about systemd services options and how to use them.

@ofborg ofborg bot added 10.rebuild-linux: 1-10 and removed 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux labels Oct 27, 2021
To pass secret data to a systemd service, systemd has the `LoadCredential` mechanism.
By passing a file path to systemd, it will make sure that the file is available to the process under a specific path.
The load credential attribute takes an id a colon and a file path
let's have a look at an [example](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/web-apps/lemmy.nix#L182)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a permalink like this https://github.com/NixOS/nixpkgs/blob/3b0bff383f8e894b1ee7a30b62c8b727a68511df/nixos/modules/services/web-apps/lemmy.nix#L182 is better?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about those, I thought it would be better to just include the code-snippet rather than a link.
My next iteration will just have the relevant snippets just copied.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's at lest do a permalink for now so that the line doesn't get lost and we can do snippets later.


Note that this requires your application to read secrets from a file.

If your service can only read secrets through environment variables, the best alternative is to ask the end user to pass an `environmentFile` containing the secrets.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to document how that's done or link to an example

To pass secret data to a systemd service, systemd has the `LoadCredential` mechanism.
By passing a file path to systemd, it will make sure that the file is available to the process under a specific path.
The load credential attribute takes an id a colon and a file path
let's have a look at an [example](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/web-apps/lemmy.nix#L182)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's at lest do a permalink for now so that the line doesn't get lost and we can do snippets later.

### Secret management {#sec-systemd-secrets}

To pass secret data to a systemd service, systemd has the `LoadCredential` mechanism.
By passing a file path to systemd, it will make sure that the file is available to the process under a specific path.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is probably a good idea to explicitly highlight that any path in the Nix store is world-readable so in order for this secret to be secret it needs to be managed outside of NixOS.

@happysalada
Copy link
Contributor Author

Thanks a lot for commenting to both of you!

I have this task for the holidays to finish this PR.


Most databases have 2 modes of connection, over TCP or over Unix socket. Connecting over a unix socket can provide 2 advantages
- 30% performance improvement as packets don't need to be encoder over TCP
- The default authentication mode postgres on unix sockets is just with the user name. This will remove the need to manage the password secret
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- The default authentication mode postgres on unix sockets is just with the user name. This will remove the need to manage the password secret
- The default authentication mode postgres on unix sockets relies on the client's uid provided by the kernel, rather than a password that you need to be care for.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though it being based on uid, this may be tricky across uid namespaces and therefore containers. I vaguely recall a nixpkgs issue or stackoverflow question about this, but I couldn't find it.

Systemd is a building block of most nixos modules.

From the [project's webpage](https://systemd.io/)
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't code but a quote. You should probably use > syntax instead.

@colemickens
Copy link
Member

A react emoji isn't enough -- thank you for this. this will be invaluable to have.

Copy link
Member

@evils evils left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some style points that caused me to hesitate while reading

it may be a bit early to start nitpicking
please ignore all of this if it'll take away time from substantive work
(especially the spell checking, which is non-exhaustive)
i'd love to do a more in-depth pass when this is closer to completion (or after it's merged)

thanks for doing this, i look forward to having it in the manual

[Systemd official website](https://systemd.io/)
[Wikipedia](https://en.wikipedia.org/wiki/Systemd)
[Archlinux Wiki](https://wiki.archlinux.org/title/Systemd)
[Systemd announcement from Lennart Poettering (one of the 2 original developpers of systemd)](http://0pointer.de/blog/projects/systemd.html)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[Systemd announcement from Lennart Poettering (one of the 2 original developpers of systemd)](http://0pointer.de/blog/projects/systemd.html)
[Systemd announcement from Lennart Poettering (one of the 2 original developers of systemd)](http://0pointer.de/blog/projects/systemd.html)

}
```

A file can be passed as well with `environmentFile`. If both are passed, `environmentFile` takes precedence over `environment`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A file can be passed as well with `environmentFile`. If both are passed, `environmentFile` takes precedence over `environment`
A file can be passed in with `environmentFile`. If both are used, `environmentFile` takes precedence over `environment`


To pass secret data to a systemd service, systemd has the `LoadCredential` mechanism.
By passing a file path to systemd, it will make sure that the file is available to the process under a specific path.
The load credential attribute takes an id a colon and a file path
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The load credential attribute takes an id a colon and a file path
The load credential attribute takes an id, a colon and a file path

```
LoadCredential = "jwt_secret:${cfg.jwtSecretPath}";
```
Inside your application, the jwt secret will be available under `$CREDENTIALS_DIRECTORY/jwt_secret` environment variable.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Inside your application, the jwt secret will be available under `$CREDENTIALS_DIRECTORY/jwt_secret` environment variable.
Inside your application, the jwt secret will be available under the `$CREDENTIALS_DIRECTORY/jwt_secret` environment variable.


Note that this requires your application to read secrets from a file.

If your service can only read secrets through environment variables, the best alternative is to ask the end user to pass an `environmentFile` containing the secrets.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If your service can only read secrets through environment variables, the best alternative is to ask the end user to pass an `environmentFile` containing the secrets.
If your service can only read secrets through environment variables, the best alternative is to ask the end user to pass in an `environmentFile` containing the secrets.

PartOf:
- use `partOf = [ "B" ];`, if service A needs to re-started when service B is.

Note that `wants,requires,bindsTo` are orthogonal to `after`. The most common occurence in nixpkgs is `requires` and `after`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"and" makes it sound (to me) like the 2 most common occurrences are being listed

Suggested change
Note that `wants,requires,bindsTo` are orthogonal to `after`. The most common occurence in nixpkgs is `requires` and `after`.
Note that `wants,requires,bindsTo` are orthogonal to `after`. The most common occurrence in nixpkgs is `requires` with `after`.

### Examples {#sec-systemd-handling-dependencies-examples}

- Web-app dependency on a database. If the web-app cannot start without the database, use `requires` and `after`. If you would rather have it operate even without a database use `wants` and `after`. [example in nixpkgs](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/web-apps/lemmy.nix#L169)
- Database migration and setup script for a web-app. It is common to make a service for database setup and migration. This service should be `partOf` the webapp service as everytime the webapp is restarted, this service should be restarted as well.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Database migration and setup script for a web-app. It is common to make a service for database setup and migration. This service should be `partOf` the webapp service as everytime the webapp is restarted, this service should be restarted as well.
- Database migration and setup script for a web-app. It is common to make a service for database setup and migration. This service should be `partOf` the web-app service as every time the web-app restarts, this service should be restarted as well.

- Web-app dependency on a database. If the web-app cannot start without the database, use `requires` and `after`. If you would rather have it operate even without a database use `wants` and `after`. [example in nixpkgs](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/web-apps/lemmy.nix#L169)
- Database migration and setup script for a web-app. It is common to make a service for database setup and migration. This service should be `partOf` the webapp service as everytime the webapp is restarted, this service should be restarted as well.
[example in nixpkgs](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/web-apps/lemmy.nix#L214)
- A web-app has two separate services, a UI and a server. The ui `requires` `after` the server. [example in nixpkgs](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/web-apps/lemmy.nix#L205)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is hard to parse as a sentence, also hard to keep it short :)

Suggested change
- A web-app has two separate services, a UI and a server. The ui `requires` `after` the server. [example in nixpkgs](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/web-apps/lemmy.nix#L205)
- A web-app with two separate services, a UI and a server. The UI `requires` the server and starts `after` it. [example in nixpkgs](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/web-apps/lemmy.nix#L205)

- 30% performance improvement as packets don't need to be encoder over TCP
- The default authentication mode postgres on unix sockets is just with the user name. This will remove the need to manage the password secret

Therefore the default for database connection for services is recommended to be with a unix socket. For postgres for example, the `host` needs to start with a `/`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Therefore the default for database connection for services is recommended to be with a unix socket. For postgres for example, the `host` needs to start with a `/`.
Therefore the recommended default for database connections for services is a unix socket. With postgres for example, `host` needs to start with a `/`.

The initialisation service should be run by the database superuser so as not to require sudo.
Typically it will involve creating the database and the user.
There will be a step to see if the database is already created.
That check is best implemented by going throug the created tables and exiting if the table already exists.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
That check is best implemented by going throug the created tables and exiting if the table already exists.
That check is best implemented by going through the created tables and exiting if the table already exists.

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 19, 2022
@con-f-use
Copy link
Contributor

Any reason this hasn't been merged?

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Apr 3, 2023
@happysalada
Copy link
Contributor Author

This was too early in the process its just incomplete. If anyone ever wants to take it up, they are more than welcome to take any part they want

@wegank wegank added the 12.approvals: 1 This PR was reviewed and approved by one reputable person label Mar 9, 2024
@wegank wegank added 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 2.status: merge conflict This PR has merge conflicts with the target branch labels Mar 19, 2024
@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Mar 20, 2024
@wegank wegank added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jul 4, 2024
@ibizaman
Copy link

ibizaman commented Jul 31, 2024

FYI I'm working on #328472 and will pick this PR up afterwards if no one beats me to it, at least for the credentials part.

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jul 31, 2024
@wegank wegank added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jan 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.status: merge conflict This PR has merge conflicts with the target branch 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 6.topic: systemd 8.has: documentation This PR adds or changes documentation 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10 12.approvals: 1 This PR was reviewed and approved by one reputable person
Projects
None yet
Development

Successfully merging this pull request may close these issues.