Installing Docker & your first run
hello-world, and what just happened.
Installing Docker puts two separate programs on your machine, and knowing which is which will save you hours later. The first is a background service called the Docker daemon. A daemon is a program that starts up and then runs quietly on its own, waiting for work to arrive. It never shows you a window. This one works like a kitchen crew: it does the actual cooking, fetching the software you asked for, running it, cleaning up after it. You never speak to the crew directly. The second program is the docker command you type into a terminal, the text window where you type instructions to your computer. That command is your order pad. You write a ticket, slide it across the counter, and the crew fills the order. Almost every lesson in this course is you writing tickets.
Which pieces you install depends on the machine in front of you. On Linux you install Docker Engine, and it runs containers directly. A container is an ordinary program running on your machine, fenced off in its own little space so it behaves as if it had the whole computer to itself. Linux already has the kernel a container needs. (The kernel is the core of the operating system, the part that actually talks to the hardware.) On a Mac or on Windows you install Docker Desktop instead. Containers need a Linux kernel, and your Mac or Windows machine doesn't have one, so Desktop quietly runs a small Linux virtual machine in the background, a whole extra computer simulated in software, and keeps your containers inside it. Either way you type the same docker commands. The examples below are Linux, because the one error nearly every beginner hits lives there.
Check that both halves are talking
Before you run anything real, get the two halves to say hello. The command docker version asks each of them to report in, and it prints one block per answer.
$ docker version
Client: Docker Engine - CommunityVersion: 27.3.1API version: 1.47Go version: go1.22.7OS/Arch: linux/amd64Context: defaultServer: Docker Engine - CommunityEngine:Version: 27.3.1API version: 1.47 (minimum version 1.24)Go version: go1.22.7OS/Arch: linux/amd64
Read it from the top. The Client block is the docker command you typed. The Server block is the daemon answering back. Two blocks, two version numbers, means your order pad reached the kitchen and the kitchen replied. That's the healthy result. If the Server half is missing, or shows an error where those numbers belong, one of two things is true: the daemon isn't running, or your account isn't allowed to talk to it. A stopped daemon on Linux starts with sudo systemctl start docker. On Docker Desktop you open the app and wait for the little whale icon to stop moving. The second cause, your account not being allowed in, is the wall nearly every beginner walks into on a brand-new Linux install. Let's walk into it on purpose.
Your first container
Tradition says your first run is a tiny image called hello-world. Two words are worth pinning down before you type it. A recipe card isn't a meal. It's the list of ingredients and the steps for making one. An image is Docker's recipe card: a read-only bundle of files plus a note saying which program to start. Read-only means that once the bundle is built, nobody edits it. A container is what you get when Docker follows the recipe and cooks it, the finished dish rather than the card. The hello-world image lives on Docker Hub, a public store of ready-made images, the way an app store is a shelf of ready-made apps. Its full name is hello-world:latest. The part after the colon is the tag, a label that picks which version you want, and latest is the label an image gets by default when nobody asks for a specific one.
Type it and read what comes back.
$ docker run hello-world
docker: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Head "http://%2Fvar%2Frun%2Fdocker.sock/_ping": dial unix /var/run/docker.sock: connect: permission denied.Run 'docker run --help' for more information
Nothing is broken here, so resist the urge to reinstall. Read the words. Permission denied while trying to connect to the Docker daemon socket at /var/run/docker.sock. A socket is a special file the client uses to hand tickets to the daemon, like a service hatch cut through a kitchen wall. On Linux that hatch belongs to the root user (Linux's all-powerful admin account), so an ordinary login isn't allowed to reach through it. Your client tried, got turned away, and told you the exact spot where it was stopped. Run docker version on this same fresh install and its Server half carries the identical error, for the identical reason.
The fix is to let your account use that hatch. Docker creates a group named docker for exactly this purpose, and anyone in that group is allowed to reach the daemon. You add yourself once, with usermod. The -aG flags mean append the account to the named group and leave the groups it already belongs to alone. One snag: your terminal session started before you joined the group, so it hasn't noticed the change. Running newgrp docker opens a fresh session that carries the new membership, and logging out and back in does the same thing. Then the command that failed goes through.
$ sudo usermod -aG docker $USER$ newgrp docker$ docker run hello-world
Unable to find image 'hello-world:latest' locallylatest: Pulling from library/hello-worldc1ec31eb5944: Pull completeDigest: sha256:d000bc569937abbe195e20322a0bde6b2922d805332fd6d8a68b19f524b7d21dStatus: Downloaded newer image for hello-world:latestHello from Docker!This message shows that your installation appears to be working correctly.To generate this message, Docker took the following steps:1. The Docker client contacted the Docker daemon.2. The Docker daemon pulled the "hello-world" image from the Docker Hub.(amd64)3. The Docker daemon created a new container from that image which runs theexecutable that produces the output you are currently reading.4. The Docker daemon streamed that output to the Docker client, which sent itto your terminal.
That wall of text is Docker narrating its own steps. It looked for hello-world on your machine, didn't find it, and said so on the Unable to find image line. Then it pulled a copy down from Docker Hub. Then it created a container from that image and started the one small program inside, which printed the greeting. The program had nothing left to do, so it exited, and the moment a container's program exits, the container stops. Every docker run you ever type follows the same path: look locally, pull the image if it's missing, create the container, start it, and let it run until its program ends.
The daemon has a name worth knowing: dockerd. That is the program doing the real work, pulling images, creating containers, wiring up networks, and on Linux it is what sits on the other side of /var/run/docker.sock. On Docker Desktop it lives inside that small Linux virtual machine, so your order pad is reaching across to another computer to hand over the ticket. Most install trouble is a break somewhere in that handoff, and the error text names which side stopped you, the way the permission line above did.
So make your smoke test boring, and run it in this order. docker version should print a Client block and a Server block. docker run --rm hello-world should print the greeting. docker ps should return a table, even an empty one with nothing but column headings. Once all three behave, you can start blaming your own app. Skip the check and you can lose an afternoon debugging an nginx port mapping on a machine where the daemon never started.
One habit to skip while you are here. You can put sudo in front of every docker command and it will work, which is how plenty of people end up typing sudo docker for years. That habit hides the group setup instead of fixing it, and it stops helping the day you sit at a machine where your account has no sudo rights.
Try this
Prove both halves are alive, then run hello-world with --rm so the finished container doesn't linger on your machine.
docker version --format "{{.Server.Version}}"docker info --format "{{.Driver}} {{.OperatingSystem}}"docker run --rm hello-world
27.x.xoverlay2 Docker DesktopHello from Docker!This message shows that your installation appears to be working correctly.
Takeaway
The docker command is a client and nothing else. If docker version prints no Server block, or hello-world can't reach the socket, that's the engine talking, not your app. Get the engine answering first, before you touch a container of your own.