Home / Alt manpages / dockerd(8)

  • dockerd(8)
  • Admin command
  • linux

Configure and Validate the Docker Engine Daemon with dockerd

You will configure a small, reviewable Docker daemon policy in daemon.json, validate it without starting Docker, and understand which changes need a restart. The examples match Docker Engine 29.8.1 from the installed docker-ce package. Allow about 20 minutes, plus a little longer if you need to check an existing service unit.

You need a shell, Docker Engine installed, and permission to read the daemon configuration. Editing the normal system configuration and restarting Docker require elevated privileges. Validation of a separate file does not.

1. Check the installed daemon

Start with read-only checks. They confirm which executable and package you are about to configure:

$ command -v dockerd
/usr/bin/dockerd
$ dockerd --version
Docker version 29.8.1, build 464cd50
$ dpkg-query -W -f='${Package} ${Version}\n' docker-ce
docker-ce 5:29.8.1-1~ubuntu.24.04~noble

The installed manual describes Linux defaults including /etc/docker/daemon.json for configuration, /var/lib/docker for persistent data, /var/run/docker.sock for the default Unix socket, json-file for container logs, and info for the daemon log level. A rootless installation uses a different configuration location, so check how your service is started before editing a file.

2. Inspect the current configuration and service

Do not overwrite an existing configuration. These commands are ordinary read-only checks:

$ sudo test -f /etc/docker/daemon.json && sudo sed -n '1,200p' /etc/docker/daemon.json
$ systemctl cat docker.service
$ systemctl is-active docker.service

An absent daemon.json is normal. The service unit may pass flags such as --host to dockerd. Docker rejects a setting duplicated between flags and the JSON file, even when the values are identical. Check the unit before adding keys such as hosts, log-driver or debug.

Checkpoint

Record the file path and any daemon flags shown by systemctl cat. If the service is not called docker.service on your system, use the unit name supplied by your package or administrator.

3. Build a minimal configuration

For a new system, make a copy of the current file if it exists, then create the directory and file. This is a configuration change, so use elevated privileges deliberately:

$ sudo install -d -m 0755 /etc/docker
$ if sudo test -f /etc/docker/daemon.json; then
    sudo cp --preserve=mode,ownership,timestamps /etc/docker/daemon.json /etc/docker/daemon.json.bak
  fi
$ sudoedit /etc/docker/daemon.json

For the editor contents, start with settings that are easy to reason about:

{
  "log-level": "info",
  "log-driver": "json-file",
  "max-concurrent-downloads": 3,
  "max-concurrent-uploads": 5,
  "default-stop-timeout": 10
}

These are the values documented by the installed manual for a Linux daemon, so this file makes the intended baseline visible rather than changing it. Docker configuration keys use the flag names without the leading hyphens. Options that accept several values use the plural form, such as labels for the label flag.

Do not add a remote TCP listener merely to make a client connect. The manual's --tls and --tlsverify settings control transport security, but an exposed daemon socket is a high-impact administrative interface. If you need remote access, design the address, certificates, firewall policy and service startup together.

4. Validate without starting the daemon

Use a separate file while iterating. It avoids touching the live configuration and does not start Docker:

$ install -m 0600 /dev/null /tmp/dockerd-check.json
$ editor /tmp/dockerd-check.json
$ dockerd --validate --config-file=/tmp/dockerd-check.json
configuration OK
$ printf 'validation exit status: %s\n' "$?"
validation exit status: 0

--validate checks the daemon configuration and exits. A non-zero status means the file is not ready to use. Typical causes are malformed JSON, an unknown directive, or a value with the wrong type. Keep the test file private if it contains proxy URLs, certificate paths or other sensitive operational details.

For example, this deliberately invalid file should fail:

$ printf '%s\n' '{"unknown-option": true}' > /tmp/dockerd-invalid.json
$ dockerd --validate --config-file=/tmp/dockerd-invalid.json
unable to configure the Docker daemon with file /tmp/dockerd-invalid.json: the following directives don't match any configuration option: unknown-option
$ printf 'validation exit status: %s\n' "$?"
validation exit status: 1

Remove temporary files after checking them, but do not remove the backup of a working production configuration until the replacement has been tested:

$ rm -- /tmp/dockerd-check.json /tmp/dockerd-invalid.json

5. Apply the configuration through the service manager

Once the live file has passed validation, restart the service so the daemon reads it. This disrupts Docker API access and may affect containers, so choose a maintenance window:

$ sudo systemctl restart docker.service
$ sudo systemctl is-active docker.service
active
$ sudo docker info --format '{{.ServerVersion}}'
29.8.1

A manually launched dockerd runs in the foreground and logs to the terminal. It is useful for troubleshooting, but do not start a second daemon against the same data directory or socket while the service is active. Stop a manually started daemon with Ctrl+C.

If the restart fails, inspect the service log before changing more settings:

$ sudo systemctl status docker.service --no-pager
$ sudo journalctl -u docker.service -n 80 --no-pager

To recover the previous file, restore the backup and restart again:

$ sudo cp --preserve=mode,ownership,timestamps /etc/docker/daemon.json.bak /etc/docker/daemon.json
$ sudo dockerd --validate --config-file=/etc/docker/daemon.json
$ sudo systemctl restart docker.service

6. Check the result and avoid misleading tests

Confirm the daemon responds and inspect the settings that matter to your change:

$ sudo docker info
$ sudo docker info --format 'Server={{.ServerVersion}} Logging={{.LoggingDriver}}'

The docker info output is a daemon-side check. It does not prove that every container inherited a new default: existing containers retain their own configuration, and settings such as the default stop timeout apply when no container-specific value is supplied. A logging-driver change is also a default for newly created containers, not a conversion of old log files.

Networking settings deserve extra care. The installed manual says --iptables and IP masquerading are enabled by default, while --ipv6 is disabled by default. Changing bridge addresses, forwarding, firewall integration or the storage driver can affect existing workloads. Take a configuration backup and test those changes on a disposable host first.

Done means

  • The installed dockerd and docker-ce versions are known.
  • The service unit and existing configuration were checked before adding keys.
  • The JSON passed dockerd --validate with exit status 0.
  • No unprotected remote listener was added as a shortcut.
  • The service is active and docker info confirms the daemon responds.
  • A restorable backup remains until the new configuration has behaved correctly.