Step 1 — Verify the install
Open a fresh terminal — PowerShell on Windows, Terminal on macOS, your shell of choice on Linux — and run:
$ docker --version Docker version 27.2.0, build d5c9a4b $ docker run --rm hello-world
The first command prints the engine version. The second pulls a tiny test image, runs it, prints a welcome message, and exits. --rm tells Docker to clean up the container when it finishes. If the welcome message appears, your install is working.
If you see Cannot connect to the Docker daemon, the engine isn’t reachable. Check the whale icon — it should be steady, not animating. If it’s stuck, jump to troubleshooting.
Step 2 — Run a real web server
Let’s start an Nginx server in the background, mapped to port 8080 on your machine:
$ docker run -d --name web -p 8080:80 nginx:alpine 8e0f4a3c2c5d... $ curl -I http://localhost:8080 HTTP/1.1 200 OK Server: nginx/1.27.1
Open http://localhost:8080 in your browser and you’ll see the Nginx welcome page. The flag breakdown:
-d— run in the background (detached).--name web— assign a friendly name so you can refer to it later.-p 8080:80— map host port 8080 to the container’s port 80.nginx:alpine— the image to run, using the lighter Alpine variant.
Step 3 — Inspect, log, and exec
$ docker ps CONTAINER ID IMAGE COMMAND PORTS NAMES 8e0f4a3c2c5d nginx:alpine "nginx -g …" 0.0.0.0:8080->80/tcp web $ docker logs web --tail 5 $ docker exec -it web sh / # ls /usr/share/nginx/html 50x.html index.html / # exit
docker ps lists running containers, docker logs tails their stdout/stderr, and docker exec -it opens an interactive shell inside the container. The -it flag combo is shorthand for “interactive + allocate a TTY.”
The Docker Desktop dashboard exposes the same operations graphically — click a container to view logs, inspect environment variables, or open a shell in one click.
Step 4 — Stop and clean up
$ docker stop web && docker rm web $ docker ps -a # confirm it is gone
docker stop sends SIGTERM and gives the process 10 seconds to exit cleanly. docker rm removes the container record. The image itself stays cached so the next pull is instant.
Step 5 — Build your first image
Create a small project directory with a Dockerfile like this:
# Dockerfile FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --omit=dev COPY . . EXPOSE 3000 CMD ["node", "server.js"]
Add a .dockerignore so big folders stay out of the build context:
# .dockerignore node_modules .git .next *.log
Build and run:
$ docker build -t myapp . $ docker run --rm -p 3000:3000 myapp
Hit localhost:3000 and you should see your app responding from inside the container.
The next 30 minutes
- Multi-service stacks. Add a
docker-compose.ymlwith your app + Postgres and rundocker compose up. The Compose Specification at compose-spec.io is the cross-tool reference. - Persistent volumes. Avoid bind-mounting database directories on macOS or Windows — use named volumes (
-v pgdata:/var/lib/postgresql/data) which live inside the VM and are dramatically faster. - Multi-arch builds.
docker buildx build --platform linux/amd64,linux/arm64 -t myapp .produces images for both architectures from a single command. - Local Kubernetes. Settings → Kubernetes → Enable Kubernetes. Wait a minute, then point
kubectlat thedocker-desktopcontext. - Stuck on something? Jump to troubleshooting.
Frequently asked questions
Questions that come up most often when running Docker Desktop for the first time.
What does "docker run --rm hello-world" do?
It pulls the official hello-world image from Docker Hub (if not already cached), runs it in a new container, prints a welcome message, and then removes the container automatically because of the --rm flag. The image stays cached on disk. It is the standard first-run verification step to confirm the engine is working.
What does --rm do in docker run?
The --rm flag tells Docker to automatically remove the container's writable layer when the container exits. Without it, stopped containers accumulate on disk. For one-shot commands and test containers you'll never reuse, --rm keeps things clean. Omit it when you want to inspect a container's state after it exits.
How do I see all running containers?
Run `docker ps` to list running containers. Add `-a` (`docker ps -a`) to include stopped containers. Each row shows the container ID, image, command, creation time, status, port bindings, and name. The Docker Desktop GUI shows the same list in the Containers tab.
What is the difference between docker stop and docker kill?
`docker stop` sends SIGTERM to the main process and waits 10 seconds for a graceful shutdown before sending SIGKILL. `docker kill` sends SIGKILL immediately without waiting. Use `docker stop` in normal operation so the process can flush buffers and close connections. Use `docker kill` only when a container is unresponsive.
Why does my docker run command say "Cannot connect to the Docker daemon"?
The Docker Desktop engine is not running or is still starting up. Check the system tray (Windows) or menu bar (macOS) — the whale icon should be steady, not animating. If Docker Desktop is not open, launch it and wait for the icon to go steady. If it is open and the error persists, open the troubleshooting page for your platform.
What is the difference between an image and a container?
An image is a read-only template — a layered snapshot of a filesystem and metadata. A container is a running (or stopped) instance of an image with its own writable layer on top. You can run many containers from the same image. Deleting a container does not delete the image; deleting an image is only possible when no containers reference it.