Docker
The standard for containerising applications and test environments. Consistent, portable, and essential for modern CI/CD pipelines.
Overview
Docker, launched in 2013, revolutionised software development by introducing lightweight, portable containers. A Docker container packages an application with all its dependencies, ensuring it runs identically on a developer's laptop, a CI server, and in production. For testing, Docker enables consistent test environments, parallel test execution, and easy integration of dependencies like databases and message queues.
In 2026, Docker is the foundational technology for modern DevOps and testing. Every major CI/CD platform supports Docker, and most NZ software teams use containers for some part of their workflow.
What it's used for
Docker is essential for:
- Consistent test environments: Run tests in the same container that runs in production.
- Integration testing: Spin up databases, caches, and message queues as containers for isolated tests.
- Parallel test execution: Run multiple test suites in parallel containers.
- CI/CD standardisation: Build once, test everywhere, deploy the same container.
- Legacy system testing: Containerise old applications for testing without installing them locally.
Pros & Cons
Pros
- Industry standard — universal adoption
- Consistent environments eliminate 'works on my machine'
- Lightweight compared to virtual machines
- Massive ecosystem of pre-built images on Docker Hub
- Integrates with all CI/CD platforms
Cons
- Security concerns with container images — requires scanning
- Can be complex for beginners (volumes, networking, compose)
- Windows container support is less mature than Linux
- Docker Desktop licensing changed in 2021 (free for personal use, paid for enterprise)
- Container sprawl can become unmanageable without orchestration
Platforms & Integrations
Docker runs on Windows, macOS, and Linux. Docker Desktop is the local development tool. Docker Engine runs on servers and CI runners. Kubernetes is the standard orchestration platform.
Pricing
| Tier | Cost | Includes |
|---|---|---|
| Docker Desktop Personal | Free | Local development, small business use |
| Docker Desktop Pro | $5/user/mo | Commercial use, advanced features |
| Docker Business | $21/user/mo | SSO, audit logs, dedicated support |
| Docker Hub | Free / Pro tiers | Image hosting, automated builds, vulnerability scanning |
NZ Context
Docker is standard in NZ software teams. Every NZ DevOps and QA role lists Docker as a required or strongly preferred skill. NZ cloud providers (AWS, Azure, GCP) all support Docker containers, and NZ startups use Docker for everything from local development to production deployment. For NZ testers, understanding Docker is essential for running integration tests and CI pipelines.
Alternatives
- Podman — Daemonless, rootless container engine. Compatible with Docker.
- LXC/LXD — System containers closer to VMs. Less common for app containerisation.
- Buildpacks — Higher-level abstraction that builds containers without Dockerfiles.
When to choose Docker
A quick decision guide for NZ teams evaluating test environment management options.
| Choose Docker when… | Choose something else when… | Combine with… |
|---|---|---|
| Your team has integration tests that spin up databases, queues, or third-party APIs, and those services behave differently across dev machines | Your team tests a pure SaaS product where you have no control over the environment — use Playwright or Cypress directly without a container wrapper | Docker Compose to orchestrate multi-service test stacks (app + Postgres + Redis) locally and in CI |
| Your CI pipeline needs reproducible builds — same image used to build is used to test and deploy, eliminating environment drift between stages | You are testing a Windows-native desktop application — Docker Windows container support is immature; use a dedicated Windows VM or Azure DevTest Labs instead | GitHub Actions or GitLab CI — both run Docker natively; use service containers to spin up Postgres or MySQL alongside your test runner |
| You need to run parallel test suites without conflicts — each suite gets its own container with its own database state, no shared mutable data | Your team is small (<5 engineers) and only runs end-to-end tests against a shared staging environment — the overhead of learning Docker outweighs the benefit; plain npm scripts suffice | Testcontainers (Java/Node/.NET library) to spin up real Docker containers from within your test code — no docker-compose file required |
| You are containerising a legacy application for testing — Docker lets you run an older Node or Java version in isolation without polluting your local environment | Container security scanning is not yet part of your pipeline and you are working with sensitive data — unscanned images are a real risk; prioritise Trivy or Docker Scout before broad adoption | Trivy or Docker Scout for image vulnerability scanning; Kubernetes when you outgrow Compose and need to orchestrate containers across multiple nodes in production |
What I would do
Practitioner judgment on tool adoption, team onboarding, and when to swap.
docker-compose.yml that brings up the full dependency stack with one command. I would pair every new tester with a 30-minute walkthrough of docker compose up, docker compose logs -f, and docker compose down -v. Those three commands handle 90% of daily container use. I would not start with Kubernetes — that is an orchestration problem, not a test environment problem.The bottom line: Docker solves the "works on my machine" problem permanently — but the real value for testers is not the containers themselves, it is the discipline of making your dependencies explicit and reproducible. Once every service your tests need is declared in a Compose file, onboarding a new tester drops from days to minutes.
Interview questions
Questions you are likely to get if you list Docker on your CV — with what interviewers are really testing for.
What is the difference between a Docker image and a Docker container?
What they’re really testing: Whether you understand the build/run lifecycle or are just parroting CLI commands you’ve copy-pasted.
Strong answer covers: An image is a read-only snapshot (layers built from a Dockerfile); a container is a running instance of that image with a writable layer on top. Multiple containers can run from the same image simultaneously. Bonus: mention that images are immutable, which is what makes deployments reproducible — a key selling point for NZ teams moving away from “configure on the server” approaches.
When would you use Docker Compose over a plain Dockerfile?
What they’re really testing: Whether you know that most real applications have multiple services and can reason about orchestration beyond a single container.
Strong answer covers: Dockerfile defines a single image; Compose coordinates multiple services (app + database + cache + queue) with a single docker compose up. Use Compose when your tests depend on more than one container. Mention that Compose is ideal for local development and CI — it is how most NZ teams wire up Postgres or Redis alongside their test runner without manual networking.
You’re joining the QA team at TeleNZ. Their integration test suite runs against a real MySQL database and takes over an hour in CI because tests share state and occasionally corrupt each other’s data. How would you approach fixing this with Docker?
What they’re really testing: Whether you can apply container isolation to a real flakiness problem, not just recite Docker theory.
Strong answer covers: Introduce Testcontainers so each test suite or test class spins up an ephemeral MySQL container and tears it down after, eliminating shared state. Parallelise suites across GitHub Actions matrix runners once isolation is guaranteed. Also worth noting: audit the test suite for missing teardown first — containers solve the symptom but fixing missing cleanup makes the underlying code more maintainable.
Your automated tests pass locally but fail in CI with a “connection refused” error when connecting to the database container. How do you debug this?
What they’re really testing: Whether you understand container startup ordering and health checks — one of the most common Docker gotchas for testers new to CI.
Strong answer covers: The container may be running but the database process inside it may not be ready yet — Docker starts the container, not the service. Fix with a healthcheck in docker-compose.yml and depends_on: condition: service_healthy, or use a wait-for-it script. Also check that the test code is using the Docker network service name (e.g. db) not localhost — that is the most common cause when it works locally but not in CI.
How would you structure a Docker-based test environment for a microservices application where ten services need to be tested together, but you don’t want CI to take 20 minutes spinning them all up?
What they’re really testing: Whether you can make pragmatic architectural trade-offs between full fidelity and pipeline speed — a common tension at scale.
Strong answer covers: Stub or mock non-critical downstream services (e.g. with WireMock in a container) and only spin up the services under test plus their direct dependencies. Use pre-built base images with dependencies baked in rather than installing at runtime. Layer your test suite: fast unit tests run first without any containers; integration tests run a minimal Compose subset; full end-to-end contract tests run on a schedule or pre-merge only. Mention that NZ teams deploying to AWS or Azure can cache Docker layer pulls to cut image download time significantly.