Docker Introduction

Introduction

Docker packages an app and its dependencies into an image, then runs it in an isolated container. You get the same behavior on laptop, CI, and server—useful for MySQL in dev, microservices, and paths toward Kubernetes. This chapter installs Docker on Ubuntu, runs hello-world and MySQL, and introduces Compose at a high level.

Prerequisites

Containers vs Virtual Machines

VMContainer
IsolationFull OS per VMShared kernel, isolated processes
Boot timeMinutesSeconds
SizeGB disk imagesMB layers
Use caseDifferent OS kernelsSame Linux kernel, repeatable app stacks

Containers are not magic security boundaries—treat them like processes with extra packaging.

Install Docker on Ubuntu

Distro package (simple):

bash
sudo apt update
sudo apt install -y docker.io
sudo systemctl enable docker
sudo systemctl start docker
docker --version

Official Docker CE repo is an alternative for newest versions—distro docker.io is enough for learning.

Run without sudo every time:

bash
# Add your user to docker group (log out and back in)
sudo usermod -aG docker "$USER"

Verify after re-login:

bash
docker run hello-world

Warning

docker Group

Members of docker can effectively act as root on the host—only add trusted users.

Core Commands

Port mapping -p host:container is how you reach apps from the host browser or curl.

Example: MySQL for JDBC Practice

Aligns with Install MySQL via Docker:

Data survives restart if you add a volume:

bash
docker run -d \
  --name dev-mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  -v mysql-data:/var/lib/mysql \
  -p 3306:3306 \
  mysql:8

Dockerfile (Awareness)

Images build from a Dockerfile:

dockerfile
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY target/myapp.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
bash
docker build -t myapp:1.0 .
docker run -d -p 8080:8080 --name myapp myapp:1.0

Production pipelines often build in CI and push to a registry—same ideas, more automation.

Docker Compose (Concept)

Compose runs multi-container stacks from compose.yaml:

bash
docker compose up -d
docker compose ps
docker compose logs -f api
docker compose down

One file replaces long docker run scripts for local dev.

Cleanup

bash
# Stop all running containers
docker stop $(docker ps -q) 2>/dev/null
 
# Remove unused images (careful on shared machines)
docker image prune -f
 
# Remove named volume when done with dev DB
docker volume rm mysql-data

FAQ

Docker vs systemd JAR deploy?

systemd + JAR is common on a single VPS. Docker shines when you need identical dev/prod images or many services. Teams use both: Nginx on host, app in container.

Cannot connect to published port?

Check docker ps PORTS column, host firewall (chapter 11), and that the app listens on 0.0.0.0 inside the container.

Permission denied on docker.sock?

User not in docker group or need re-login after usermod.

Container exits immediately?

Run docker logs <name>—wrong command, missing env var, or crash on start.

What comes next?

Nginx reverse proxy and deployment.