## 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>
2.5 KiB
title, linkTitle, description, weight
| title | linkTitle | description | weight |
|---|---|---|---|
| Replace H2 with the Testcontainers JDBC URL | JDBC URL approach | Use the Testcontainers special JDBC URL to swap H2 for a real PostgreSQL database. | 20 |
Replacing H2 with a real PostgreSQL database requires two test properties:
@DataJpaTest
@TestPropertySource(properties = {
"spring.test.database.replace=none",
"spring.datasource.url=jdbc:tc:postgresql:16-alpine:///db"
})
class ProductRepositoryWithJdbcUrlTest {
@Autowired
ProductRepository productRepository;
@Test
@Sql("classpath:/sql/seed-data.sql")
void shouldGetAllProducts() {
List<Product> products = productRepository.findAll();
assertEquals(2, products.size());
}
}
That's it — two properties and your tests run against a real PostgreSQL database.
How the special JDBC URL works
A standard PostgreSQL JDBC URL looks like:
jdbc:postgresql://localhost:5432/postgres
The Testcontainers special JDBC URL inserts tc: after jdbc::
jdbc:tc:postgresql:///db
The hostname, port, and database name are ignored — Testcontainers manages them automatically. You can specify the Docker image tag after the database name:
jdbc:tc:postgresql:16-alpine:///db
This creates a container from the postgres:16-alpine image.
Initialize the database with a script
Pass TC_INITSCRIPT to run an SQL script when the container starts:
jdbc:tc:postgresql:16-alpine:///db?TC_INITSCRIPT=sql/init-db.sql
Testcontainers runs the script automatically. For production applications, use a database migration tool like Flyway or Liquibase instead.
The special JDBC URL also works for MySQL, MariaDB, PostGIS, YugabyteDB, CockroachDB, and other databases with Testcontainers JDBC support.
Testing JdbcTemplate-based repositories
The same approach works for JdbcTemplate-based repositories. Use @JdbcTest
instead of @DataJpaTest:
@JdbcTest
@TestPropertySource(properties = {
"spring.test.database.replace=none",
"spring.datasource.url=jdbc:tc:postgresql:16-alpine:///db?TC_INITSCRIPT=sql/init-db.sql"
})
class JdbcProductRepositoryTest {
@Autowired
private JdbcTemplate jdbcTemplate;
private JdbcProductRepository productRepository;
@BeforeEach
void setUp() {
productRepository = new JdbcProductRepository(jdbcTemplate);
}
@Test
@Sql("/sql/seed-data.sql")
void shouldGetAllProducts() {
List<Product> products = productRepository.getAllProducts();
assertEquals(2, products.size());
}
}