Skip to content

Commit b951e92

Browse files
mdelapenyaclaude
andauthored
feat(guides): migrate all testcontainers.com guides (#24505)
## Description Migrate 17 Testcontainers guides from testcontainers.com into the Docker docs site, covering Java (14 guides), .NET (2 guides), and Node.js (1 guide). This follows up on PR #24450 which added the initial Go and Python guides. Each guide is converted from AsciiDoc to Hugo Markdown, split into multi-chapter stepper navigation, updated to the latest Testcontainers API, and verified with passing tests running in containers. Java guides use testcontainers-java 2.0.4 with the new 2.x Maven coordinates and package names (e.g., `testcontainers-postgresql`, `org.testcontainers.postgresql.PostgreSQLContainer`). The Quarkus guide uses Quarkus 3.22.3 with TC 1.x managed by the Quarkus BOM, since no released Quarkus version ships TC 2.x yet. ## How to test All code snippets have been verified by running each guide's source repository tests inside Docker containers with the Docker socket mounted. To re-run the verification, use the `/testcontainers-guides-migrator` skill included in this PR (`.claude/skills/testcontainers-guides-migrator/SKILL.md`). The skill's Step 6 documents the exact container commands and macOS Docker Desktop workarounds (host override, docker-java API version, etc.) needed to run each language's tests: ``` /testcontainers-guides-migrator I want you to verify all the guides in this branch. Do a full review, verifying that all code snippets compile, the code is executable, and ALL the tests pass. Run them as docker containers, never locally. ``` ## Related issues or tickets Supersedes #24450 (expanded from 2 guides to all 19) ## Reviews - [ ] Technical review - [ ] Editorial review - [ ] Product review --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c454cbb commit b951e92

72 files changed

Lines changed: 7879 additions & 20 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/testcontainers-guides-migrator/SKILL.md

Lines changed: 96 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ These are the 21 guides from testcontainers.com/guides/ and their source repos:
5252
| 20 | Getting started for Python | tc-guide-getting-started-with-testcontainers-for-python | python | getting-started |
5353
| 21 | Keycloak with Spring Boot | tc-guide-securing-spring-boot-microservice-using-keycloak-and-testcontainers | java | keycloak-spring-boot |
5454

55-
Already migrated: **#13 (Go getting-started)**, **#20 (Python getting-started)**
55+
Already migrated: **#2 (Java getting-started)**, **#13 (Go getting-started)**, **#20 (Python getting-started)**
5656

5757
## Step 0: Pre-flight
5858

@@ -137,8 +137,9 @@ For each language, check the cloned repo's existing code, then update to the lat
137137
- No `TearDownSuite()` needed if `CleanupContainer` is registered in the helper
138138
- Go version prerequisite: 1.25+
139139

140-
**Java** (testcontainers-java):
141-
- Check the latest BOM version at https://java.testcontainers.org/
140+
**Java** (testcontainers-java 2.0.4):
141+
- Artifacts renamed in 2.x: `org.testcontainers:postgresql` → `org.testcontainers:testcontainers-postgresql`
142+
- Check the latest version at https://java.testcontainers.org/
142143
- Use `@Testcontainers` and `@Container` annotations for JUnit 5 lifecycle
143144
- Prefer module-specific containers (e.g. `PostgreSQLContainer`) over `GenericContainer`
144145
- Use `@DynamicPropertySource` for Spring Boot integration
@@ -246,17 +247,90 @@ If compilation fails, fix the code and update the guide markdown to match.
246247

247248
### 6d: Run tests in a container with Docker socket mounted
248249

249-
Run tests in the same kind of container, but **mount the Docker socket** so Testcontainers can create sibling containers:
250+
Run tests in the same kind of container, but **mount the Docker socket** so Testcontainers can create sibling containers.
251+
252+
#### macOS Docker Desktop workarounds
253+
254+
When running on macOS with Docker Desktop, these environment variables and flags are **required**:
255+
256+
- **`TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal`** — On macOS, containers can't reach sibling containers via the Docker bridge IP (`172.17.0.x`). This tells Testcontainers (including Ryuk) to connect via `host.docker.internal` instead. **Do NOT disable Ryuk** — it is a core Testcontainers feature and the guides must demonstrate proper usage.
257+
- **`docker-java.properties`** with `api.version=1.47` — Docker Desktop's minimum API version is 1.44, but docker-java defaults to 1.24. Create this file in the project root and mount it to `/root/.docker-java.properties` inside Java containers.
258+
- **`-Dspotless.check.skip=true`** — The Spotless Maven plugin in the source repos is incompatible with JDK 21. Skip it since it's a code formatter, not part of the test.
259+
- **`-Dmicronaut.test.resources.enabled=false`** — Micronaut's Test Resources service starts a separate process that can't connect to Docker from inside a container. The guide tests use Testcontainers directly, not Test Resources. Only needed for Micronaut guides.
260+
#### Java guide test command
261+
262+
```bash
263+
# Create docker-java.properties in the project root
264+
echo "api.version=1.47" > <tmpdir>/{REPO_NAME}/docker-java.properties
265+
266+
docker run --rm \
267+
-v "<tmpdir>/{REPO_NAME}":/app \
268+
-v /var/run/docker.sock:/var/run/docker.sock \
269+
-v "<tmpdir>/{REPO_NAME}/docker-java.properties":/root/.docker-java.properties \
270+
-e DOCKER_HOST=unix:///var/run/docker.sock \
271+
-e TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal \
272+
-w /app \
273+
maven:3.9-eclipse-temurin-21 \
274+
mvn -B test -Dspotless.check.skip=true -Dspotless.apply.skip=true
275+
```
276+
277+
For Quarkus guides, use `maven:3.9-eclipse-temurin-17` instead (Quarkus 3.22.3 compiles for Java 17).
278+
279+
#### Go guide test command
280+
281+
```bash
282+
docker run --rm \
283+
-v "<tmpdir>/{REPO_NAME}":/app \
284+
-v /var/run/docker.sock:/var/run/docker.sock \
285+
-e DOCKER_HOST=unix:///var/run/docker.sock \
286+
-e TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal \
287+
-w /app \
288+
golang:1.25-alpine \
289+
sh -c "apk add --no-cache gcc musl-dev && go test -v -count=1 ./..."
290+
```
291+
292+
#### Python guide test command
250293

251294
```bash
252295
docker run --rm \
253296
-v "<tmpdir>/{REPO_NAME}":/app \
254297
-v /var/run/docker.sock:/var/run/docker.sock \
255-
-w /app <language-image> \
256-
sh -c "<test command>"
298+
-e DOCKER_HOST=unix:///var/run/docker.sock \
299+
-e TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal \
300+
-w /app \
301+
python:3.13-slim \
302+
sh -c "pip install -r requirements.txt && python -m pytest"
257303
```
258304

259-
The key is `-v /var/run/docker.sock:/var/run/docker.sock` — this lets Testcontainers inside the container talk to the host's Docker daemon and create sibling containers.
305+
#### .NET guide test command
306+
307+
```bash
308+
docker run --rm \
309+
-v "<tmpdir>/{REPO_NAME}":/app \
310+
-v /var/run/docker.sock:/var/run/docker.sock \
311+
-e DOCKER_HOST=unix:///var/run/docker.sock \
312+
-e TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal \
313+
-w /app \
314+
mcr.microsoft.com/dotnet/sdk:9.0 \
315+
dotnet test
316+
```
317+
318+
#### Node.js guide test command
319+
320+
```bash
321+
docker run --rm \
322+
-v "<tmpdir>/{REPO_NAME}":/app \
323+
-v /var/run/docker.sock:/var/run/docker.sock \
324+
-e DOCKER_HOST=unix:///var/run/docker.sock \
325+
-e TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal \
326+
-w /app \
327+
node:22-alpine \
328+
sh -c "npm install && npm test"
329+
```
330+
331+
#### Important: run tests sequentially
332+
333+
Run guide tests **one at a time**. Running multiple concurrent DinD or sibling-container tests can overwhelm Docker Desktop's containerd store and cause `meta.db: input/output error` corruption, requiring a Docker Desktop restart.
260334

261335
### 6e: Fix until green
262336

@@ -274,11 +348,23 @@ If any test fails, debug and fix the code in both the temporary project AND the
274348

275349
## Step 8: Validate
276350

351+
**IMPORTANT**: Run ALL validation locally before committing. Vale checks run on CI and will block the PR if they fail — fixing after push wastes CI cycles and review time.
352+
277353
1. `npx prettier --write content/guides/testcontainers-{LANG}-{GUIDE_ID}/`
278354
2. `npx prettier --write content/manuals/testcontainers.md`
279-
3. `docker buildx bake lint` — must pass
280-
4. `docker buildx bake vale` — check `tmp/vale.out` for errors in new files
281-
- Spelling errors for tech terms: add to `_vale/config/vocabularies/Docker/accept.txt`
355+
3. `docker buildx bake lint` — must pass with no errors
356+
4. `docker buildx bake vale` — then check for errors in the new files:
357+
```bash
358+
grep -A2 "testcontainers-{LANG}-{GUIDE_ID}" tmp/vale.out
359+
```
360+
Fix ALL errors before proceeding. Common issues:
361+
- **Vale.Spelling**: tech terms (library names, tools) not in the dictionary → add to `_vale/config/vocabularies/Docker/accept.txt` (alphabetical order)
362+
- **Vale.Terms**: wrong casing (e.g. "python" → "Python") → fix in the markdown. Watch for package names like `testcontainers-python` triggering false positives — rephrase to "Testcontainers for Python" in prose.
363+
- **Docker.Avoid**: hedge words like "very", "simply" → reword
364+
- **Docker.We**: first-person plural → rewrite to "you" or imperative
365+
- Info-level suggestions (e.g. "VS Code" → "versus") are not blocking but review them
366+
367+
Re-run `docker buildx bake vale` after fixes until no errors remain in the new files.
282368
5. Verify in local dev server (`HUGO_PORT=1314 docker compose watch`):
283369
- Guide appears when filtering by its language
284370
- Guide appears when filtering by `Testing with Docker` tag

_vale/config/vocabularies/Docker/accept.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ exfiltration
88
sandboxing
99
Adreno
1010
Aleksandrov
11+
Awaitility
1112
Amazon
1213
Anchore
1314
Apple
@@ -36,6 +37,7 @@ Chrome DevTools
3637
CI
3738
CI/CD
3839
Citrix
40+
classpath
3941
cli
4042
CLI
4143
CloudFront
@@ -48,13 +50,14 @@ CouchDB
4850
Crowdstrike
4951
[Cc]ybersecurity
5052
datacenter
53+
datasource
5154
Datadog
5255
Ddosify
5356
Debootstrap
5457
denylist
5558
deprovisioning
5659
deserialization
57-
deserialize
60+
deserialize[d]?
5861
Dev
5962
Dev Environments?
6063
Dex
@@ -96,13 +99,16 @@ Git
9699
GitHub
97100
GitHub Actions
98101
Google
102+
Gradle
99103
Grafana
100104
Gravatar
101105
gRPC
102106
Groq
103107
Grype
104108
HyperKit
105109
inferencing
110+
initializer
111+
Initializr
106112
inotify
107113
Intel
108114
Intune
@@ -117,6 +123,7 @@ JetBrains
117123
JFrog
118124
JUnit
119125
Kata
126+
Keycloak
120127
Kerberos
121128
Kiro
122129
Kitematic
@@ -129,7 +136,9 @@ Laradock
129136
Laravel
130137
libseccomp
131138
Linux
139+
Liquibase
132140
LinuxKit
141+
logback
133142
Loggly
134143
Logstash
135144
lookup
@@ -138,15 +147,18 @@ macOS
138147
macvlan
139148
Mail(chimp|gun)
140149
mfsymlinks
150+
Micronaut
141151
Microsoft
142152
minikube
153+
misconfiguration
143154
monorepos?
144155
musl
145156
MySQL
146157
nameserver
147158
namespaced?
148159
namespacing
149160
Neovim
161+
Npgsql
150162
netfilter
151163
netlabel
152164
netlink
@@ -222,14 +234,18 @@ Traefik
222234
Trivy
223235
Trixie
224236
Turtlesim
237+
typesafe
225238
Ubuntu
226239
ufw
227240
umask
228241
uncaptured
229242
Uncaptured
243+
unconfigured
230244
undeterminable
231245
Unix
246+
unmarshalling
232247
unmanaged
248+
upsert
233249
Visual Studio Code
234250
VMware
235251
vpnkit
@@ -244,6 +260,7 @@ WireMock
244260
workdir
245261
WORKDIR
246262
Xdebug
263+
xUnit
247264
XQuartz
248265
youki
249266
Yubikey
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
title: Testing an ASP.NET Core web app with Testcontainers
3+
linkTitle: ASP.NET Core testing
4+
description: Learn how to use Testcontainers for .NET to replace SQLite with a real Microsoft SQL Server in ASP.NET Core integration tests.
5+
keywords: testcontainers, dotnet, csharp, testing, mssql, asp.net core, integration testing, entity framework
6+
summary: |
7+
Learn how to test an ASP.NET Core web app using Testcontainers for .NET
8+
with a real Microsoft SQL Server instance instead of SQLite.
9+
toc_min: 1
10+
toc_max: 2
11+
tags: [testing-with-docker]
12+
languages: [c-sharp]
13+
params:
14+
time: 25 minutes
15+
---
16+
17+
<!-- Source: https://github.com/testcontainers/tc-guide-testing-aspnet-core -->
18+
19+
In this guide, you'll learn how to:
20+
21+
- Use Testcontainers for .NET to spin up a Microsoft SQL Server container for integration tests
22+
- Replace SQLite with a production-like database provider in ASP.NET Core tests
23+
- Customize `WebApplicationFactory` to configure test dependencies with Testcontainers
24+
- Manage container lifecycle with xUnit's `IAsyncLifetime`
25+
26+
## Prerequisites
27+
28+
- .NET 8.0+ SDK
29+
- A code editor or IDE (Visual Studio, VS Code, Rider)
30+
- A Docker environment supported by Testcontainers. For details, see the
31+
[Testcontainers .NET system requirements](https://dotnet.testcontainers.org/supported_docker_environment/).
32+
33+
> [!NOTE]
34+
> If you're new to Testcontainers, visit the
35+
> [Testcontainers overview](https://testcontainers.com/getting-started/) to learn more about
36+
> Testcontainers and the benefits of using it.

0 commit comments

Comments
 (0)