diff --git a/docs/features/containers.md b/docs/features/containers.md index 1f5501e3c..9df4e0c4b 100644 --- a/docs/features/containers.md +++ b/docs/features/containers.md @@ -308,6 +308,18 @@ const container = await new GenericContainer("alpine") .start(); ``` +### With custom hostname + +**Not recommended.** + +See this [Docker blog post on Testcontainers best practices](https://www.docker.com/blog/testcontainers-best-practices/#:~:text=Don't%20hardcode%20the%20hostname) + +```javascript +const container = await new GenericContainer("alpine") + .withHostname("my-hostname") + .start(); +``` + ## Stopping a container Testcontainers by default will not wait until the container has stopped. It will simply issue the stop command and return immediately. This is to save time when running tests. diff --git a/packages/testcontainers/src/generic-container/abstract-started-container.ts b/packages/testcontainers/src/generic-container/abstract-started-container.ts index a88ec6fff..d5cd65278 100644 --- a/packages/testcontainers/src/generic-container/abstract-started-container.ts +++ b/packages/testcontainers/src/generic-container/abstract-started-container.ts @@ -31,6 +31,10 @@ export class AbstractStartedContainer implements StartedTestContainer { return this.startedTestContainer.getHost(); } + public getHostname(): string { + return this.startedTestContainer.getHostname(); + } + public getFirstMappedPort(): number { return this.startedTestContainer.getFirstMappedPort(); } diff --git a/packages/testcontainers/src/generic-container/generic-container.test.ts b/packages/testcontainers/src/generic-container/generic-container.test.ts index 9eff27f52..29f7b7983 100644 --- a/packages/testcontainers/src/generic-container/generic-container.test.ts +++ b/packages/testcontainers/src/generic-container/generic-container.test.ts @@ -534,6 +534,16 @@ describe("GenericContainer", () => { await secondStartedContainer.stop(); }); + it("should set the hostname", async () => { + const container = await new GenericContainer("cristianrgreco/testcontainer:1.1.14") + .withHostname("hostname") + .start(); + + expect(container.getHostname()).toEqual("hostname"); + + await container.stop(); + }); + // failing to build an image hangs within the DockerImageClient.build method, // that change might be larger so leave it out of this commit but skip the failing test it.skip("should throw an error for a target stage that does not exist", async () => { diff --git a/packages/testcontainers/src/generic-container/generic-container.ts b/packages/testcontainers/src/generic-container/generic-container.ts index 4ebe2899f..234f6e90e 100644 --- a/packages/testcontainers/src/generic-container/generic-container.ts +++ b/packages/testcontainers/src/generic-container/generic-container.ts @@ -475,4 +475,9 @@ export class GenericContainer implements TestContainer { this.logConsumer = logConsumer; return this; } + + public withHostname(hostname: string): this { + this.createOpts.Hostname = hostname; + return this; + } } diff --git a/packages/testcontainers/src/generic-container/started-generic-container.ts b/packages/testcontainers/src/generic-container/started-generic-container.ts index c5ff8865a..9039d3664 100644 --- a/packages/testcontainers/src/generic-container/started-generic-container.ts +++ b/packages/testcontainers/src/generic-container/started-generic-container.ts @@ -89,6 +89,10 @@ export class StartedGenericContainer implements StartedTestContainer { return this.host; } + public getHostname(): string { + return this.inspectResult.Config.Hostname; + } + public getFirstMappedPort(): number { return this.boundPorts.getFirstBinding(); } diff --git a/packages/testcontainers/src/test-container.ts b/packages/testcontainers/src/test-container.ts index 056921ac8..ff3094068 100644 --- a/packages/testcontainers/src/test-container.ts +++ b/packages/testcontainers/src/test-container.ts @@ -47,6 +47,7 @@ export interface TestContainer { withResourcesQuota(resourcesQuota: ResourcesQuota): this; withSharedMemorySize(bytes: number): this; withLogConsumer(logConsumer: (stream: Readable) => unknown): this; + withHostname(hostname: string): this; } export interface RestartOptions { @@ -63,6 +64,7 @@ export interface StartedTestContainer { stop(options?: Partial): Promise; restart(options?: Partial): Promise; getHost(): string; + getHostname(): string; getFirstMappedPort(): number; getMappedPort(port: number): number; getName(): string;