Architectures officially supported by this Docker container:
This container runs chrony on Alpine Linux. More about chrony can be found at:
Pull and run -- it's this simple.
# pull from docker hub
$> docker pull cturra/ntp
# run ntp
$> docker run --name=ntp \
--restart=always \
--detach \
--publish=123:123/udp \
--cap-add=SYS_TIME \
cturra/ntp
# OR run ntp with higher security (default behaviour of run.sh and docker-compose).
$> docker run --name=ntp \
--restart=always \
--detach \
--publish=123:123/udp \
--cap-add=SYS_TIME \
--read-only \
--tmpfs=/etc/chrony:rw,mode=1750 \
--tmpfs=/run/chrony:rw,mode=1750 \
--tmpfs=/var/lib/chrony:rw,mode=1750 \
cturra/ntp
Using the docker-compose.yml file included in this git repo, you can build the container yourself (should you choose to).
*Note: this docker-compose files uses the 3.4
compose format, which requires Docker Engine release 17.09.0+
# pull from docker hub
$> docker pull cturra/ntp
# build ntp
$> docker-compose build ntp
# run ntp
$> docker-compose up -d ntp
# (optional) check the ntp logs
$> docker-compose logs ntp
Using the vars file in this git repo, you can update any of the variables to reflect your environment. Once updated, simply execute the build then run scripts.
# build ntp
$> ./build.sh
# run ntp
$> ./run.sh
By default, this container uses CloudFlare's time server (time.cloudflare.com). If you'd
like to use one or more different NTP server(s), you can pass this container an NTP_SERVERS
environment variable. This can be done by updating the vars, docker-compose.yml
files or manually passing --env=NTP_SERVERS="..."
to docker run
.
Below are some examples of how to configure common NTP Servers.
Do note, to configure more than one server, you must use a comma delimited list WITHOUT spaces.
# (default) cloudflare
NTP_SERVERS="time.cloudflare.com"
# google
NTP_SERVERS="time1.google.com,time2.google.com,time3.google.com,time4.google.com"
# alibaba
NTP_SERVERS="ntp1.aliyun.com,ntp2.aliyun.com,ntp3.aliyun.com,ntp4.aliyun.com"
From any machine that has ntpdate
you can query your new NTP container with the follow
command:
$> ntpdate -q <DOCKER_HOST_IP>
Here is a sample output from my environment:
$> ntpdate -q 10.13.13.9
server 10.13.1.109, stratum 4, offset 0.000642, delay 0.02805
14 Mar 19:21:29 ntpdate[26834]: adjust time server 10.13.13.109 offset 0.000642 sec
If you see a message, like the following, it's likely the clock is not yet synchronized. You should see this go away if you wait a bit longer and query again.
$> ntpdate -q 10.13.13.9
server 10.13.13.9, stratum 16, offset 0.005689, delay 0.02837
11 Dec 09:47:53 ntpdate[26030]: no server suitable for synchronization found
To see details on the ntp status of your container, you can check with the command below on your docker host:
$> docker exec ntp chronyc tracking
Reference ID : D8EF2300 (time1.google.com)
Stratum : 2
Ref time (UTC) : Sun Mar 15 04:33:30 2020
System time : 0.000054161 seconds slow of NTP time
Last offset : -0.000015060 seconds
RMS offset : 0.000206534 seconds
Frequency : 5.626 ppm fast
Residual freq : -0.001 ppm
Skew : 0.118 ppm
Root delay : 0.022015510 seconds
Root dispersion : 0.001476757 seconds
Update interval : 1025.2 seconds
Leap status : Normal
Here is how you can see a peer list to verify the state of each ntp source configured:
$> docker exec ntp chronyc sources
210 Number of sources = 2
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^+ time.cloudflare.com 3 10 377 404 -623us[ -623us] +/- 24ms
^* time1.google.com 1 10 377 1023 +259us[ +244us] +/- 11ms
Finally, if you'd like to see statistics about the collected measurements of each ntp source configured:
$> docker exec ntp chronyc sourcestats
210 Number of sources = 2
Name/IP Address NP NR Span Frequency Freq Skew Offset Std Dev
==============================================================================
time.cloudflare.com 35 18 139m +0.014 0.141 -662us 530us
time1.google.com 33 13 128m -0.007 0.138 +318us 460us