Chapter 02Lesson 01~95 minutes

Installing Docker Engine and Desktop, CLI Basics, Daemon Connectivity, Contexts, and Environment Setup: Concepts, Architecture, and Mental Model

Install Docker correctly by modeling the full environment first: supported host or Desktop platform, trusted distribution source, Docker client and Engine boundary, selected context and endpoint, persistent daemon state, and the privilege model used to administer it.

Installation modelEngine vs DesktopContextsData rootPrivileges

Learning objectives

  • Explain why a working Docker CLI does not prove that a local Docker daemon exists or that the intended daemon is selected.
  • Distinguish native Linux Docker Engine from Docker Desktop VM-backed execution and from CLI-only remote-client setups.
  • Model package source, client/server/API identity, context/endpoint, daemon service, data root, storage/image store, and access mode as separate state.
  • Explain the security difference between explicit sudo, docker-group socket access, rootless Docker, and Desktop-managed user access.
  • Perform a read-only platform/install preflight before changing packages or daemon configuration.
Chapter 02 technical baseline — verified 2026-09-20. Docker Engine 29.8.1 and Docker Desktop 4.91.0 are current releases at this verification date. Current upstream Buildx, BuildKit, and Compose releases are 0.37.1, 0.33.0, and 5.5.1 respectively. Do not infer those exact bundled versions from the product name: every lab records the actual client/server/API/context/storage/component baseline first.

1. Installation is not just “get a docker command”

Chapter 01 separated the Docker client, the Engine daemon, the runtime stack, the image, and the container process. Installation is the first time those boundaries become operational. A machine can have a Docker CLI with no local daemon, a daemon with a client that targets some other endpoint, Docker Desktop with a daemon inside a managed Linux VM, or two valid local targets selected by different contexts. The command docker ps only has meaning after you know which client is speaking to which endpoint.

A reproducible installation therefore has several identities: host OS and architecture, package or Desktop source, client version, server version and API negotiation, active context, daemon endpoint, data root, storage/image-store behavior, privilege model, and the exact image/container used to verify the environment. If any one is ambiguous, troubleshooting and automation can change the wrong machine while still returning syntactically valid Docker output.

Security boundary. A local Docker socket is not a harmless developer convenience. Access to a rootful daemon can be equivalent to host-level privilege. Never “fix” permission errors with chmod 666 /var/run/docker.sock, broad socket sharing, or unauthenticated TCP exposure.

2. The installation mental model

From supported platform to verified runtime
flowchart TD
  A[Supported host or Desktop platform] --> B[Trusted package or Desktop distribution]
  B --> C[Docker CLI and Engine or managed VM]
  C --> D[Selected Docker context and endpoint]
  D --> E[Daemon runtime state and data root]
  E --> F[Image content pulled by exact daemon]
  F --> G[Test container object and process]
  G --> H[Recorded version context storage and lifecycle evidence]

The arrows matter. A package install can succeed while the daemon service is stopped. A daemon can be healthy while the CLI points at another context. A test container can run while the user still has an unsafe privilege model. A Desktop GUI can be open while a shell overrides the selected context through environment variables. Installation is complete only when the whole chain is proven.

3. Docker Engine and Docker Desktop are different installation boundaries

PathWhere the daemon runsTypical endpoint modelWhat to record
Native Docker Engine on LinuxDirectly on the Linux host.Usually a Unix socket such as /var/run/docker.sock.Distribution, kernel, package repository, Engine/CLI/API, service unit, data root, storage driver/image store, privilege mode.
Docker Desktop on Windows/macOSLinux containers run through Docker Desktop's managed Linux VM/backend; Windows can also support Windows-container paths under specific editions/modes.Docker Desktop configures client access to its managed backend.Desktop version, host OS, backend such as WSL 2/Hyper-V/VMM where applicable, context, Desktop disk/data location, actual Engine reported by docker version.
Docker Desktop on LinuxA dedicated Linux VM, separate from a native host Engine.Desktop creates and selects a desktop-linux context; native Engine commonly remains on default.Which context is active, Desktop version, host Engine presence, and which environment owns images/containers.
CLI-only or remote-client setupNo local daemon is required.Named SSH/TLS context or another protected endpoint.Client version, context name, endpoint scheme, TLS/SSH identity, remote server version/API.

This is why “Docker is installed” is too vague. On macOS a standalone Docker CLI does not include a local Linux daemon. On Linux, Desktop and native Engine can coexist but manage different object stores. On Windows, the Desktop backend and host features determine what the daemon can run.

4. Package source is part of the supply chain

On supported Linux distributions, Docker's own repository provides the current Engine packages. Distribution-maintained packages such as docker.io are a separate supply and support path and can differ in version, build configuration, packaging, or support ownership. Manual static binaries are useful for testing but Docker explicitly discourages them as a normal production installation because automatic security updates and package lifecycle management are weaker.

The convenience script at get.docker.com is also not a production lifecycle strategy. Docker documents it for testing/development and recommends reviewing or dry-running it first. Its convenience is that it detects a platform and configures a package source; its tradeoff is that it hides choices and normally tracks the latest stable release unless you deliberately manage versions afterward.

Supply-chain evidence
  • Distribution and architecture are supported for the chosen method.
  • Repository URL and signing-key location are documented.
  • Installed package names and exact versions are captured.
  • Upgrade and rollback ownership are known.
  • Conflicting distribution/third-party packages are identified before removal.

5. Client version, server version, and API version are separate

The Docker CLI is a client of the Engine API. docker version reports client and server information independently. A newer CLI can often communicate with an older daemon through API negotiation, but that does not mean every new CLI feature is available on that server. The environment variable DOCKER_API_VERSION can force an API version for debugging and disables normal negotiation, so it should not be left behind accidentally in a shell profile.

docker version
docker info
printf 'DOCKER_API_VERSION=%s
' "${DOCKER_API_VERSION:-}"

Record the values the pair actually reports. Version skew is a fact to reason about, not automatically a fault. If a feature fails, first ask whether the selected server supports it.

6. Contexts answer the most important operational question: which daemon?

A Docker context bundles endpoint and related connection metadata under a human-readable name. docker context use changes the persistent default in the client configuration, while --context and DOCKER_CONTEXT can override it. Current CLI documentation states that DOCKER_CONTEXT overrides DOCKER_HOST and the stored default context. Command-line flags override environment variables.

docker context ls
docker context show
docker context inspect "$(docker context show)"
printf 'DOCKER_CONTEXT=%s
' "${DOCKER_CONTEXT:-}"
printf 'DOCKER_HOST=%s
' "${DOCKER_HOST:-}"

Never make a destructive change after looking only at the shell prompt or host name. A remote context can make a local shell administer a remote daemon, and Docker Desktop can deliberately select a context different from a native Engine.

7. Service state, daemon configuration, data root, and object state are different

On a regular Linux Engine installation, dockerd is commonly managed by systemd. Its preferred configuration surface is a JSON file (normally /etc/docker/daemon.json for rootful Linux), while the default persistent Docker data root is /var/lib/docker. Runtime/exec state lives elsewhere. Docker Desktop owns its daemon configuration through Desktop settings rather than asking users to manage the VM's daemon as if it were a normal host service.

docker info --format 'DockerRootDir={{.DockerRootDir}}'
docker info --format 'Driver={{.Driver}} CgroupDriver={{.CgroupDriver}} CgroupVersion={{.CgroupVersion}}'
docker info --format 'SecurityOptions={{json .SecurityOptions}}'

Changing or deleting a data root is not an installation cleanup shortcut. It can destroy images, container metadata, volumes, and other state. Chapter 32 will cover storage internals; at installation time the correct habit is to identify the data root and leave it alone unless a deliberate migration plan exists.

8. “Run Docker without sudo” has two very different meanings

Adding a user to the docker group lets that user access the rootful daemon socket. Docker's own documentation warns that this grants root-level privileges. Rootless Docker is a different architecture: both daemon and containers run without root privileges inside a user namespace, with prerequisites such as newuidmap/newgidmap and subordinate UID/GID ranges.

ModeDaemon identityMain benefitMain caution
sudo docker ...Rootful daemon; CLI invoked through sudo.Explicit elevation at use time.Still full daemon privilege; scripts may become awkward.
docker groupRootful daemon; group can access socket.Convenient non-sudo CLI.Group membership is root-level privilege, not least privilege.
Rootless DockerDaemon and containers run as an unprivileged user in a user namespace.Reduces daemon/runtime privilege on the host.Has platform, networking, storage, cgroup, and subordinate-ID prerequisites/limitations.
Docker Desktop user accessManaged backend/VM with Desktop-specific privilege mediation.Developer-oriented host integration.Host/VM boundary and Desktop licensing/enterprise policy still matter.

9. Read-only installation preflight

Before installing or changing anything, collect a short host baseline. These commands are intentionally non-destructive and help explain why a later installation path succeeds or fails.

uname -a
uname -m
cat /etc/os-release 2>/dev/null || true
command -v docker || true
docker --version 2>/dev/null || true
docker context ls 2>/dev/null || true
systemctl status docker --no-pager 2>/dev/null || true
getent group docker 2>/dev/null || true
grep "^${USER}:" /etc/subuid /etc/subgid 2>/dev/null || true

On Windows, record winver/systeminfo, wsl --version, and Docker Desktop's version/backend. On macOS, record sw_vers, architecture, and Desktop version. The purpose is not to collect everything; it is to know which installation assumptions apply.

10. Common wrong models to remove now

Wrong statementCorrect model
“If docker --version works, Docker is running.”That proves only the client binary executes. Server connectivity is a separate state.
“The default context means this physical machine.”A context is client configuration. Inspect its endpoint instead of inferring geography.
“Adding myself to the docker group makes Docker unprivileged.”It gives the user access to a privileged rootful daemon.
“Docker Desktop is just the Linux Docker daemon installed directly on Windows or macOS.”Linux containers run through a managed Linux VM/backend.
“Reinstalling Docker resets everything.”Package removal and daemon data are separate. Existing data roots can persist across uninstall/reinstall.

Knowledge check

A shell shows Docker CLI 29.8.1, but docker version cannot show a Server section. What has actually been proved?

Why is docker context show required before a destructive command?

Does adding a user to the docker group implement rootless Docker?

Where do Linux containers run when using Docker Desktop on macOS or Windows?

Why should package source and exact package versions be recorded in an installation evidence packet?

Summary

Installing Docker means establishing a supported platform, trusted distribution source, Docker client, reachable Engine endpoint, explicit context, persistent daemon state, and an understood privilege model. Docker Engine and Docker Desktop can present similar CLI workflows while owning different host/runtime boundaries. The next lesson turns this model into a safe installation and verification workflow on a disposable environment.

Next lesson

Next: Installing Docker Engine and Desktop, CLI Basics, Daemon Connectivity, Contexts, and Environment Setup: Guided Hands-On Workflow and Core Operations

Continue with the next lesson in the course sequence and carry forward the evidence-first Docker operating model.

Official references and version notes

Version-sensitive statements in this chapter were rechecked against primary documentation on 2026-09-20. Installation support, package names, Desktop requirements, component versions, context behavior, rootless prerequisites, and security guidance evolve. Always record the versions and platform facts actually reported by the environment you are operating.

Current baseline, not a frozen requirement

At this chapter's verification date, Docker Engine 29.8.1 and Docker Desktop 4.91.0 are current releases, while Buildx 0.37.1, BuildKit 0.33.0, and Compose 5.5.1 are current upstream releases. Bundled component versions can differ by Engine/Desktop/package source. Use docker version, docker info, docker buildx version, and docker compose version as execution evidence rather than assuming those upstream versions are installed.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.