# Quadlet File Standards
## Rule
All container services MUST be managed through Quadlet files with health checks, restart policies, and appropriate file placement.
## Format
```ini
# service-name.container
[Unit]
Description=<service description>
After=network-online.target
[Container]
Image=<registry>/<image>:<pinned-tag>
HealthCmd=<health check command>
HealthInterval=30s
Label=io.containers.autoupdate=registry
[Service]
Restart=always
TimeoutStartSec=90
[Install]
WantedBy=default.target
```
## Requirements
1. **File placement** — rootless: `~/.config/containers/systemd/`, rootful: `/etc/containers/systemd/`
2. **Image pinning** — ALWAYS use pinned tags, never :latest
3. **Health checks** — REQUIRED for all long-running services
4. **Restart policy** — set `Restart=always` for production services
5. **Auto-update labels** — add for images that should track registry updates
6. **Description** — meaningful [Unit] Description for `systemctl status`
7. **Timeouts** — set TimeoutStartSec appropriate to the service
## Examples
### Good
```ini
[Unit]
Description=Application API Server
After=network-online.target
[Container]
Image=ghcr.io/myorg/api:2.1.0
PublishPort=8080:8080
Volume=api-data.volume:/data
Environment=NODE_ENV=production
Secret=api-keys,type=mount
HealthCmd=curl -sf http://localhost:8080/health || exit 1
HealthInterval=30s
HealthStartPeriod=10s
Label=io.containers.autoupdate=registry
[Service]
Restart=always
TimeoutStartSec=90
TimeoutStopSec=30
[Install]
WantedBy=default.target
```
### Bad
```ini
# Missing: description, health check, restart policy, pinned image
[Container]
Image=myapp:latest
PublishPort=8080:8080
Environment=DB_PASSWORD=secret123
```
## Enforcement
Lint Quadlet files in CI before deployment. Check for required fields: Image with pinned tag, HealthCmd, Restart, Description.