liveBook · Manning

Container

As explained in gRPC Microservices in Go

A container is an isolated process environment that packages an application or dependency with its required runtime components.

A container is an isolated process environment that packages an application or dependency with its required runtime components. In a microservice system, each service runs in its own container and can be deployed, configured, and scaled independently. section 1.4.2

Use containers to support independent service operations:

  • Define resource requests, runtime settings, and scaling factors separately for each service. section 1.4.2
  • Deploy services through Kubernetes specifications in a CI/CD pipeline and discover gRPC endpoints through Kubernetes service names. section 1.4.2
  • Run the same cloud-native service on Kubernetes, AWS Fargate, AWS ECS, or Docker for local development. section 1.4.2

Containers also provide repeatable infrastructure for integration tests. Testcontainers can start a MySQL image, expose its port, wait for a liveness or SQL readiness probe, and pass the resulting endpoint to the test suite. Docker Compose can instead provision a database with initialization SQL and a health check before connections are accepted. section 7.3.2 section 7.4.4

MySQL container for order tests

Configure a MySQL 8.0.30 container with an orders database, expose port 3306, wait for SQL readiness, obtain its connection URL, and run save-and-get integration tests with `go test ./...`. Use a nonroot database user outside the simplified test setup. section 7.3.2

func (o *OrderDatabaseTestSuite) SetupSuite() {                      #1
    ctx := context.Background()
    port := "3306/tcp"
    dbURL := func(port nat.Port) string {
        return fmt.Sprintf("root:s3cr3t@tcp(localhost:%s)/
         orders?charset=utf8mb4&parseTime=True&loc=Local", 
         port.Port())                                              #2
    }
    req := testcontainers.ContainerRequest{
        Image:        "docker.io/mysql:8.0.30",
        ExposedPorts: []string{port},
        Env: map[string]string{
            "MYSQL_ROOT_PASSWORD": "s3cr3t",
            "MYSQL_DATABASE":      "orders",
        },
        WaitingFor: wait.ForSQL(nat.Port(port), "mysql", 
         dbURL).Timeout(time.Second * 30),                         #3
    }
    mysqlContainer, err := testcontainers.GenericContainer(ctx, 
     testcontainers.GenericContainerRequest{
        ContainerRequest: req,
        Started:          true,
    })
    if err != nil {
        log.Fatal("Failed to start Mysql.", err)
    }
    endpoint, _ := mysqlContainer.Endpoint(ctx, "")
    o.DataSourceUrl = 
     fmt.Sprintf("root:s3cr3t@tcp(%s)/
     orders?charset=utf8mb4&parseTime=True&loc=Local", endpoint)   #4
}

Shows the Testcontainers request, environment variables, exposed port, and SQL readiness configuration used to start MySQL for tests. section 7.3.2

How gRPC Microservices in Go covers it

How deep it goes
Explains deployment configuration, service discovery, scaling, readiness checks, and test setup without descending into container internals.
Examples
Uses Kubernetes service deployments, a MySQL 8.0.30 Testcontainer, and a Docker Compose database initialized with payments and orders schemas.
What you can do after
Apply containers via Kubernetes, Docker Compose, and Testcontainers to deploy services and run database-backed integration tests.
How it connects
Connects containers to microservices, Kubernetes, gRPC, service discovery, CI/CD, horizontal scaling, Docker Compose, and integration testing.

Also explained in

Compare how 27 books explain container →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of gRPC Microservices in Go. The section links point to the parts of the book it draws on.