### Multi-Container Integration Test Setup Source: https://github.com/ory/dockertest/blob/v4/_autodocs/advanced-usage.md A comprehensive example demonstrating how to set up multiple containers (PostgreSQL, Redis, and an application) on a shared Docker network for integration testing. It includes building the application image, configuring environment variables for service discovery, and verifying connectivity. ```go func TestMultiContainer(t *testing.T) { pool := dockertest.NewPoolT(t, "") // Create dedicated network net := pool.CreateNetworkT(t, "integration-test", nil) // Start PostgreSQL postgres := pool.RunT(t, "postgres", dockertest.WithTag("14"), dockertest.WithEnv([]string{"POSTGRES_PASSWORD=secret"}), ) postgres.ConnectToNetwork(t.Context(), net) // Start Redis redis := pool.RunT(t, "redis", dockertest.WithTag("7"), ) redis.ConnectToNetwork(t.Context(), net) // Start application app := pool.BuildAndRunT(t, "myapp:test", &dockertest.BuildOptions{ContextDir: "./testdata"}, dockertest.WithEnv([]string{ "DB_HOST=postgres", // Container name "DB_PORT=5432", "REDIS_HOST=redis", // Container name "REDIS_PORT=6379", }), ) app.ConnectToNetwork(t.Context(), net) // Verify connectivity err := pool.Retry(t.Context(), 30*time.Second, func() error { // App should be able to reach both postgres and redis return checkAppHealthy() }) } ``` -------------------------------- ### Install Dockertest Source: https://github.com/ory/dockertest/blob/v4/README.md Use 'go get' to install the Dockertest library for your Go project. ```bash go get github.com/ory/dockertest/v4 ``` -------------------------------- ### Start PostgreSQL Container and Connect Source: https://github.com/ory/dockertest/blob/v4/_autodocs/examples.md Demonstrates how to start a PostgreSQL container, retrieve its connection details, and establish a connection for testing. Includes a retry mechanism to ensure the database is ready before attempting to connect. ```go package main import ( "context" "database/sql" "fmt" "testing" "time" _ "github.com/lib/pq" "github.com/ory/dockertest/v4" ) func TestPostgres(t *testing.T) { pool := dockertest.NewPoolT(t, "") // Start PostgreSQL container postgres := pool.RunT(t, "postgres", dockertest.WithTag("14"), dockertest.WithEnv([]string{ "POSTGRES_PASSWORD=secret", "POSTGRES_DB=testdb", }), ) // Get connection string hostPort := postgres.GetHostPort("5432/tcp") connStr := fmt.Sprintf( "postgres://postgres:secret@%s/testdb?sslmode=disable", hostPort, ) // Wait for database to be ready err := pool.Retry(t.Context(), 30*time.Second, func() error { conn, err := sql.Open("postgres", connStr) if err != nil { return err } defer conn.Close() return conn.Ping() }) if err != nil { t.Fatalf("Database not ready: %v", err) } // Test database operations conn, _ := sql.Open("postgres", connStr) defer conn.Close() var version string err = conn.QueryRow("SELECT version() ").Scan(&version) if err != nil { t.Fatal(err) } t.Logf("PostgreSQL version: %s", version) } ``` -------------------------------- ### Run PostgreSQL Container for Tests Source: https://github.com/ory/dockertest/blob/v4/README.md This example demonstrates how to start a PostgreSQL container using Dockertest, configure its environment variables, and retrieve its host port for connection. It includes a retry mechanism to wait for the database to become ready. ```go package myapp_test import ( "testing" "time" dockertest "github.com/ory/dockertest/v4" ) func TestPostgres(t *testing.T) { pool := dockertest.NewPoolT(t, "") // Container is automatically reused across test runs based on "postgres:14". postgres := pool.RunT(t, "postgres", dockertest.WithTag("14"), dockertest.WithEnv([]string{ "POSTGRES_PASSWORD=secret", "POSTGRES_DB=testdb", }), ) hostPort := postgres.GetHostPort("5432/tcp") // Connect to postgres://postgres:secret@hostPort/testdb // Wait for PostgreSQL to be ready err := pool.Retry(t.Context(), 30*time.Second, func() error { // try connecting... return nil }) if err != nil { t.Fatalf("Could not connect: %v", err) } } ``` -------------------------------- ### Docker Networking Setup Source: https://github.com/ory/dockertest/blob/v4/_autodocs/MANIFEST.txt Illustrates how to create a Docker network and connect a container to it. This is essential for multi-container setups where containers need to communicate. ```go network, err := pool.CreateNetwork("test-network") if err != nil { log.Fatalf("Failed to create network: %s", err) } resource, err := pool.RunWithOptions(dockertest.RunOptions{ Name: "my-container", NetworkID: network.Network.ID, }) if err != nil { log.Fatalf("Failed to run container: %s", err) } ``` -------------------------------- ### Multi-Container Setup with Dockertest Source: https://github.com/ory/dockertest/blob/v4/_autodocs/README.md Demonstrates setting up multiple containers (PostgreSQL and a custom app) and connecting them to a shared network. ```go func TestMultiContainer(t *testing.T) { pool := dockertest.NewPoolT(t, "") net := pool.CreateNetworkT(t, "app-network", nil) postgres := pool.RunT(t, "postgres", dockertest.WithName("postgres")) postgres.ConnectToNetwork(t.Context(), net) app := pool.BuildAndRunT(t, "myapp:test", &dockertest.BuildOptions{ContextDir: "./testdata"}, dockertest.WithEnv([]string{"DB_HOST=postgres"}), ) app.ConnectToNetwork(t.Context(), net) } ``` -------------------------------- ### Test Redis Container with Dockertest Source: https://github.com/ory/dockertest/blob/v4/_autodocs/examples.md This example demonstrates starting a Redis container and testing its connectivity and basic operations like SET and GET. It includes a retry mechanism for initial connection. ```go import "github.com/redis/go-redis/v9" func TestRedis(t *testing.T) { pool := dockertest.NewPoolT(t, "") redis := pool.RunT(t, "redis", dockertest.WithTag("7"), ) hostPort := redis.GetHostPort("6379/tcp") err := pool.Retry(t.Context(), 30*time.Second, func() error { client := redis.NewClient(&redis.Options{ Addr: hostPort, }) defer client.Close() return client.Ping(t.Context()).Err() }) if err != nil { t.Fatal(err) } // Use Redis for tests client := redis.NewClient(&redis.Options{ Addr: hostPort, }) defer client.Close() client.Set(t.Context(), "test_key", "test_value", 0) val := client.Get(t.Context(), "test_key").Val() if val != "test_value" { t.Errorf("Expected 'test_value', got '%s'", val) } } ``` -------------------------------- ### Minimal Dockertest Initialization Source: https://github.com/ory/dockertest/blob/v4/_autodocs/module-structure.md Use this for straightforward test setups where automatic cleanup is desired. The pool is ready to use immediately after creation. ```go import "github.com/ory/dockertest/v4" func TestExample(t *testing.T) { pool := dockertest.NewPoolT(t, "") // Pool is ready to use; cleanup is automatic } ``` -------------------------------- ### Create Docker Network with Options Source: https://github.com/ory/dockertest/blob/v4/_autodocs/types.md Example of creating a Docker network using Pool.CreateNetworkT with specific options like driver, internal setting, and labels. ```go net := pool.CreateNetworkT(t, "my-network", &dockertest.NetworkCreateOptions{ Driver: "bridge", Internal: false, Labels: map[string]string{ "environment": "test", }, }, ) ``` -------------------------------- ### Multi-Container Setup with Dockertest Source: https://github.com/ory/dockertest/blob/v4/_autodocs/examples.md Start multiple containers (PostgreSQL and Redis) on a shared network using dockertest. Containers can reach each other by name or IP. Verifies connectivity to PostgreSQL. ```go func TestMultiContainer(t *testing.T) { pool := dockertest.NewPoolT(t, "") // Create network net := pool.CreateNetworkT(t, "app-network", nil) // Start PostgreSQL postgres := pool.RunT(t, "postgres", dockertest.WithTag("14"), dockertest.WithEnv([]string{ "POSTGRES_PASSWORD=secret", "POSTGRES_DB=testdb", }), dockertest.WithName("postgres"), // Use hostname for DNS ) postgres.ConnectToNetwork(t.Context(), net) // Start Redis redis := pool.RunT(t, "redis", dockertest.WithTag("7"), dockertest.WithName("redis"), // Use hostname for DNS ) redis.ConnectToNetwork(t.Context(), net) // Get network IPs pgIP := postgres.GetIPInNetwork(net) redisIP := redis.GetIPInNetwork(net) // Containers can reach each other by name or IP t.Logf("PostgreSQL IP in network: %s", pgIP) t.Logf("Redis IP in network: %s", redisIP) // Verify connectivity psql := postgres.GetHostPort("5432/tcp") err := pool.Retry(t.Context(), 30*time.Second, func() error { conn, err := sql.Open("postgres", fmt.Sprintf("postgres://postgres:secret@%s/testdb?sslmode=disable", psql)) if err != nil { return err } defer conn.Close() return conn.Ping() }) if err != nil { t.Fatal(err) } } ``` -------------------------------- ### PostgreSQL Test Setup with Dockertest Source: https://github.com/ory/dockertest/blob/v4/_autodocs/README.md Sets up a PostgreSQL container using Dockertest, configures its environment, and retries a database connection until successful. ```go func TestPostgres(t *testing.T) { pool := dockertest.NewPoolT(t, "") postgres := pool.RunT(t, "postgres", dockertest.WithTag("14"), dockertest.WithEnv([]string{"POSTGRES_PASSWORD=secret"}), ) hostPort := postgres.GetHostPort("5432/tcp") connStr := fmt.Sprintf("postgres://user:secret@%s/db?sslmode=disable", hostPort) err := pool.Retry(t.Context(), 30*time.Second, func() error { conn, _ := sql.Open("postgres", connStr) defer conn.Close() return conn.Ping() }) } ``` -------------------------------- ### Connect to Cassandra Source: https://github.com/ory/dockertest/blob/v4/_autodocs/examples.md Connect to an Apache Cassandra instance running in a Docker container. This example shows how to configure the connection and perform a basic query. ```go import "github.com/gocql/gocql" func TestCassandra(t *testing.T) { pool := dockertest.NewPoolT(t, "") cassandra := pool.RunT(t, "cassandra", dockertest.WithTag("4"), ) hostPort := cassandra.GetHostPort("9042/tcp") host := cassandra.GetBoundIP("9042/tcp") var session *gocql.Session err := pool.Retry(t.Context(), 60*time.Second, func() error { var err error cluster := gocql.NewCluster(host) cluster.Port = 9042 session, err = cluster.CreateSession() return err }) if err != nil { t.Fatal(err) } defer session.Close() // Use Cassandra var id string iter := session.Query("SELECT id FROM system.local").Iter() if iter.Scan(&id) { t.Logf("Node ID: %s", id) } } ``` -------------------------------- ### Test MySQL Container with Dockertest Source: https://github.com/ory/dockertest/blob/v4/_autodocs/examples.md This snippet shows how to start a MySQL container, configure it with a root password and database, and then test connectivity using a retry mechanism. ```go func TestMySQL(t *testing.T) { pool := dockertest.NewPoolT(t, "") mysql := pool.RunT(t, "mysql", dockertest.WithTag("8"), dockertest.WithEnv([]string{ "MYSQL_ROOT_PASSWORD=root", "MYSQL_DATABASE=testdb", }), ) hostPort := mysql.GetHostPort("3306/tcp") connStr := fmt.Sprintf("root:root@tcp(%s)/testdb", hostPort) err := pool.Retry(t.Context(), 30*time.Second, func() error { conn, err := sql.Open("mysql", connStr) if err != nil { return err } defer conn.Close() return conn.Ping() }) if err != nil { t.Fatal(err) } } ``` -------------------------------- ### Executing Commands and Retrieving Logs Source: https://github.com/ory/dockertest/blob/v4/UPGRADE.md Provides examples for executing commands within a container using `Exec` and retrieving container logs using `Logs` or streaming them with `FollowLogs`. ```go result, err := resource.Exec(ctx, []string{"pg_isready"}) // result.StdOut, result.StdErr, result.ExitCode stdout, stderr, err := resource.Logs(ctx) // stdout and stderr are separated strings // Stream logs until container exits or ctx is cancelled: err = resource.FollowLogs(ctx, os.Stdout, os.Stderr) ``` -------------------------------- ### Container Startup Flow Source: https://github.com/ory/dockertest/blob/v4/_autodocs/module-structure.md Details the steps for running a container within a pool. This includes configuration, checking for existing containers, pulling images, creating and starting new containers, and registering them. ```go pool.Run(ctx, repository, opts) ├─ Build runConfig from RunOptions ├─ Compute reuseID (default: "repository:tag") ├─ Check global registry for existing container ├─ If not found: │ ├─ Pull image via p.pullImage() │ ├─ Create and start container via p.createAndStartContainer() │ ├─ Inspect container with port retry │ ├─ Register in global registry │ └─ Track in pool.resources ├─ Return ClosableResource with reference count └─ Return error on any failure ``` -------------------------------- ### Container Reuse Example Source: https://github.com/ory/dockertest/blob/v4/README.md Demonstrates how containers are automatically reused based on repository and tag. Multiple RunT calls with the same image and tag will reuse the same container. ```go // First test creates container r1 := pool.RunT(t, "postgres", dockertest.WithTag("14")) // Second test reuses the same container r2 := pool.RunT(t, "postgres", dockertest.WithTag("14")) // r1 and r2 point to the same container ``` -------------------------------- ### Pool.Run Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md Starts a Docker container with the given repository. Containers are reused by default based on repository:tag. ```APIDOC ## Pool.Run ### Description Starts a Docker container with the given repository. Containers are reused by default based on `repository:tag`. Use `WithoutReuse()` to force fresh containers. ### Method ```go func (p *pool) Run(ctx context.Context, repository string, opts ...RunOption) (ClosableResource, error) ``` ### Parameters #### Path Parameters - **ctx** (context.Context) - Required - Context for the operation; supports cancellation - **repository** (string) - Required - Docker image repository (e.g., "postgres", "redis") - **opts** ([]RunOption) - Optional - Container configuration options ### Return - `ClosableResource`: Provides access to the running container - `error`: Non-nil on image pull, container creation, or startup failure ### Throws - **`ErrImagePullFailed`**: Docker image could not be pulled from registry - **`ErrContainerCreateFailed`**: Docker container creation failed - **`ErrContainerStartFailed`**: Docker container failed to start ### Example ```go resource, err := pool.Run(ctx, "postgres", dockertest.WithTag("14"), dockertest.WithEnv([]string{"POSTGRES_PASSWORD=secret"}), ) if err != nil { panic(err) } defer resource.Close(ctx) hostPort := resource.GetHostPort("5432/tcp") ``` ``` -------------------------------- ### Retrieve All Containers from Registry Source: https://github.com/ory/dockertest/blob/v4/_autodocs/advanced-usage.md Get a list of all containers currently tracked by the global registry. ```go allResources := dockertest.GetAll() t.Logf("Total containers in registry: %d", len(allResources)) for _, r := range allResources { t.Logf("Container: %s", r.ID()) } ``` -------------------------------- ### Container Creation Flow Source: https://github.com/ory/dockertest/blob/v4/_autodocs/module-structure.md Details the process of creating and starting a Docker container. It involves building container configurations, setting up host configurations, and handling potential errors during startup. ```go p.createAndStartContainer(ctx, ref, cfg) ├─ Build container.Config │ ├─ Set image, env, cmd, user, working_dir, labels, hostname │ ├─ Apply WithContainerConfig modifier if provided ├─ Build container.HostConfig │ ├─ Set PublishAllPorts=true │ ├─ Set port bindings if provided │ ├─ Set binds/volumes if provided │ ├─ Apply WithHostConfig modifier if provided ├─ ContainerCreate with options ├─ ContainerStart │ └─ If fails, remove container and return ErrContainerStartFailed └─ Return container ID ``` -------------------------------- ### Connect to MongoDB with Dockertest Source: https://github.com/ory/dockertest/blob/v4/_autodocs/examples.md Connect to a MongoDB container started by dockertest. Ensure the MongoDB client is retried until a connection is established. ```go import "go.mongodb.org/mongo-driver/mongo" func TestMongo(t *testing.T) { pool := dockertest.NewPoolT(t, "") mongo := pool.RunT(t, "mongo", dockertest.WithTag("6"), ) hostPort := mongo.GetHostPort("27017/tcp") uri := fmt.Sprintf("mongodb://%s", hostPort) var client *mongo.Client err := pool.Retry(t.Context(), 30*time.Second, func() error { var err error client, err = mongo.Connect(t.Context(), options.Client().ApplyURI(uri)) if err != nil { return err } return client.Ping(t.Context(), nil) }) if err != nil { t.Fatal(err) } defer client.Disconnect(t.Context()) // Use MongoDB for tests db := client.Database("testdb") coll := db.Collection("test") result := coll.InsertOne(t.Context(), bson.M{"test": "data"}) t.Logf("Inserted document: %v", result.InsertedID) } ``` -------------------------------- ### Execute Command and Check Result Go Snippet Source: https://github.com/ory/dockertest/blob/v4/_autodocs/types.md Example of executing a command using resource.Exec() and checking its exit code and output. Ensure to handle potential errors. ```go result, err := resource.Exec(ctx, []string{"pg_isready", "-U", "postgres"}) if err != nil { t.Fatal(err) } if result.ExitCode != 0 { t.Logf("Command failed: %s", result.StdErr) } ``` -------------------------------- ### Container Management with Explicit Cleanup (Go) Source: https://github.com/ory/dockertest/blob/v4/_autodocs/README.md This example demonstrates how to manage Docker containers with explicit cleanup using `dockertest.NewPool` and `resource.Close`. It's suitable for applications where manual control over resource lifecycle is needed. ```go func main() { ctx := context.Background() pool, err := dockertest.NewPool(ctx, "") if err != nil { panic(err) } defer pool.Close(ctx) resource, err := pool.Run(ctx, "postgres") if err != nil { panic(err) } defer resource.Close(ctx) } ``` -------------------------------- ### Run Docker Container with Explicit Cleanup Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md Use pool.Run to start a container, optionally configuring it with environment variables and tags. The returned resource requires manual closing via resource.Close(ctx). ```go resource, err := pool.Run(ctx, "postgres", dockertest.WithTag("14"), dockertest.WithEnv([]string{"POSTGRES_PASSWORD=secret"}), ) if err != nil { panic(err) } deffer resource.Close(ctx) hostPort := resource.GetHostPort("5432/tcp") ``` -------------------------------- ### Test Suite with Shared Setup using TestMain Source: https://github.com/ory/dockertest/blob/v4/_autodocs/examples.md Use the TestMain function to set up a shared Docker pool for multiple tests. This pattern pre-warms containers, improving test execution speed. ```go var pool dockertest.ClosablePool func TestMain(m *testing.M) { ctx := context.Background() var err error pool, err = dockertest.NewPool(ctx, "") if err != nil { fmt.Printf("Could not create pool: %v\n", err) os.Exit(1) } // Pre-warm containers _, _ = pool.Run(ctx, "postgres", dockertest.WithTag("14")) _, _ = pool.Run(ctx, "redis", dockertest.WithTag("7")) code := m.Run() if err := pool.Close(ctx); err != nil { fmt.Printf("Could not close pool: %v\n", err) os.Exit(1) } os.Exit(code) } func TestWithSharedPool(t *testing.T) { ctx := context.Background() // All tests use pre-warmed containers postgres, _ := pool.Run(ctx, "postgres", dockertest.WithTag("14")) defer postgres.Close(ctx) hostPort := postgres.GetHostPort("5432/tcp") t.Logf("Using PostgreSQL at %s", hostPort) } ``` -------------------------------- ### Get Connection Info for Docker Container Source: https://github.com/ory/dockertest/blob/v4/README.md Retrieve connection details like host:port, port, IP, and container ID for a running Docker resource. Useful for connecting to services started by dockertest. ```go resource := pool.RunT(t, "postgres", dockertest.WithTag("14")) // Get host:port (e.g., "127.0.0.1:54320") hostPort := resource.GetHostPort("5432/tcp") // Get just the port (e.g., "54320") port := resource.GetPort("5432/tcp") // Get just the IP (e.g., "127.0.0.1") ip := resource.GetBoundIP("5432/tcp") // Get container ID id := resource.ID() ``` -------------------------------- ### Multiple Container Test (v3 vs v4) Source: https://github.com/ory/dockertest/blob/v4/UPGRADE.md Demonstrates setting up multiple containers for testing, comparing v3 and v4 syntax. v4's NewPoolT simplifies cleanup. ```go // v3 pool, _ := dockertest.NewPool("") db, _ := pool.Run("postgres", "14", []string{"POSTGRES_PASSWORD=secret"}) defer pool.Purge(db) cache, _ := pool.Run("redis", "7", nil) defer pool.Purge(cache) ``` ```go // v4 — NewPoolT handles cleanup automatically pool := dockertest.NewPoolT(t, "") db := pool.RunT(t, "postgres", dockertest.WithTag("14"), dockertest.WithEnv([]string{"POSTGRES_PASSWORD=secret"}), ) cache := pool.RunT(t, "redis", dockertest.WithTag("7")) ``` -------------------------------- ### Configure Docker Container Run Options Source: https://github.com/ory/dockertest/blob/v4/_autodocs/README.md Customize container creation with options for tags, environment variables, user, labels, and resource limits. ```go container := pool.RunT(t, "postgres", dockertest.WithTag("14"), dockertest.WithEnv([]string{"POSTGRES_PASSWORD=secret"}), dockertest.WithUser("postgres"), dockertest.WithLabels(map[string]string{"env": "test"}), dockertest.WithHostConfig(func(hc *container.HostConfig) { hc.Resources.Memory = 512 * 1024 * 1024 // 512 MiB }), ) ``` -------------------------------- ### Build and Run Docker Image from Dockerfile Source: https://github.com/ory/dockertest/blob/v4/README.md Build a Docker image from a specified Dockerfile and context directory, then run it as a container. Supports build arguments and environment variables. Use BuildAndRunT for test helper integration. ```go version := "1.0.0" resource, err := pool.BuildAndRun(ctx, "myapp:test", &dockertest.BuildOptions{ ContextDir: "./testdata", Dockerfile: "Dockerfile.test", BuildArgs: map[string]*string{"VERSION": &version}, }, dockertest.WithEnv([]string{"APP_ENV=test"}), ) if err != nil { t.Fatal(err) } ``` ```go resource := pool.BuildAndRunT(t, "myapp:test", &dockertest.BuildOptions{ ContextDir: "./testdata", }, ) ``` -------------------------------- ### Get Container ID Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md Retrieves the full 64-character hexadecimal ID of the Docker container. ```go func (r *resource) ID() string ``` -------------------------------- ### Database Initialization in Container Source: https://github.com/ory/dockertest/blob/v4/_autodocs/advanced-usage.md Execute commands to initialize a database within a container, such as creating a new database. ```go // Create a test database result, err := resource.Exec(ctx, []string{ "createdb", "-U", "postgres", "-T", "template0", // Use clean template "testdb", }) if result.ExitCode != 0 { t.Logf("Database creation output: %s", result.StdErr) } ``` -------------------------------- ### Get Network ID Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md Returns the network ID. Use this to identify a specific Docker network. ```go func (n *dockerNetwork) ID() string ``` -------------------------------- ### API Reference - Docker Networking Source: https://github.com/ory/dockertest/blob/v4/_autodocs/MANIFEST.txt Functions for creating and managing Docker networks to facilitate multi-container setups. ```APIDOC ## CreateNetwork ### Description Creates a new Docker network within the pool. ### Function Signature `CreateNetwork(options ...PoolOption) (*Network, error)` ### Parameters - **options** (`...PoolOption`): A variadic list of `PoolOption` to configure the network creation. ### Return Value - `*Network`: A pointer to the created `Network` object. - `error`: An error if the network creation fails. ## ConnectToNetwork ### Description Connects a running container (Resource) to a specified Docker network. ### Function Signature `ConnectToNetwork(resource *Resource, network *Network, options ...PoolOption) error` ### Parameters - **resource** (`*Resource`): The container to connect. - **network** (`*Network`): The network to connect the container to. - **options** (`...PoolOption`): A variadic list of `PoolOption` for network connection configuration. ### Return Value - `error`: An error if the connection fails. ``` -------------------------------- ### Pool Creation and Lifecycle Source: https://github.com/ory/dockertest/blob/v4/_autodocs/MANIFEST.txt Demonstrates how to create a new pool for managing Docker containers. Use NewPool for standard pools and NewPoolT for test-integrated pools. ```go pool, err := dockertest.NewPool() if err != nil { log.Fatalf("Could not construct model: %s", err) } poolT, err := dockertest.NewPoolT(m.T()) if err != nil { log.Fatalf("Could not construct model: %s", err) } ``` -------------------------------- ### Global Registry Functions Source: https://github.com/ory/dockertest/blob/v4/_autodocs/module-structure.md Functions for managing a global registry of containers. These include registering, getting, and resetting the registry. ```APIDOC ## Global Registry Functions ### Description Global registry functions for managing container registrations. ### Functions - `Register()` - `Get()` - `GetAll()` - `ResetRegistry()` ``` -------------------------------- ### Configure Docker Image Builds with BuildOptions Source: https://github.com/ory/dockertest/blob/v4/_autodocs/types.md Use BuildOptions to configure the building of Docker images from Dockerfiles. ContextDir is required. ```go type BuildOptions struct { // Dockerfile is the name of the Dockerfile within the ContextDir. // Defaults to "Dockerfile" if empty. Dockerfile string // ContextDir is the directory containing the Dockerfile and build context. // This directory will be archived and sent to the Docker daemon. // REQUIRED - build will fail if empty. ContextDir string // Tags are the tags to apply to the built image. // If empty, the image name from BuildAndRun will be used. Tags []string // BuildArgs are build-time variables passed to the Dockerfile. // Use pointers to distinguish between empty string and unset. BuildArgs map[string]*string // Labels are metadata to apply to the built image. Labels map[string]string // NoCache disables build cache when set to true. NoCache bool // ForceRemove always removes intermediate containers, even on build failure. ForceRemove bool } ``` ```go version := "1.0.0" resource := pool.BuildAndRunT(t, "myapp:test", &dockertest.BuildOptions{ ContextDir: "./testdata", Dockerfile: "Dockerfile.test", BuildArgs: map[string]*string{ "VERSION": &version, }, Labels: map[string]string{ "app": "myapp", "env": "test", }, }, ) ``` -------------------------------- ### Retrieve Specific Container from Registry Source: https://github.com/ory/dockertest/blob/v4/_autodocs/advanced-usage.md Get a container from the global registry by its tag. Checks if the container has been previously registered or reused. ```go resource, found := dockertest.Get("postgres:14") if found { t.Logf("Found reused container: %s", resource.ID()) } ``` -------------------------------- ### Get Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md Retrieves a resource from the global registry using its unique reuse identifier. Returns the resource and a boolean indicating if it was found. ```APIDOC ## Get ### Description Retrieves a resource from the global registry. ### Function Signature ```go func Get(reuseID string) (ClosableResource, bool) ``` ### Parameters #### Path Parameters - **reuseID** (string) - Required - Unique reuse identifier ### Return - `ClosableResource`: Found resource, or nil if not found - `bool`: True if found ``` -------------------------------- ### Demonstrate Parallel Acquisition and Release Source: https://github.com/ory/dockertest/blob/v4/_autodocs/module-structure.md Illustrates safe parallel acquisition and release of resources using goroutines and a WaitGroup. This pattern leverages reference counting to manage concurrent access to potentially shared containers. ```go // Parallel acquisition and release var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() r, _ := pool.Run(ctx, "postgres") // May acquire same container defer r.Close(ctx) // Safe ref count decrement }() } wg.Wait() ``` -------------------------------- ### Get Container Inspect Response Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md Fetches the complete Docker container inspection response, providing detailed metadata about the container. ```go func (r *resource) Container() container.InspectResponse ``` -------------------------------- ### Manual Dockertest Initialization Source: https://github.com/ory/dockertest/blob/v4/_autodocs/module-structure.md Use this when you need explicit control over the Docker pool's lifecycle, such as managing context and explicit cleanup. Ensure to defer the `Close` call. ```go import ( "context" "github.com/ory/dockertest/v4" ) func main() { ctx := context.Background() pool, err := dockertest.NewPool(ctx, "") if err != nil { panic(err) } defer pool.Close(ctx) // Use pool } ``` -------------------------------- ### Container Running and Management Source: https://github.com/ory/dockertest/blob/v4/_autodocs/MANIFEST.txt Shows how to run a Docker container from an image. Use Run for standard runs and RunT for test-integrated runs. Ensure the image is available locally or will be pulled. ```go resource, err := pool.Run("postgres", "9.6", []string{"POSTGRES_PASSWORD=secret"}) if err != nil { log.Fatalf("Failed to run container: %s", err) } resourceT, err := poolT.Run("postgres", "9.6", []string{"POSTGRES_PASSWORD=secret"}) if err != nil { log.Fatalf("Failed to run container: %s", err) } ``` -------------------------------- ### Get Container IP in Network Source: https://github.com/ory/dockertest/blob/v4/_autodocs/advanced-usage.md Retrieve the IP address of a container within a specific Docker network. This is useful for constructing connection strings. ```go ip := postgres.GetIPInNetwork(net) // ip = "172.18.0.2" // Use in connection strings connStr := fmt.Sprintf("postgres://user:pass@%s:5432/db", ip) ``` -------------------------------- ### Building Custom Images Source: https://github.com/ory/dockertest/blob/v4/_autodocs/MANIFEST.txt Demonstrates building a custom Docker image from a Dockerfile and then running a container from it. This is useful for testing applications with specific dependencies or configurations. ```go resource, err := pool.BuildAndRun(".", "docker-compose.yml", []string{"POSTGRES_PASSWORD=secret"}) if err != nil { log.Fatalf("Failed to build and run container: %s", err) } ``` -------------------------------- ### Build and Run Custom Docker Images Source: https://github.com/ory/dockertest/blob/v4/UPGRADE.md Explains how to build and run custom Docker images using `BuildAndRun` and `BuildAndRunT`. The `name` parameter is used as the image tag. ```go resource, err := pool.BuildAndRun(ctx, "myapp:test", &dockertest.BuildOptions{ ContextDir: "./testdata", Dockerfile: "Dockerfile.test", }, dockertest.WithEnv([]string{"APP_ENV=test"}), ) if err != nil { panic(err) } defer resource.Close(ctx) // Or in tests (cleanup is automatic via NewPoolT): resource := pool.BuildAndRunT(t, "myapp:test", &dockertest.BuildOptions{ContextDir: "./testdata"}, ) ``` -------------------------------- ### Build and Run Docker Image Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md Builds a Docker image from a Dockerfile and runs it as a container. Requires build options specifying the context directory and Dockerfile, and optionally accepts environment variables and other run options. ```go resource, err := pool.BuildAndRun(ctx, "myapp:test", &dockertest.BuildOptions{ ContextDir: "./testdata", Dockerfile: "Dockerfile.test", BuildArgs: map[string]*string{ "VERSION": pointer("1.0.0"), }, }, dockertest.WithEnv([]string{"APP_ENV=test"}), ) if err != nil { panic(err) } defer resource.Close(ctx) ``` -------------------------------- ### Configure Container Creation with RunOption Source: https://github.com/ory/dockertest/blob/v4/_autodocs/types.md Use RunOption to configure container creation when calling Pool.Run() or Pool.RunT(). Apply multiple options as needed. ```go type RunOption func(*runConfig) error ``` ```go resource := pool.RunT(t, "postgres", dockertest.WithTag("14"), dockertest.WithEnv([]string{"POSTGRES_PASSWORD=secret"}), dockertest.WithLabels(map[string]string{"app": "test"}), ) ``` -------------------------------- ### Error Handling Patterns Source: https://github.com/ory/dockertest/blob/v4/_autodocs/MANIFEST.txt Shows how to check for specific errors using Error.Is() and handle common error scenarios. This is crucial for robust test setup and teardown. ```go if errors.Is(err, dockertest.ErrContainerNotRunning) { log.Println("Container is not running, attempting restart.") } else if err != nil { log.Fatalf("An unexpected error occurred: %s", err) } ``` -------------------------------- ### Run Docker Container with Automatic Test Cleanup Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md pool.RunT is a test helper that starts a container and automatically registers its cleanup with t.Cleanup(). It calls t.Fatalf() on errors. ```go func TestPostgres(t *testing.T) { pool := dockertest.NewPoolT(t, "") postgres := pool.RunT(t, "postgres", dockertest.WithTag("14")) hostPort := postgres.GetHostPort("5432/tcp") } ``` -------------------------------- ### Define ErrContainerStartFailed Source: https://github.com/ory/dockertest/blob/v4/_autodocs/errors.md This error occurs when a Docker container fails to start after being successfully created, often due to issues within the container's entrypoint or environment. ```go var ErrContainerStartFailed = errors.New("container start failed") ``` -------------------------------- ### Container Network Management (Outside Tests) Source: https://github.com/ory/dockertest/blob/v4/UPGRADE.md Demonstrates creating and managing container networks outside of tests using `CreateNetwork`. Remember to manually clean up networks using `net.Close`. ```go // Outside tests: net, err := pool.CreateNetwork(ctx, "test-net", nil) if err != nil { panic(err) } defer net.Close(ctx) ``` -------------------------------- ### Configure Container with Options Source: https://github.com/ory/dockertest/blob/v4/README.md Configures a Docker container with various options including tag, user, environment variables, and labels. ```go resource := pool.RunT(t, "postgres", dockertest.WithTag("14"), dockertest.WithUser("postgres"), dockertest.WithWorkingDir("/var/lib/postgresql/data"), dockertest.WithLabels(map[string]string{ "test": "integration", "service": "database", }), dockertest.WithHostname("test-db"), dockertest.WithEnv([]string{"POSTGRES_PASSWORD=secret"}), ) ``` -------------------------------- ### Get Host Port for Container Port Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md Resolves a container port (e.g., '5432/tcp') to its corresponding host port. Returns an empty string if the port is not found. ```go hostPort := resource.GetPort("5432/tcp") ``` -------------------------------- ### Automatic Container Cleanup with NewPoolT and RunT Source: https://github.com/ory/dockertest/blob/v4/_autodocs/README.md Use NewPoolT and RunT for automatic cleanup of Docker resources when the test exits. This simplifies test setup by leveraging t.Cleanup(). ```go func TestAuto(t *testing.T) { pool := dockertest.NewPoolT(t, "") // Auto-cleanup on t.Cleanup() resource := pool.RunT(t, "postgres") // Auto-cleanup on t.Cleanup() // Everything cleaned up when test exits } ``` -------------------------------- ### Build and Run Custom Docker Image Source: https://github.com/ory/dockertest/blob/v4/_autodocs/examples.md Build a Docker image from a Dockerfile and run it. This is useful for testing applications that require a custom environment. Ensure the Dockerfile and context directory are correctly specified. ```go func TestCustomImage(t *testing.T) { pool := dockertest.NewPoolT(t, "") // Build image from Dockerfile app := pool.BuildAndRunT(t, "myapp:test", &dockertest.BuildOptions{ ContextDir: "./testdata", Dockerfile: "Dockerfile", BuildArgs: map[string]*string{ "VERSION": pointer("1.0.0"), }, }, dockertest.WithEnv([]string{ "APP_ENV=test", "APP_DEBUG=true", }), ) hostPort := app.GetHostPort("8080/tcp") url := fmt.Sprintf("http://%s/health", hostPort) // Wait for app to be ready err := pool.Retry(t.Context(), 30*time.Second, func() error { resp, err := http.Get(url) if err != nil { return err } if resp.StatusCode != http.StatusOK { return fmt.Errorf("unexpected status: %d", resp.StatusCode) } return nil }) if err != nil { t.Fatal(err) } // Test the application resp, _ := http.Get(url) t.Logf("Health check: %d", resp.StatusCode) } func pointer(s string) *string { return &s } ``` -------------------------------- ### Get Container IP Address in Network Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md Retrieves the IP address of a container within a specific Docker network. If the container is not connected to the network, an empty string is returned. ```go func (r *resource) GetIPInNetwork(net Network) string ``` ```go ip := resource.GetIPInNetwork(myNetwork) connStr := fmt.Sprintf("postgres://user:pass@%s:5432/db", ip) ``` -------------------------------- ### Get Underlying Docker Client Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md Retrieves the Moby Docker client instance managed by the pool. This allows for advanced Docker operations not directly exposed by the dockertest pool. ```go func (p *pool) Client() client.DockerClient ``` -------------------------------- ### Basic Test with Automatic Cleanup (Go) Source: https://github.com/ory/dockertest/blob/v4/_autodocs/README.md Use this for testing scenarios where automatic cleanup is desired. It leverages `dockertest.NewPoolT` and `pool.RunT` for simplified container management within tests. ```go package main import ( "fmt" "testing" "github.com/ory/dockertest/v4" ) func TestPostgres(t *testing.T) { // Create pool with automatic cleanup pool := dockertest.NewPoolT(t, "") // Start container (reuses if available) postgres := pool.RunT(t, "postgres", dockertest.WithTag("14"), dockertest.WithEnv([]string{"POSTGRES_PASSWORD=secret"}), ) // Get connection string hostPort := postgres.GetHostPort("5432/tcp") connStr := fmt.Sprintf("postgres://user:secret@%s/db", hostPort) // Use in tests... } ``` -------------------------------- ### Set Resource Limits for Container Source: https://github.com/ory/dockertest/blob/v4/_autodocs/advanced-usage.md Configure memory and CPU limits for a container using WithHostConfig. Ensure values are within system capabilities. ```go resource := pool.RunT(t, "postgres", dockertest.WithTag("14"), dockertest.WithHostConfig(func(hc *container.HostConfig) { hc.Resources = container.Resources{ Memory: 512 * 1024 * 1024, // 512 MiB MemorySwap: 1024 * 1024 * 1024, // 1 GiB CPUShares: 512, // Relative weight } }), ) ``` -------------------------------- ### Build and Run Docker Images Source: https://github.com/ory/dockertest/blob/v4/_autodocs/README.md Build custom Docker images from a Dockerfile using `BuildAndRunT`, specifying build context, Dockerfile name, and build arguments. ```go resource := pool.BuildAndRunT(t, "myapp:test", &dockertest.BuildOptions{ ContextDir: "./testdata", Dockerfile: "Dockerfile.test", BuildArgs: map[string]*string{ "VERSION": pointer("1.0.0"), }, }, ) ``` -------------------------------- ### Package-Level Retry Helper (Exponential Backoff) Source: https://github.com/ory/dockertest/blob/v4/UPGRADE.md Use RetryWithBackoff for exponential backoff retries. This strategy increases the delay between retries over time, which can be useful for services that take longer to start. ```go // Exponential backoff retry dockertest.RetryWithBackoff(ctx, 30*time.Second, 100*time.Millisecond, 5*time.Second, func() error { return db.Ping() }) ``` -------------------------------- ### Container Network Management (Tests) Source: https://github.com/ory/dockertest/blob/v4/UPGRADE.md Shows how to create and manage container networks within tests using `CreateNetworkT`. Networks are automatically cleaned up. ```go // In tests: net := pool.CreateNetworkT(t, "test-net", nil) db := pool.RunT(t, "postgres", dockertest.WithTag("14")) db.ConnectToNetwork(t.Context(), net) ip := db.GetIPInNetwork(net) // Get container's IP on this network db.DisconnectFromNetwork(t.Context(), net) ``` -------------------------------- ### Build and Run Custom Docker Image Source: https://github.com/ory/dockertest/blob/v4/_autodocs/advanced-usage.md Use BuildAndRun to build an image from a Dockerfile and run it immediately. Ensure to close the resource when done. ```go resource, err := pool.BuildAndRun(ctx, "myapp:test", &dockertest.BuildOptions{ ContextDir: "./testdata", Dockerfile: "Dockerfile.test", }, dockertest.WithEnv([]string{"APP_ENV=test"}), ) if err != nil { panic(err) } defer resource.Close(ctx) ``` -------------------------------- ### Wrap Docker API Errors Source: https://github.com/ory/dockertest/blob/v4/_autodocs/module-structure.md Wraps Docker API errors with context for better debugging. Use these patterns for image pull, container creation, and container start operations. ```go fmt.Errorf("%w: %s: %w", ErrImagePullFailed, ref, err) ``` ```go fmt.Errorf("%w from %s: %w", ErrContainerCreateFailed, ref, err) ``` ```go fmt.Errorf("%w: %s: %w", ErrContainerStartFailed, containerID, err) ``` -------------------------------- ### Build and Run Docker Image (Test Helper) Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md A test helper variant of BuildAndRun that uses a TestingTB interface for error handling and cleanup. It does not expose Close() or Cleanup() methods directly. ```go func (p *pool) BuildAndRunT(t TestingTB, name string, buildOpts *BuildOptions, runOpts ...RunOption) Resource ``` -------------------------------- ### Get Host:Port Combination Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md Constructs a 'host:port' string for accessing a container port. Useful for creating connection strings. Returns an empty string if the port is not found. ```go hostPort := resource.GetHostPort("5432/tcp") connStr := fmt.Sprintf("postgres://user:pass@%s/dbname", hostPort) ``` -------------------------------- ### Run Container: v3 vs v4 Source: https://github.com/ory/dockertest/blob/v4/UPGRADE.md Illustrates the difference in running a container between v3 and v4. v4 utilizes functional options for specifying tags and environment variables. ```go resource, err := pool.Run("postgres", "14", []string{"POSTGRES_PASSWORD=secret"}) ``` ```go pool.RunT(t, "postgres", dockertest.WithTag("14"), dockertest.WithEnv([]string{"POSTGRES_PASSWORD=secret"})) ``` -------------------------------- ### Configure Pool with PoolOption Source: https://github.com/ory/dockertest/blob/v4/_autodocs/types.md Use PoolOption to configure a pool when creating it with NewPool() or NewPoolT(). ```go type PoolOption func(*pool) ``` ```go pool := dockertest.NewPoolT(t, "", dockertest.WithMaxWait(2*time.Minute), ) ``` -------------------------------- ### Initialize Docker Test Pool Source: https://github.com/ory/dockertest/blob/v4/_autodocs/README.md Choose between automatic cleanup with `NewPoolT` using `t.Cleanup()` or manual cleanup with `NewPool` requiring `pool.Close()`. ```go // Test helper (automatic cleanup) pool := dockertest.NewPoolT(t, "") // Explicit (manual cleanup) pool, err := dockertest.NewPool(ctx, "") defer pool.Close(ctx) ``` -------------------------------- ### Handle ErrContainerStartFailed Source: https://github.com/ory/dockertest/blob/v4/_autodocs/errors.md Use errors.Is to detect ErrContainerStartFailed, enabling specific handling for containers that fail to start. This can help identify problems with the container's internal configuration or startup commands. ```go resource, err := pool.Run(ctx, "postgres") if errors.Is(err, dockertest.ErrContainerStartFailed) { // Handle container startup failure log.Printf("Container failed to start: %v", err) } ``` -------------------------------- ### New Pool Creation (v4 - Recommended) Source: https://github.com/ory/dockertest/blob/v4/UPGRADE.md Use NewPoolT for most tests in v4. Cleanup is automatically registered via t.Cleanup, eliminating the need for TestMain. ```go // v4 — cleanup is automatic pool := dockertest.NewPoolT(t, "", dockertest.WithMaxWait(2 * time.Minute), ) ``` -------------------------------- ### Get Host IP for Container Port Source: https://github.com/ory/dockertest/blob/v4/_autodocs/api-reference.md Retrieves the host IP address bound to a specific container port. For wildcard bindings (0.0.0.0 or ::), it returns '127.0.0.1'. Returns an empty string if the port is not found. ```go func (r *resource) GetBoundIP(portID string) string ``` -------------------------------- ### Log Retrieval and Streaming Source: https://github.com/ory/dockertest/blob/v4/_autodocs/MANIFEST.txt Demonstrates how to retrieve logs from a Docker container. Logs can be fetched as a single output or streamed in real-time. ```go logs, err := resource.Logs() if err != nil { log.Fatalf("Failed to get logs: %s", err) } log.Printf("Container logs: %s", logs) logReader, err := resource.FollowLogs() if err != nil { log.Fatalf("Failed to follow logs: %s", err) } for line := range logReader { log.Printf("Log stream: %s", line) } ``` -------------------------------- ### Set Container Entrypoint Source: https://github.com/ory/dockertest/blob/v4/_autodocs/options.md Sets the container entrypoint, overriding the image's default ENTRYPOINT. ```go resource := pool.RunT(t, "myapp", dockertest.WithEntrypoint([]string{"/bin/sh", "-c"}), ) ``` -------------------------------- ### Initialize Pool: v3 vs v4 Source: https://github.com/ory/dockertest/blob/v4/UPGRADE.md Compare the initialization of a dockertest pool in v3 versus v4. v4 introduces `NewPoolT` which requires a testing.T object. ```go pool, err := dockertest.NewPool("") ``` ```go pool := dockertest.NewPoolT(t, "") ```