When I offload the runtime, and when I stay on the daemon
It is 15 July. Since April 2021 I have had local Testcontainers, and since November 2021 Docker on an Azure agent. In 2023 Cloud stayed off the blog on purpose: AtomicJar’s public beta went out on 25 January, and I did not yet have a reason to write about a service I was not paying for as a process. On 11 December 2023 Docker acquired AtomicJar. Today, a year and a half after the beta and half a year after the acquisition, I am asking one thing: when I offload container runtime to the cloud, and when I stay on the daemon on the laptop and on the hosted agent.
My thesis for July 2024 is narrow. Testcontainers Cloud is mature enough as a Docker service that I can offload runtime from the laptop and from the CI agent without rewriting ContainerBuilder tests. That does not replace the 2021 lesson. A local daemon and a socket on Azure are still canon. Cloud is an option when CPU, RAM, or Docker-in-Docker on the runner hurts.
I do not know of a separate GA announcement before 15 July, and I am not inventing a date. I am not describing unified-plan pricing that Docker will announce in the autumn. I pay for the product that exists, not for a December plan.
Workshop state. NuGet Testcontainers is 3.9.0 from 17 June. The app is on .NET 8. Playwright in the background is 1.45.1 from 2 July; 1.45.2 is tomorrow and I am not pinning it. GPT-4o mini does not yet exist as a pin for this post.
What it is, and what it is not
The same OSS tests. Java, .NET Testcontainers 3.9, Node. Cloud is a worker in the cloud plus Testcontainers Desktop on the laptop or a CI agent with a service-account token. It is not a new framework and not “Testcontainers 4.x”. The libraries stay free. I pay for runtime.
I am not rewriting the MSSQL intro from 2021. I am not teaching socket YAML from scratch from November 2021. August 2022 stays the same pipeline idea: the same test code, a different runtime.
Desktop vs CI
On the laptop, Desktop takes the local daemon off CPU and RAM when the suite stands up Postgres, a queue, and fake SMTP at once. In CI the agent does not have to be privileged and I do not have to mount /var/run/docker.sock the way I did in 2021. The service-account token goes into a secret, not into the repository.
The contrast is runtime, not API. new ContainerBuilder().WithImage("postgres:16") stays. What changes is where the Docker process lives.
When I do not turn it on
A small suite, one Postgres, hosted ubuntu with Docker is enough. Cloud is billed in minutes. I do not put it on every PR, because the CI strategy still splits the gate, main, and nightly. Isolation from October 2021 does not vanish because the container came up in the cloud. I still do not share a database between workers.
July pitfalls
The network to the worker is an extra class of flake the local daemon does not have. An image pull in the cloud does not use the layer cache on the agent I know from Azure. DNS can drift between the laptop and the worker. A service-account secret leaks the same ways as any other token in Actions.
Demo: a synthetic .NET 8 test, Testcontainers 3.9.0, Postgres. Once DOCKER_HOST points at the local daemon. Once Desktop or the Cloud agent. The SELECT 1 assertion is the same. I do not paste a token. I do not name an org.
An LLM is not July’s topic. GPT-4o has existed since May. I do not mix it with container runtime.
Summary
Cloud is a tool for heavy dependencies and a tight runner. The blog canon stays: code defines the container, isolation first, trigger second.
Three sentences for a year from now. 3.9.0 tests do not change when runtime goes to Cloud after the AtomicJar acquisition. I have no GA date to write down and no December price list in July. The Azure socket and the local daemon stay when the suite is small.
What does not follow. It does not follow that I delete Docker on the agent. It does not follow that Compose from February 2021 is redundant. It does not follow that without Docker on CI “I no longer need isolation”.
The condition: two runs, local and Cloud, on the same ContainerBuilder yield the same SELECT 1 without hand-mapping a port. Until then I turn Cloud on where the runner cannot pull images, and I leave 2021 canon where it can.

