1 # pkgs.portableService {#sec-pkgs-portableService}
3 `pkgs.portableService` is a function to create [Portable Services](https://systemd.io/PORTABLE_SERVICES/) in a read-only, immutable, `squashfs` raw disk image.
4 This lets you use Nix to build images which can be run on many recent Linux distributions.
7 Portable services are supported starting with systemd 239 (released on 2018-06-22).
10 The generated image will contain the file system structure as required by the Portable Services specification, along with the packages given to `portableService` and all of their dependencies.
11 When generated, the image will exist in the Nix store with the `.raw` file extension, as required by the specification.
12 See [](#ex-portableService-hello) to understand how to use the output of `portableService`.
14 ## Inputs {#ssec-pkgs-portableService-inputs}
16 `portableService` expects one argument with the following attributes:
20 : The name of the portable service.
21 The generated image will be named according to the template `$pname_$version.raw`, which is supported by the Portable Services specification.
25 : The version of the portable service.
26 The generated image will be named according to the template `$pname_$version.raw`, which is supported by the Portable Services specification.
28 `units` (List of Attribute Set)
30 : A list of derivations for systemd unit files.
31 Each derivation must produce a single file, and must have a name that starts with the value of `pname` and ends with the suffix of the unit type (e.g. ".service", ".socket", ".timer", and so on).
32 See [](#ex-portableService-hello) to better understand this naming constraint.
34 `description` (String or Null; _optional_)
36 : If specified, the value is added as `PORTABLE_PRETTY_NAME` to the `/etc/os-release` file in the generated image.
37 This could be used to provide more information to anyone inspecting the image.
39 _Default value:_ `null`.
41 `homepage` (String or Null; _optional_)
43 : If specified, the value is added as `HOME_URL` to the `/etc/os-release` file in the generated image.
44 This could be used to provide more information to anyone inspecting the image.
46 _Default value:_ `null`.
48 `symlinks` (List of Attribute Set; _optional_)
50 : A list of attribute sets in the format `{object, symlink}`.
51 For each item in the list, `portableService` will create a symlink in the path specified by `symlink` (relative to the root of the image) that points to `object`.
53 All packages that `object` depends on and their dependencies are automatically copied into the image.
55 This can be used to create symlinks for applications that assume some files to exist globally (`/etc/ssl` or `/bin/bash`, for example).
56 See [](#ex-portableService-symlinks) to understand how to do that.
58 _Default value:_ `[]`.
60 `contents` (List of Attribute Set; _optional_)
62 : A list of additional derivations to be included as-is in the image.
63 These derivations will be included directly in a `/nix/store` directory inside the image.
65 _Default value:_ `[]`.
67 `squashfsTools` (Attribute Set; _optional_)
69 : Allows you to override the package that provides {manpage}`mksquashfs(1)`, which is used internally by `portableService`.
71 _Default value:_ `pkgs.squashfsTools`.
73 `squash-compression` (String; _optional_)
75 : Passed as the compression option to {manpage}`mksquashfs(1)`, which is used internally by `portableService`.
77 _Default value:_ `"xz -Xdict-size 100%"`.
79 `squash-block-size` (String; _optional_)
81 : Passed as the block size option to {manpage}`mksquashfs(1)`, which is used internally by `portableService`.
83 _Default value:_ `"1M"`.
85 ## Examples {#ssec-pkgs-portableService-examples}
87 []{#ex-pkgs-portableService}
88 :::{.example #ex-portableService-hello}
89 # Building a Portable Service image
91 The following example builds a Portable Service image with the `hello` package, along with a service unit that runs it.
94 { lib, writeText, portableService, hello }:
96 hello-service = writeText "hello.service" ''
98 Description=Hello world service
102 ExecStart=${lib.getExe hello}
107 inherit (hello) version;
108 units = [ hello-service ];
112 After building the package, the generated image can be loaded into a system through {manpage}`portablectl(1)`:
116 (some output removed for clarity)
117 /nix/store/8c20z1vh7z8w8dwagl8w87b45dn5k6iq-hello-img-2.12.1
119 $ portablectl attach /nix/store/8c20z1vh7z8w8dwagl8w87b45dn5k6iq-hello-img-2.12.1/hello_2.12.1.raw
120 Created directory /etc/systemd/system.attached.
121 Created directory /etc/systemd/system.attached/hello.service.d.
122 Written /etc/systemd/system.attached/hello.service.d/20-portable.conf.
123 Created symlink /etc/systemd/system.attached/hello.service.d/10-profile.conf → /usr/lib/systemd/portable/profile/default/service.conf.
124 Copied /etc/systemd/system.attached/hello.service.
125 Created symlink /etc/portables/hello_2.12.1.raw → /nix/store/8c20z1vh7z8w8dwagl8w87b45dn5k6iq-hello-img-2.12.1/hello_2.12.1.raw.
127 $ systemctl start hello
128 $ journalctl -u hello
129 Feb 28 22:39:16 hostname systemd[1]: Starting Hello world service...
130 Feb 28 22:39:16 hostname hello[102887]: Hello, world!
131 Feb 28 22:39:16 hostname systemd[1]: hello.service: Deactivated successfully.
132 Feb 28 22:39:16 hostname systemd[1]: Finished Hello world service.
134 $ portablectl detach hello_2.12.1
135 Removed /etc/systemd/system.attached/hello.service.
136 Removed /etc/systemd/system.attached/hello.service.d/10-profile.conf.
137 Removed /etc/systemd/system.attached/hello.service.d/20-portable.conf.
138 Removed /etc/systemd/system.attached/hello.service.d.
139 Removed /etc/portables/hello_2.12.1.raw.
140 Removed /etc/systemd/system.attached.
144 :::{.example #ex-portableService-symlinks}
145 # Specifying symlinks when building a Portable Service image
147 Some services may expect files or directories to be available globally.
148 An example is a service which expects all trusted SSL certificates to exist in a specific location by default.
150 To make things available globally, you must specify the `symlinks` attribute when using `portableService`.
151 The following package builds on the package from [](#ex-portableService-hello) to make `/etc/ssl` available globally (this is only for illustrative purposes, because `hello` doesn't use `/etc/ssl`).
154 { lib, writeText, portableService, hello, cacert }:
156 hello-service = writeText "hello.service" ''
158 Description=Hello world service
162 ExecStart=${lib.getExe hello}
167 inherit (hello) version;
168 units = [ hello-service ];
170 { object = "${cacert}/etc/ssl"; symlink = "/etc/ssl"; }