A minimal, configurable, secure container image for running chrony NTP server/client, optimized for systems without a Real-Time Clock (RTC) such as Raspberry Pi.
ghcr.io/chris-short/chrony:latest
This container has been tested and verified on:
- macOS (Docker Desktop / Podman)
- Raspberry Pi 5 (arm64, no RTC)
- x86_64 Linux
- RTC-free operation: Optimized configuration for devices without hardware clocks
- Fast sync on boot: Uses
makestepto quickly correct time after restart - Drift tracking: Maintains accuracy across reboots via persistent drift file
- Host networking: Binds directly to host interfaces for reliable IPv4/IPv6 NTP service
- Custom NTP servers: Includes local and public time sources for redundancy
docker compose up -d# Build the image
docker build -t chrony:latest .
# Run with minimal configuration
docker run -d --name chrony \
--network host \
--cap-add SYS_TIME \
chrony:latest
# Run with persistent drift/logs
docker run -d --name chrony \
--network host \
--cap-add SYS_TIME \
-v chrony-data:/var/lib/chrony \
-v chrony-logs:/var/log/chrony \
chrony:latest# Generate systemd service
podman generate systemd --new --name chrony > ~/.config/systemd/user/chrony.service
systemctl --user enable --now chronyCreate /etc/systemd/system/chrony-container.service:
[Unit]
Description=Chrony NTP Container
After=docker.service
Requires=docker.service
[Service]
Restart=always
ExecStartPre=-/usr/bin/docker rm -f chrony
ExecStart=/usr/bin/docker run --rm --name chrony \
--network host \
--cap-drop ALL \
--cap-add SYS_TIME \
-v chrony-data:/var/lib/chrony \
ghcr.io/chris-short/chrony:latest
ExecStop=/usr/bin/docker stop chrony
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl daemon-reload
sudo systemctl enable --now chrony-containerEdit chrony.conf to add your preferred NTP servers:
server your.ntp.server iburst
Uncomment in chrony.conf:
allow 10.0.5.0/24
# Check sync status
docker exec chrony chronyc tracking
# View sources
docker exec chrony chronyc sources -v
# Check server stats
docker exec chrony chronyc serverstats- ~5MB image: Alpine Linux with only
chronypackage installed - Non-root runtime: Drops to
chronyuser immediately after binding port 123 - Weekly rebuilds: Automated builds every Sunday pull the latest Alpine base image with security patches
- Multi-architecture: Native builds for
linux/amd64andlinux/arm64
| Setting | Purpose |
|---|---|
cap_drop: ALL |
Drop all Linux capabilities |
cap_add: SYS_TIME |
Add back only what chrony needs |
read_only: true |
Immutable root filesystem |
no-new-privileges: true |
Prevent privilege escalation |
Report security vulnerabilities to: security@chrisshort.net
| Tag | Description |
|---|---|
latest |
Most recent build from main branch |
YYYYMMDD |
Date-stamped builds |
<sha> |
Git commit SHA |
MIT