Docker

7 posts in this section

Testcontainers in CI/CD — GitHub Actions, Docker, and Production Patterns

Testcontainers tests that run perfectly on your developer laptop can fail in CI for environmental reasons — Docker daemon availability, image pull timeouts, port conflicts, and resource limits. This final article covers production-ready CI/CD configuration for Testcontainers in GitHub Actions, GitLab CI, and Jenkins, plus Spring Boot 3.1’s development-time container support. What You’ll Learn GitHub Actions configuration for Testcontainers (zero extra setup on ubuntu-latest) GitLab CI configuration with Docker-in-Docker Jenkins configuration with Docker socket mounting TestApplication — running your app locally with containers instead of a real database .

Continue reading »

Understanding Wait Strategies in Testcontainers

A container being started does not mean it is ready to accept connections. Docker marks the container as running the moment the entrypoint process starts. PostgreSQL needs another second or two to initialize storage, bind to port 5432, and start accepting connections. If your test code tries to connect before the database is ready, you get Connection refused. The wrong solution is Thread.sleep(5000). That is a fixed delay: too short on a slow machine, too long on a fast one.

Continue reading »

What Is Testcontainers and Why You Need It

Your CI pipeline goes green. You deploy to staging. The application crashes on startup because Flyway migrations fail against MySQL — but all your tests used H2. Your team has seen this before. Tests that pass on every machine, fail in production. Not because the business logic was wrong, but because the test infrastructure was fake. This is the problem Testcontainers was built to solve. This article covers what Testcontainers is, why traditional approaches to integration testing fall short, and how Testcontainers gives you test environments that match production — automatically, repeatably, with no shared test database to maintain.

Continue reading »

Starting a Kafka Cluster: Single-Broker and 3-Broker with KRaft

Prerequisites Docker Desktop installed and running docker compose v2 (bundled with Docker Desktop 4.x+) Ports 9092, 9093, 9094 free on your machine All articles in this series assume a running local Kafka cluster. Start with the single-broker setup for articles 1–6, then switch to the 3-broker cluster when we cover replication and fault tolerance. Single-Broker Cluster (Development) This is the simplest setup — one Kafka node running in combined mode (broker + controller).

Continue reading »

Dockerizing Spring Boot Applications

Packaging your Spring Boot application as a Docker container is the standard way to deploy it — to Kubernetes, cloud platforms, or any container runtime. This article covers building production-quality images. The Naive Dockerfile (Don’t Use This) FROM eclipse-temurin:21-jdk COPY target/order-service.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"] Problems: 600MB+ image (JDK, not JRE) No layer caching — every code change rebuilds the whole JAR layer Runs as root (security risk) No health check Layered JARs (Better Cache Utilization) Spring Boot 3 creates layered JARs by default.

Continue reading »

Spring Boot Docker: Multi-Stage Builds, Layered JARs, and Buildpacks

There are three ways to containerise a Spring Boot application: a naive single-stage Dockerfile, a proper multi-stage Dockerfile with layered JARs, and Cloud Native Buildpacks. Each has different tradeoffs in build speed, image size, and maintenance overhead. This guide covers all three approaches, explains why layered JARs matter for CI/CD speed, and shows how to produce small, secure, production-ready images. The Problem with the Naive Dockerfile Most tutorials show this:

Continue reading »

Spring Boot Testing with Testcontainers: The Right Way

Testcontainers spins up real Docker containers for your tests — a real PostgreSQL database, a real Redis, a real Kafka broker. No more mocking JDBC connections or in-memory H2 databases that behave differently from production. Spring Boot 3.1 added @ServiceConnection, which removes the boilerplate of configuring connection URLs manually. This guide covers the right patterns for fast, reliable integration tests with Testcontainers. Why Testcontainers Over H2 Teams use H2 in-memory databases for testing because it’s fast.

Continue reading »