Docker & Containers
Docker is how modern applications are packaged and deployed. Every cloud platform, Kubernetes cluster, and CI/CD pipeline works with Docker containers. This skill is mandatory.
| Instruction | Purpose |
|---|---|
FROM | Base image to start from (always first) |
WORKDIR | Set working directory inside container |
COPY | Copy files from host โ container |
RUN | Execute command during BUILD (creates a new layer) |
EXPOSE | Document port (doesn't actually publish) |
CMD | Default command to run when container starts |
ENV | Set environment variable |
ARG | Build-time variable |
Volumes โ Persistent Data
Networking โ Containers Talking to Each Other
alpine base images (e.g., eclipse-temurin:21-jre-alpine instead of eclipse-temurin:21-jre). Alpine is ~5MB vs ~200MB for the full image.COPY simply copies files or directories from host to container. It's straightforward and predictable โ recommended for most use cases.
ADD does everything COPY does plus: automatically extracts tar archives, and can download from URLs. Because of its extra magic, it can cause surprises. Best practice: use COPY unless you specifically need ADD's extra features.
Multi-stage builds use multiple FROM statements. Each stage starts fresh from a base image. You can copy artifacts from one stage to another.
Why: the build stage needs JDK + Maven + source code (large). The final stage only needs JRE + the JAR (small). Without multi-stage, your production image would contain the entire JDK and source code. With multi-stage, the final image is 5-10x smaller and doesn't expose source code.
EXPOSE in Dockerfile is documentation โ it tells other developers which port the container listens on. It does NOT actually publish the port to the host.
-p 8080:8080 in docker run actually publishes the port โ maps port 8080 on the host to port 8080 in the container, making it accessible from outside Docker.
Containers defined in the same docker-compose.yml are automatically on the same Docker network. They can reach each other using the service name as the hostname.
So if your compose file has a service named db, the Spring Boot app can connect to it at jdbc:postgresql://db:5432/studentdb โ the hostname is just db, not localhost or an IP address.