Learn Docker by running real containers, inspecting images, and writing a minimal Dockerfile you can reuse for local development.
What you will learn
- Images vs containers vs volumes
- Pull, run, stop, and remove containers safely
- Map ports and mount a local folder
- Build a small custom image
- Where official docs override any tutorial shortcut
Prerequisites
- Admin rights to install Docker
- Terminal comfort
- Install from Get Docker and verify with
docker version
Mental model
- Image: immutable template (filesystem + metadata)
- Container: a running (or stopped) instance of an image
- Volume / bind mount: persistent or host-shared files
- Registry: where images are pulled from (Docker Hub by default)
First commands
docker pull hello-world
docker run --rm hello-world
docker pull nginx:alpine
docker run -d --name web -p 8080:80 nginx:alpine
curl -I http://127.0.0.1:8080
docker ps
docker logs web
docker stop web
docker rm webOfficial tour: Docker Get Started.
Persist data with a volume
docker volume create notes
docker run --rm -v notes:/data alpine sh -c "echo hello > /data/hi.txt"
docker run --rm -v notes:/data alpine cat /data/hi.txtBuild a tiny image
Create Dockerfile:
FROM node:22-alpine
WORKDIR /app
COPY package.json ./
RUN npm install --omit=dev
COPY . .
EXPOSE 3000
CMD ["npm", "start"]docker build -t my-api:dev .
docker run --rm -p 3000:3000 my-api:devDockerfile reference: Dockerfile reference.
Bind-mount a project folder
docker run --rm -it -v "$PWD":/work -w /work node:22-alpine shOn Windows PowerShell use ${PWD} or a full path. This pattern is great for one-off tooling without polluting the host Node version.
Useful inspection
docker images
docker inspect web
docker logs --tail 100 web
docker system dfCompose (optional next step)
When you need app + database together, learn Compose from the official overview: Docker Compose. Keep the mental model the same—services are still containers.
Practice checklist
- Run nginx on port
8080and open it in a browser - Write a one-line file into a named volume and read it back
- Build and run a custom image from a
Dockerfile - Remove stopped containers and dangling images when finished
Common pitfalls
- Binding privileged ports without need
- Copying
node_modulesinto images instead of installing inside the build - Forgetting
-pand assuming the app is reachable - Running containers as root in production without a reason
Sources and further reading
- Docker Get Started
- Docker CLI reference
- Dockerfile reference
- Engine source (Moby): moby/moby
- Compose overview: Docker Compose
Who this guide is for
- Developers who want reproducible local environments
- Teams packaging an existing service
- Operators reviewing a container before it reaches a registry
Definition of done
A small, non-root container image that starts predictably, exposes only the required port, persists data intentionally, and has a documented build and rollback command.
Finishing the commands is not the same as finishing the guide. Keep the result only when another person can reproduce it, inspect the evidence, and understand the remaining risks.
Professional workflow
Phase 1 — Make the application deterministic
Goal: Separate application behavior from machine-specific setup.
- List runtime files, environment variables, ports, and writable directories.
- Pin a supported base image deliberately.
- Create a .dockerignore so secrets, build output, and local dependencies are excluded.
Verification: A clean clone can build the image without relying on untracked host files.
Phase 2 — Run and inspect
Goal: Verify the container contract rather than only seeing a green process.
- Start with explicit port and volume mappings.
- Inspect logs, exit code, health behavior, and filesystem writes.
- Stop and recreate the container to prove important data survives only where intended.
Verification: The service passes a functional request after a fresh create, not merely a restart.
Phase 3 — Harden the delivery path
Goal: Prepare the image for review and controlled release.
- Run as a non-root user when the application permits it.
- Scan the built image and review its effective configuration.
- Tag releases immutably and record how to roll back.
Verification: The release note identifies the image digest, configuration source, health check, and previous known-good tag.
Review questions before you continue
- Which data must persist outside the container lifecycle?
- Can the image build without downloading untrusted artifacts at runtime?
- What proves the application is ready, not just listening?
- Who owns base-image and dependency updates?
If an answer is unknown, record it as an explicit follow-up instead of hiding the uncertainty behind a successful demo.
Troubleshooting decision guide
- The port is unreachable: verify the process listens on the container interface and the host mapping is correct.
- Changes do not appear: confirm build context, cache use, and bind-mount precedence.
- The container exits immediately: inspect logs and the configured command before adding restart policies.
- The image is unexpectedly large: inspect layers and separate build dependencies with a multi-stage build.
Change one variable at a time, preserve the first useful error, and write down the command or condition that fixed it. That turns a private debugging session into team knowledge.
Production-readiness checklist
- Use a trusted minimal base and rebuild regularly.
- Keep secrets outside image layers and repository history.
- Set CPU, memory, log, and restart policies at the orchestrator level.
- Add health checks that exercise a meaningful dependency boundary.
- Back up volumes and prove restoration before relying on persistence.
These checks are intentionally stricter than a beginner demo. Use them to decide whether to continue learning, run a controlled pilot, or request specialist review.
Your next 30 minutes
- Build the image once with cache and once from a clean cache.
- Run it as a non-root user and perform one real request.
- Record image size, digest, exposed port, and data paths.
- Open the official Compose guide when the service needs dependencies.
CTA: Pick the first unchecked step, complete it now, and save the evidence in your project README or decision log. Then open the official documentation linked below before adopting the result in production.