Microservices · Lesson 11
Containerizing with Docker
Why Containers Help
A container packages an application with its runtime assumptions into an isolated, portable unit. Docker images make the same service artifact runnable on a developer machine, CI worker, or production platform. Containers do not remove the need for security, monitoring, or resource limits.
A Container-Friendly Java Process
A Java service should write logs to standard output, read configuration from the environment, and handle termination signals so the platform can manage it.
public class ContainerProcess {
public static void main(String[] arguments) throws InterruptedException {
String serviceName = System.getenv().getOrDefault("SERVICE_NAME", "course-service");
System.out.println(serviceName + " is ready");
Thread.sleep(100);
System.out.println(serviceName + " stopped cleanly");
}
}
A Dockerfile commonly selects a small trusted JRE image, copies the built artifact, exposes the service port, and uses java -jar as the entrypoint.
Container Concerns
| Concern | Practice | Benefit |
|---|---|---|
| Image | Pin a trusted base | Reproducible runtime |
| User | Run without root | Smaller blast radius |
| Config | Environment or secrets | Same image across environments |
| Health | Container health check | Safer traffic routing |
| Size | Multi-stage or JRE image | Faster delivery |
Common Mistake and Practices
Common Mistake: Baking credentials or local configuration into an image. Image layers can persist in registries and expose values to anyone who can pull them.
- Scan images for vulnerabilities.
- Run as a non-root user.
- Pin base images and rebuild regularly.
- Keep images small and disposable.
- Send logs and metrics outside the container.
Real-World Use Case
Each academy service is built into an immutable image and deployed with environment-specific settings. A failed release can be rolled back by selecting the previous image digest.
Quiz Check