systemd-lsp 0.1.4

Language Server Protocol implementation for systemd unit files
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
# [Container] Section

The `[Container]` section describes the container that will be run as a systemd service using Podman Quadlet. Quadlet is a feature of Podman that allows you to manage containers declaratively through systemd unit files. Container units use the `.container` file extension and are automatically converted into systemd service units.

*Based on [podman-systemd.unit(5)](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html) official documentation.*

## Required Directives

### Image=
The container image to run. It is recommended to use a fully qualified image name rather than a short name, both for performance and robustness reasons.

**Format:** `registry.com/repository/image:tag` or image digest

**Example:** `Image=docker.io/nginx:latest`

**Note:** Supports references to `.image` or `.build` Quadlet files

## Basic Configuration

### ContainerName=
Specifies a custom name for the Podman container instead of using the default.

**Default:** `systemd-%N` (service name with `systemd-` prefix)

### Exec=
Additional arguments for the container; this has exactly the same effect as passing more arguments after a `podman run <image> <arguments>` invocation.

**Format:** Command line arguments matching systemd command syntax

### WorkingDir=
Overrides the default working directory for command execution inside the container.

**Default:** `/` (root directory, or the image's WORKDIR if set)

### Entrypoint=
Overrides the default ENTRYPOINT instruction from the container image.

**Format:** Command string or JSON string for multi-option commands

### User=
Specifies the numeric user ID (UID) or username for processes executing in the container.

**Note:** Can be combined with `Group=` to create `--user USER:GROUP` argument

### Group=
Sets the numeric GID for processes running within the container.

**Note:** Must be paired with `User=` to create `--user USER:GROUP` argument

### HostName=
Configures the hostname accessible within the container environment.

**Example:** `HostName=example.com`

## Networking

### Network=
Defines networking configuration including network mode or custom network attachment.

**Format:** `host`, `none`, network name, or `.network` Quadlet reference

**Default:** Bridge network

**Multiple:** Yes (can specify multiple networks)

**Example:**
- `Network=host` - Use host networking
- `Network=mynetwork.network` - Use Quadlet network

### PublishPort=
Exposes container ports to the host with optional host binding and IP specification.

**Format:**
- `containerPort` (e.g., `80`)
- `hostPort:containerPort` (e.g., `8080:80`)
- `ip:hostPort:containerPort` (e.g., `127.0.0.1:8080:80`)
- `ip::containerPort` (dynamic host port)

**Multiple:** Yes

**Example:** `PublishPort=8080:80`

### ExposeHostPort=
Exposes host ports or port ranges to the container.

**Format:** Port number or range (e.g., `50-59`)

**Multiple:** Yes

### IP=
Assigns a static IPv4 address to the container.

**Example:** `IP=10.88.64.128`

### IP6=
Assigns a static IPv6 address to the container.

**Example:** `IP6=fd46:db93:aa76:ac37::10`

### NetworkAlias=
Registers network-scoped DNS aliases grouping containers for service discovery.

**Multiple:** Yes

### DNS=
Assigns network-scoped DNS resolver or nameserver for the container.

**Format:** IP address

**Multiple:** Yes

**Example:** `DNS=192.168.55.1`

### DNSSearch=
Configures DNS search domains for hostname resolution within the container.

**Format:** Domain name or `.` to remove search domain

**Multiple:** Yes

### DNSOption=
Sets custom DNS resolver options and behaviors.

**Example:** `DNSOption=ndots:1`

**Multiple:** Yes

### AddHost=
Establishes hostname-to-IP address mappings within the container's /etc/hosts file.

**Format:** `hostname:ip`

**Multiple:** Yes

**Example:** `AddHost=db.local:192.168.1.10`

## Storage and Volumes

### Volume=
Mounts host directories or named volumes into the container filesystem.

**Format:** `[[SOURCE-VOLUME|HOST-DIR:]CONTAINER-DIR[:OPTIONS]]`

**Options:**
- `z` - Shared SELinux label
- `Z` - Private SELinux label
- `ro` - Read-only
- `rw` - Read-write

**Multiple:** Yes

**Example:**
- `Volume=/srv/data:/usr/share/nginx/html:Z`
- `Volume=myvolume.volume:/data`

### Mount=
Attaches filesystem mounts with advanced configuration options.

**Format:** `type=TYPE,TYPE-SPECIFIC-OPTION[,...]`

**Multiple:** Yes

**Note:** Supports `.volume` and `.image` file references

### Tmpfs=
Mounts temporary filesystems within the container at specified paths.

**Format:** `CONTAINER-DIR[:OPTIONS]`

**Multiple:** Yes

**Example:** `Tmpfs=/tmp:size=64M`

### Rootfs=
Specifies a directory containing container filesystem content instead of using an image.

**Note:** Conflicts with `Image` directive; supports overlay mount syntax

### ReadOnly=
Mounts the container's root filesystem in read-only mode.

**Format:** `true` or `false`

**Default:** `false`

### ReadOnlyTmpfs=
If ReadOnly is set to `true`, mount a read-write tmpfs on /dev, /dev/shm, /run, /tmp, and /var/tmp.

**Format:** `true` or `false`

**Default:** `true` (when ReadOnly is enabled)

## Environment Variables

### Environment=
Sets environment variables inside the container using systemd service variable format.

**Format:** `name=value` pairs matching systemd environment syntax

**Multiple:** Yes

**Example:** `Environment=FOO=bar`

### EnvironmentFile=
Loads environment variables from a line-delimited file into the container.

**Format:** Absolute or relative path to environment file

**Multiple:** Yes; order persists when passed to podman run

### EnvironmentHost=
Inherits the host system's environment variables into the container.

**Format:** `true` or `false`

**Default:** `false`

## Security

### AddCapability=
Extends the default Podman capability set by adding specified capabilities to the container.

**Format:** Space-separated list of capability names

**Multiple:** Yes

**Example:** `AddCapability=CAP_DAC_OVERRIDE CAP_IPC_OWNER`

### DropCapability=
Removes capabilities from the default Podman set or removes all with `all`.

**Format:** Space-separated capability names or `all`

**Multiple:** Yes

### NoNewPrivileges=
Prevents container processes from acquiring additional privileges through setuid or capabilities.

**Format:** `true` or `false`

**Default:** `false`

### SeccompProfile=
Applies a seccomp (secure computing) filter profile for syscall restriction.

**Format:** JSON file path or `unconfined` to disable filters

### AppArmor=
Configures the AppArmor confinement profile for the container.

**Format:** Profile name or `unconfined` to disable AppArmor

### SecurityLabelDisable=
Disables SELinux label separation and isolation for the container.

**Format:** `true` or `false`

**Default:** `false` (labels enabled)

### SecurityLabelType=
Sets the SELinux process type context for container operations.

**Example:** `SecurityLabelType=spc_t`

### SecurityLabelLevel=
Assigns SELinux level context for container processes.

**Example:** `SecurityLabelLevel=s0:c1,c2`

### SecurityLabelFileType=
Sets the SELinux file type context for container files.

**Example:** `SecurityLabelFileType=usr_t`

### SecurityLabelNested=
Enables SELinux label functionality within the container for nested isolation.

**Format:** `true` or `false`

**Default:** `false`

### Mask=
Prevents access to specified filesystem paths within the container.

**Format:** Colon-separated paths

**Example:** `Mask=/proc/sys/foo:/proc/sys/bar`

### Unmask=
Removes read-only or masked restrictions from filesystem paths in the container.

**Format:** `ALL` or colon-separated paths

## User Namespaces

### UserNS=
Configures the user namespace mode with optional parameters.

**Format:** `MODE[:OPTIONS,...]`

**Example:** `UserNS=keep-id:uid=200,gid=210`

### UIDMap=
Establishes user ID mapping for the container's user namespace.

**Format:** `container_uid:host_uid:range`

**Multiple:** Yes

**Example:** `UIDMap=0:10000:10`

### GIDMap=
Establishes GID mapping for the container's new user namespace.

**Format:** `container_gid:host_gid:range`

**Multiple:** Yes

**Example:** `GIDMap=0:10000:10`

### SubUIDMap=
Applies user ID mapping using a named entry from /etc/subuid.

### SubGIDMap=
Applies group ID mapping using a named entry from /etc/subgid.

### GroupAdd=
Assigns additional groups to the primary user process or applies special flags.

**Format:** Group name, numeric GID, or `keep-groups` flag

**Multiple:** Yes

## Resource Limits

### Memory=
Restricts the maximum memory allocation for the container process.

**Example:** `Memory=20g`

**Default:** None (unlimited)

### PidsLimit=
Restricts the maximum number of processes within the container.

**Format:** Numeric limit

### ShmSize=
Specifies the allocation size for the /dev/shm shared memory filesystem.

**Example:** `ShmSize=100m`

### Ulimit=
Sets resource limits for processes within the container.

**Format:** `name=softLimit:hardLimit`

**Multiple:** Yes

**Example:** `Ulimit=nofile=1000:10000`

### Sysctl=
Configures namespace-scoped kernel parameters within the container.

**Format:** Space-separated `name=value` pairs

**Multiple:** Yes

**Example:** `Sysctl=net.ipv4.ip_forward=1`

## Health Checks

### HealthCmd=
Defines or modifies the healthcheck command executed within the container.

**Format:** Command string or `none` to disable existing healthchecks

### HealthInterval=
Establishes the time interval between successive healthcheck executions.

**Format:** Duration (e.g., `2m`) or `disable`

### HealthTimeout=
Establishes the maximum duration per healthcheck command before timeout.

**Example:** `HealthTimeout=20s`

### HealthRetries=
Sets the number of failed healthcheck attempts before marking unhealthy.

### HealthStartPeriod=
Allows initialization time before healthchecks begin.

**Example:** `HealthStartPeriod=1m`

### HealthOnFailure=
Specifies corrective action when the container becomes unhealthy.

**Example:** `HealthOnFailure=kill` (works best with systemd restart)

### HealthStartupCmd=
Specifies a startup-phase healthcheck command distinct from regular healthchecks.

### HealthStartupInterval=
Sets the interval for startup-phase healthcheck execution.

**Format:** Duration or `disable`

### HealthStartupRetries=
Limits startup-phase healthcheck attempts before restart.

### HealthStartupSuccess=
Specifies successful startup-phase runs before regular healthchecks activate.

### HealthStartupTimeout=
Sets the maximum duration for startup-phase healthcheck command execution.

### HealthLogDestination=
Specifies where healthcheck logs are stored or logged.

**Format:** `local` (default; overlay storage), `directory` (specified path), or `events_logger`

**Default:** `local`

### HealthMaxLogCount=
Limits the number of healthcheck log entries retained.

**Format:** Numeric value (0 = unlimited)

**Default:** `5` attempts

### HealthMaxLogSize=
Restricts healthcheck log size to a character limit.

**Format:** Numeric character count (0 = unlimited)

**Default:** `500` characters

## Devices and System Access

### AddDevice=
Mounts a device node from the host system into the container environment.

**Format:** `HOST-DEVICE[:CONTAINER-DEVICE][:PERMISSIONS]`

**Permissions:** Combine 'r' (read), 'w' (write), 'm' (mknod)

**Multiple:** Yes

**Note:** Prefix with `-` to add only if device exists

**Example:** `AddDevice=/dev/sda:/dev/xvdc:rwm`

## Logging

### LogDriver=
Selects the logging driver for container output handling.

**Example:** `LogDriver=journald`

### LogOpt=
Provides driver-specific logging configuration options.

**Multiple:** Yes

**Example:** `LogOpt=path=/var/log/mykube.json`

## Lifecycle and Signals

### StopSignal=
Designates the signal sent to halt the container process.

**Default:** `SIGTERM`

**Example:** `StopSignal=SIGINT`

### StopTimeout=
Sets seconds to wait before forcibly terminating the container.

**Note:** Should be lower than systemd timeout to prevent systemd killing podman rm

### ReloadSignal=
Adds an ExecReload directive sending a signal to the container's main process.

**Note:** Mutually exclusive with `ReloadCmd`

**Example:** `ReloadSignal=SIGHUP`

### ReloadCmd=
Adds an ExecReload directive executing a podman exec command for service reloads.

**Note:** Mutually exclusive with `ReloadSignal`

### Notify=
Configures systemd notification handling between container application and systemd.

**Format:**
- `false` (systemd handles) - default
- `true` (container handles)
- `healthy` (waits for healthcheck)

**Default:** `false`

### RunInit=
Provides a minimal init process within the container for signal forwarding.

**Format:** `true` or `false`

**Default:** `false`

## Container Groups (Pods)

### Pod=
Associates the container with a Quadlet `.pod` unit for group management.

**Format:** `<name>.pod` reference to existing pod unit

**Example:** `Pod=myapp.pod`

### StartWithPod=
Controls whether the container starts automatically when its associated pod starts.

**Format:** `true` or `false`

**Default:** `true`

## Image Management

### Pull=
Determines when and how container images are pulled from registries.

**Format:** Policy keyword (e.g., `never`, `always`, `missing`)

### Retry=
Sets the number of image pull retry attempts on HTTP errors.

### RetryDelay=
Establishes the delay interval between image pull retry attempts.

**Example:** `RetryDelay=5s`

### AutoUpdate=
Controls whether the container undergoes automatic updates via podman-auto-update(1).

**Format:**
- `registry` (requires fully-qualified image reference)
- `local` (compares against locally-stored image)

### HttpProxy=
Governs whether proxy environment variables propagate to the container during image operations.

**Format:** `true` or `false`

**Default:** `true`

## Advanced Options

### CgroupsMode=
The cgroups mode of the container created by Quadlet.

**Format:** `split`, `no-conmon`, `enabled`, or other cgroup modes

**Default:** `split` (differs from Podman CLI default of `enabled`)

### ContainersConfModule=
Loads specified containers.conf(5) module configurations.

**Format:** Path to module file

**Multiple:** Yes

### Timezone=
Sets the timezone for processes executing within the container.

**Example:** `Timezone=local`

### Label=
Attaches OCI metadata labels to the container as key-value pairs.

**Format:** List of `key=value` items

**Multiple:** Yes

**Example:** `Label=version=1.0 app=web`

### Annotation=
Assigns OCI annotations to the container as metadata key-value pairs.

**Format:** List of `key=value` items

**Multiple:** Yes

### Secret=
Injects Podman secrets into the container as files or environment variables.

**Format:** `secret[,opt=opt ...]` syntax

**Multiple:** Yes

### GlobalArgs=
Passes arguments directly between `podman` and `run` commands, enabling access to unsupported Podman features.

**Format:** Space-separated arguments, individually escapable for whitespace

**Multiple:** Yes

### PodmanArgs=
Injects arguments directly into the `podman run` command for unsupported features.

**Format:** Space-separated arguments, individually escapable

**Multiple:** Yes

## Example

```ini
[Unit]
Description=Nginx web server
After=network-online.target
Wants=network-online.target

[Container]
Image=docker.io/nginx:latest
ContainerName=nginx-server
PublishPort=8080:80
Volume=/srv/www:/usr/share/nginx/html:Z
Environment=NGINX_PORT=80
AutoUpdate=registry
HealthCmd=curl -f http://localhost/ || exit 1
HealthInterval=30s

[Service]
Restart=always
TimeoutStartSec=900

[Install]
WantedBy=multi-user.target
```

## See Also

- [podman-systemd.unit(5)]https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html
- [podman-run(1)]https://docs.podman.io/en/latest/markdown/podman-run.1.html
- systemd.unit(5)
- systemd.service(5)