To learn Docker, install a supported Docker environment, build and run a small image, then use Compose to run an application with a backing service. The labs below take you through that sequence and show why a local demo still needs readiness checks, persistent storage, and production-specific configuration before it is suitable for deployment.
How do you install Docker and check that it works?
Choose the installation method for your operating system. Docker documents direct Docker Engine installation for supported Linux distributions. Docker Desktop is available for Windows, macOS, and Linux, and is the easiest route to a bundled Engine, CLI, and Compose setup. Linux users who already have Engine and the CLI can install the Compose plugin separately; Docker marks its standalone Compose option as legacy and intended for backward compatibility.
As an Amazon Associate I earn from qualifying purchases.
Use Docker’s current platform-specific instructions: Linux distributions and architectures have distinct steps, and derivatives of supported distributions may work without being tested or verified by Docker. Installation support, release channels, product packaging, and terms can change, so check the current instructions for your platform before installing. Docker’s test release channel contains pre-release features that may break.
- Install Docker Desktop on Windows, macOS, or Linux, or install Docker Engine and the Compose plugin on a supported Linux distribution.
- Open a terminal and run
docker --versionanddocker compose versionto check that the CLI and Compose are available. - Run
docker run hello-world. Docker downloads and runs a small verification image; a success message confirms that the client can reach an Engine and run a container.
Docker states that Docker Engine is licensed under Apache License 2.0. Its installation page also says that commercial use of Docker Engine obtained through Docker Desktop in enterprises exceeding 250 employees or $10 million USD in annual revenue requires a paid subscription. Because the terms and their scope may change, check Docker’s current licensing information for your organization before relying on this summary.
#1 Best Overall
What is the difference between an image, a container, and a Dockerfile?
A Dockerfile contains instructions for building an image. An image is the packaged filesystem and configuration used to create containers. A container is a running (or stopped) instance of an image. The image is not the running application, and a container is not the same thing as the source code used to build it.
Build and run a prebuilt image
Try a small web server image to see the container lifecycle:
docker run --rm -d --name demo-web -p 127.0.0.1:8080:80 nginx:alpine
docker ps
docker logs demo-web
docker stop demo-web
Open http://127.0.0.1:8080 while the container is running. The -p option maps the host’s loopback address and port 8080 to port 80 in the container. Binding to 127.0.0.1 makes this example reachable from the same machine rather than exposing it on every network interface. --rm removes the container after it stops; it does not remove the image.
Build an image from a Dockerfile
Use the following small Flask app and Dockerfile for the Compose lab. Create a directory and save these files in it.
Rank #2
requirements.txt:
Flask
redis
gunicorn
app.py:
import os
import redis
from flask import Flask
app = Flask(__name__)
client = redis.Redis(
host=os.environ.get("REDIS_HOST", "localhost"),
port=6379,
decode_responses=True,
socket_connect_timeout=2,
socket_timeout=2,
)
@app.get("/")
def index():
try:
count = client.incr("visits")
except redis.RedisError:
return {"error": "The backing service is unavailable"}, 503
return {"visits": count}
@app.get("/health")
def health():
return {"status": "ok"}
Dockerfile:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
RUN useradd --create-home appuser
USER appuser
EXPOSE 5000
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
.dockerignore:
.git
.venv
__pycache__
*.py[cod]
.env
The build context is the set of files Docker can access for a build; excluding version-control data, local environments, caches, and environment files avoids sending irrelevant files into that context. Build and run the image:
docker build -t counter-app:dev .
docker run --rm -d --name counter-app -p 127.0.0.1:8000:5000 -e REDIS_HOST=host.docker.internal counter-app:dev
This example runs the web process but not Redis, so requests that need Redis will return a service-unavailable response unless a reachable Redis instance is configured. Stop this standalone container before continuing:
Free tools Windows power users keep installed
One-click scans. No signup required.
docker stop counter-app
The Dockerfile’s base image is intentionally small, but a slim or Alpine label alone does not establish that an image is trustworthy or appropriate. Choose a base image from a source you trust, minimize unnecessary packages, and decide whether you need a moving tag that receives updates or an immutable digest for more reproducible builds. Regularly rebuild to pick up base-image and dependency updates. docker build --pull checks for a newer base image; docker build --no-cache reruns build steps without using the build cache. They solve different problems and can be combined when appropriate.
How do you run an app and Redis together with Docker Compose?
Compose declares related services and their runtime configuration in YAML. The Dockerfile describes how to build the application image; the Compose file describes how services run together. Save this as compose.yaml beside the app files:
Rank #3
services:
app:
build: .
environment:
REDIS_HOST: redis
depends_on:
redis:
condition: service_healthy
redis:
image: redis:7-alpine
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
volumes:
redis-data:
Start the services with a development overlay that publishes the app locally and mounts the app source file into the container. Save it as compose.dev.yaml:
services:
app:
ports:
- "127.0.0.1:8000:5000"
volumes:
- ./app.py:/app/app.py:ro
Then build and start the stack:
docker compose -f compose.yaml -f compose.dev.yaml up --build -d
docker compose -f compose.yaml -f compose.dev.yaml ps
Visit http://127.0.0.1:8000. Each request increments a counter in Redis. The Compose service name redis is the hostname the app uses on Compose’s network; the app should not try to connect to Redis through localhost, which would refer to the app container itself.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Why readiness is different from startup order
A container can be started before the service inside it is ready to accept connections. A simple startup order is therefore not a readiness guarantee. Here, Redis’s health check runs redis-cli ping, and the app’s depends_on condition waits for Redis to become healthy before starting the app. The app also returns a 503 if Redis later becomes unavailable. In a real application, choose retry and failure behavior that fits its requirements; a startup check does not eliminate failures after startup.
Why the volume matters
Redis writes its data to the named redis-data volume, rather than relying only on the container’s writable layer. This example enables Redis append-only persistence and mounts the volume at /data. Recreate the stack with docker compose -f compose.yaml -f compose.dev.yaml down, then start it again: the counter should continue. The named volume remains after down. Running docker compose -f compose.yaml -f compose.dev.yaml down -v removes it and deletes the stored counter.
A named volume addresses container replacement; it is not, by itself, a backup, restore plan, or guarantee against every kind of data loss. Decide how important the data is and provide appropriate backups and recovery procedures before treating the example as a production data store.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →How should you change a Compose setup for production?
A development setup and a production deployment have different needs. Docker’s production guidance identifies source-code mounts, published host ports, environment variables, restart behavior, and logging as configuration to reconsider. Keep the development overlay separate from a production overlay so that local convenience does not become an accidental deployment setting.
For example, save this as compose.production.yaml:
services:
app:
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
redis:
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
Run the production configuration without the development overlay:
docker compose -f compose.yaml -f compose.production.yaml up --build -d
Because the base Compose file does not publish a host port and the production overlay does not add one, the app is not directly reachable from the host in this configuration. A real deployment needs an intentional network and ingress design, such as a separately configured reverse proxy. The example also does not provide production secrets management, high availability, monitoring, or a backup policy; do not infer those capabilities from a successful Compose start.
Best Value
- Docker, Docker Swarm, Docker Compose, Programmer, Developer, Coding, Programming, Software Engineer, Code, DevOps, Deploy, Deployment, Kubernetes, Salt, Puppet, Chef, Terraform, Container, AWS, Azure, Cloud, Geek, Funny, Computer, Software, Tech, IT
- Integration, Scrum, Compile, Compilation, Science, Bug, Debug, Python, Linux, Java, Javascript, Scala, Dotnet, Kotlin
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
Rebuild and recreate deliberately
When application code or its dependencies change, rebuild the affected service and recreate it so the running container uses the new image:
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesdocker compose -f compose.yaml -f compose.production.yaml build --pull app
docker compose -f compose.yaml -f compose.production.yaml up -d --no-deps app
--pull checks for an updated base image during the build. If you need to rerun all Dockerfile build steps instead of reusing cached layers, add --no-cache to the build command. That can make builds slower and does not itself guarantee that every dependency is current.
Deployment boundaries
Compose is useful for defining and running a multi-container application on a Docker host. A working Compose deployment is not automatically a complete production operations plan. Plan how the host is secured, how data is backed up, how credentials are supplied, how images are updated, and how service failures and logs are monitored. Docker also documents deploying to remote Docker hosts using Docker host and TLS environment settings; use the current remote-host guidance for the target’s connection details rather than exposing an unauthenticated Engine endpoint.
Where can you continue learning Docker?
- Docker’s beginner learning path covers images and containers, layers, build-cache behavior, multi-stage and multi-architecture builds, orchestration concepts, the Engine API, and Compose. Its stated prerequisites include Docker Desktop, Git, and a code editor.
- Docker’s training materials include self-guided introductions to getting started, building images, and Compose.
- Docker’s 101 tutorial offers hands-on work with image builds, containers, volumes, source mounts, Compose, networking, and image-building practices.
These official materials are a natural next step after the labs: add a health endpoint that checks dependencies, build a multi-stage image, then document how to update and restore the stack on the host where it will run.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




