A quick live-demo walkthrough showing the power of containers using Docker CLI and Docker Compose.
Start an NGINX web server in seconds:
docker run --detach --publish 8080:80 --name web nginxOpen in browser:
http://localhost:8080
- No installation required
- No config files
- No service management
- Works instantly on a clean machine
Start PostgreSQL:
docker run -d \
-e POSTGRES_PASSWORD=secret \
-p 5432:5432 \
--name db \
postgresConfirm it's up and accepting connections:
docker logs db
telnet 127.0.0.1 5432- Fully initialized database in seconds
- No apt install or manual setup
- Disposable infrastructure
Run a temporary Node.js environment:
docker run --rm -it node nodeℹ️ -it is short for --interactive --tty
Inside Node REPL:
console.log("Hello from a clean runtime");
[1,2,3].map(x => x * 2)Exit the container:
.exit- No Node.js installed locally
- No environment pollution
- Disposable tooling
docker run --rm python:3.8 python --version
docker run --rm python:3.12 python --version# NOTE: eclipse-temurin = OpenJDK binaries
docker run --rm eclipse-temurin:17 java -version
docker run --rm eclipse-temurin:21 java -version
docker run --rm eclipse-temurin:latest java -version- Multiple versions simultaneously
- No dependency conflicts
- Perfect reproducibility
docker network create wp-netdocker run -d \
--name wp-db \
--network wp-net \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wp \
-e MYSQL_PASSWORD=wp \
mysql:8docker run -d \
--name wp \
--network wp-net \
-p 8081:80 \
-e WORDPRESS_DB_HOST=wp-db:3306 \
-e WORDPRESS_DB_USER=wp \
-e WORDPRESS_DB_PASSWORD=wp \
-e WORDPRESS_DB_NAME=wordpress \
wordpressOpen in browser:
http://localhost:8081
- Multiple services connected instantly
- Automatic service discovery
- Environment-based configuration
- No manual database wiring
These Docker commands setup our infrastructure consistently, but wouldn't it be nice if we could persist these as a configuration file? This is where Docker Compose comes in!
The commands above have been persisted as compose.yml, and can all be brought up with a simple docker compose up --detach command.
This is called 🌟 Infrastructure as Code 🌟
A full JVM application + database stack — Spring Boot + Postgres — defined entirely in a single compose.yaml. No local JDK, no local Postgres, just one command.
See edu-spring-postgres/README.md for the walkthrough and commands.
We can mount in volumes using the CLI with the --volume or -v argument.
Volumes can be either relative or absolute paths on your machine - or the name of a docker volume.
Example:
docker run --volume ./web:/usr/share/nginx/html --detach --publish 8080:80 --name web nginxRemove containers:
docker rm --force web db wp wp-db spring-app spring-dbRemove networks:
docker network rm wp-net spring-netRemove compose stack (and data volumes!):
docker compose down --volumesGeneral cleanup of all unused Docker resources
docker system prune- No leftover configuration
- No config drift
- Fully disposable environments
- Containers package the entire runtime environment
- Same image runs everywhere
- No "works on my machine"
- Fast local development setup
- Easy reproducibility
- Infrastructure becomes disposable
- Consistent deployments across environments