testcontainers / testcontainers-go

Testcontainers for Go is a Go package that makes it simple to create and clean up container-based dependencies for automated integration/smoke tests. The clean, easy-to-use API enables developers to programmatically define containers that should be run as part of a test and clean up those resources when the test is done.
https://golang.testcontainers.org
MIT License
3.32k stars 451 forks source link

[Bug]: Docker Compose run failed #2559

Closed NX-Official closed 1 month ago

NX-Official commented 1 month ago

Testcontainers version

0.31.0

Using the latest Testcontainers version?

Yes

Host OS

Linux (WSL)

Host arch

x86

Go version

1.22

Docker version

Client:
 Cloud integration: v1.0.35+desktop.13
 Version:           26.1.1
 API version:       1.45
 Go version:        go1.21.9
 Git commit:        4cf5afa
 Built:             Tue Apr 30 11:46:57 2024
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Desktop
 Engine:
  Version:          26.1.1
  API version:      1.45 (minimum version 1.24)
  Go version:       go1.21.9
  Git commit:       ac2de55
  Built:            Tue Apr 30 11:48:28 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.31
  GitCommit:        e377cd56a71523140ca6ae87e30244719194a521
 runc:
  Version:          1.1.12
  GitCommit:        v1.1.12-0-g51d5e94
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Docker info

Client:
 Version:    26.1.1
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.14.0-desktop.1
    Path:     /usr/local/lib/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.27.0-desktop.2
    Path:     /usr/local/lib/docker/cli-plugins/docker-compose
  debug: Get a shell into any image or container (Docker Inc.)
    Version:  0.0.29
    Path:     /usr/local/lib/docker/cli-plugins/docker-debug
  dev: Docker Dev Environments (Docker Inc.)
    Version:  v0.1.2
    Path:     /usr/local/lib/docker/cli-plugins/docker-dev
  extension: Manages Docker extensions (Docker Inc.)
    Version:  v0.2.23
    Path:     /usr/local/lib/docker/cli-plugins/docker-extension
  feedback: Provide feedback, right in your terminal! (Docker Inc.)
    Version:  v1.0.4
    Path:     /usr/local/lib/docker/cli-plugins/docker-feedback
  init: Creates Docker-related starter files for your project (Docker Inc.)
    Version:  v1.1.0
    Path:     /usr/local/lib/docker/cli-plugins/docker-init
  sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc.)
    Version:  0.6.0
    Path:     /usr/local/lib/docker/cli-plugins/docker-sbom
  scout: Docker Scout (Docker Inc.)
    Version:  v1.8.0
    Path:     /usr/local/lib/docker/cli-plugins/docker-scout

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 11
 Server Version: 26.1.1
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: e377cd56a71523140ca6ae87e30244719194a521
 runc version: v1.1.12-0-g51d5e94
 init version: de40ad0
 Security Options:
  seccomp
   Profile: unconfined
 Kernel Version: 5.15.146.1-microsoft-standard-WSL2
 Operating System: Docker Desktop
 OSType: linux
 Architecture: x86_64
 CPUs: 16
 Total Memory: 15.62GiB
 Name: docker-desktop
 ID: 051fda61-320c-4f84-9f15-c4f7c706cc58
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 HTTP Proxy: http.docker.internal:3128
 HTTPS Proxy: http.docker.internal:3128
 No Proxy: hubproxy.docker.internal
 Labels:
  com.docker.desktop.address=unix:///var/run/docker-cli.sock
 Experimental: false
 Insecure Registries:
  hubproxy.docker.internal:5555
  127.0.0.0/8
 Live Restore Enabled: false

WARNING: No blkio throttle.read_bps_device support
WARNING: No blkio throttle.write_bps_device support
WARNING: No blkio throttle.read_iops_device support
WARNING: No blkio throttle.write_iops_device support
WARNING: daemon is not using the default seccomp profile

What happened?

I want to setup a MySQL environment defined in docker-compose.yml , then use GORM to connect it.

But it just shutdown after be created, and could not connect.

I tried to add time.Sleep(10 * time.Second) before I connect but it is not useful

Relevant log output

2024/05/30 11:53:57 github.com/testcontainers/testcontainers-go - Connected to docker: 
  Server Version: 26.1.1
  API Version: 1.45
  Operating System: Docker Desktop
  Total Memory: 15996 MB
  Resolved Docker Host: unix:///var/run/docker.sock
  Resolved Docker Socket Path: /var/run/docker.sock
  Test SessionID: 45c4629982958c81596f5cbfe3ded48bbcd27739521d552eee2ae8e90a790f09
  Test ProcessID: d2f18b19-f2d1-4fd7-a7cb-41faced6db3b
2024/05/30 11:53:57 🐳 Creating container for image testcontainers/ryuk:0.7.0
2024/05/30 11:53:58 ✅ Container created: 2c7a3263adc3
2024/05/30 11:53:58 🐳 Starting container: 2c7a3263adc3
2024/05/30 11:53:58 ✅ Container started: 2c7a3263adc3
2024/05/30 11:53:58 🚧 Waiting for container id 2c7a3263adc3 image: testcontainers/ryuk:0.7.0. Waiting for: &{Port:8080/tcp timeout:<nil> PollInterval:100ms}
2024/05/30 11:53:58 🔔 Container is ready: 2c7a3263adc3
time="2024-05-30T11:53:58+08:00" level=warning msg="/home/nx/helloworld-linux/docker-compose.yml: `version` is obsolete"
 Network 96856658-a4ed-4dca-9c89-4056d17506f5_default  Creating
 Network 96856658-a4ed-4dca-9c89-4056d17506f5_default  Created
 Container 96856658-a4ed-4dca-9c89-4056d17506f5-mysql-1  Creating
 Container 96856658-a4ed-4dca-9c89-4056d17506f5-mysql-1  Created
 Container 96856658-a4ed-4dca-9c89-4056d17506f5-mysql-1  Starting
 Container 96856658-a4ed-4dca-9c89-4056d17506f5-mysql-1  Started
 Container 96856658-a4ed-4dca-9c89-4056d17506f5-mysql-1  Waiting
 Container 96856658-a4ed-4dca-9c89-4056d17506f5-mysql-1  Healthy
[mysql] 2024/05/30 11:54:07 packets.go:37: unexpected EOF
[mysql] 2024/05/30 11:54:07 packets.go:37: unexpected EOF
[mysql] 2024/05/30 11:54:07 packets.go:37: unexpected EOF

2024/05/30 11:54:07 /home/nx/helloworld-linux/main_test.go:44
[error] failed to initialize database, got error driver: bad connection
    main_test.go:45: 
            Error Trace:    /home/nx/helloworld-linux/main_test.go:45
            Error:          Received unexpected error:
                            driver: bad connection
            Test:           TestCompose
 Container 96856658-a4ed-4dca-9c89-4056d17506f5-mysql-1  Stopping
 Container 96856658-a4ed-4dca-9c89-4056d17506f5-mysql-1  Stopped
 Container 96856658-a4ed-4dca-9c89-4056d17506f5-mysql-1  Removing
 Container 96856658-a4ed-4dca-9c89-4056d17506f5-mysql-1  Removed
 Network 96856658-a4ed-4dca-9c89-4056d17506f5_default  Removing
 Network 96856658-a4ed-4dca-9c89-4056d17506f5_default  Removed
--- FAIL: TestCompose (20.79s)

FAIL

Additional information

main_test.go

package main

import (
    "context"
    "fmt"
    "github.com/stretchr/testify/require"
    tc "github.com/testcontainers/testcontainers-go/modules/compose"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "testing"
)

type User struct {
    ID   uint `gorm:"primarykey"`
    Name string
    Age  int
}

func TestCompose(t *testing.T) {
    compose, err := tc.NewDockerCompose("docker-compose.yml")
    require.NoError(t, err, "NewDockerComposeAPI()")

    t.Cleanup(func() {
        require.NoError(t, compose.Down(context.Background(), tc.RemoveOrphans(true), tc.RemoveImagesLocal), "compose.Down()")
    })

    ctx, cancel := context.WithCancel(context.Background())
    t.Cleanup(cancel)

    require.NoError(t, compose.Up(ctx, tc.Wait(true)), "compose.Up()")

    mysqlContainer, err := compose.ServiceContainer(ctx, "mysql")
    require.NoError(t, err, "ServiceContainer()")

    // Get the mapped port for MySQL
    mysqlPort, err := mysqlContainer.MappedPort(ctx, "3306")
    require.NoError(t, err)

    //time.Sleep(10 * time.Second)

    // Construct the DSN
    dsn := fmt.Sprintf("root:12345678@tcp(localhost:%s)/test?charset=utf8mb4&parseTime=True&loc=Local", mysqlPort.Port())

    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    require.NoError(t, err)

    require.NoError(t, db.AutoMigrate(&User{}))

    require.NoError(t, db.Create(&User{Name: "jinzhu", Age: 18}).Error)
    require.NoError(t, db.Create(&User{Name: "jinzhu 2", Age: 20}).Error)
    require.NoError(t, db.Create(&User{Name: "jinzhu 3", Age: 22}).Error)

    var users []User
    require.NoError(t, db.Find(&users).Error)
    require.Equal(t, 3, len(users))
}

docker-compose.yml

version: '2.1'

services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: 12345678
      MYSQL_DATABASE: test
      TZ: Asia/Shanghai
    ports:
      - "3306:3306"
    healthcheck:
      test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
      interval: 1s
      retries: 10
    privileged: true
    restart: always
JulienBreux commented 1 month ago

Hi!

Just could you get the host?

    // Get the mapped port for MySQL.
    mysqlPort, err := mysqlContainer.MappedPort(ctx, "3306")
    require.NoError(t, err)

    // Get the host for MySQL.
    mysqlHost, err := mysqlContainer.Host(ctx)
    require.NoError(t, err)

    // Format the DSN.
    dsn := fmt.Sprintf("root:12345678@tcp(%s:%s)/test?charset=utf8mb4&parseTime=True&loc=Local", mysqlHost, mysqlPort.Port())
NX-Official commented 1 month ago

Oh I am sorry for creating this issue, thanks for help :)

And I hope there can be more examples to help users to use.

JulienBreux commented 1 month ago

Oh I am sorry for creating this issue, thanks for help :)

And I hope there can be more examples to help users to use.

Hey @NX-Official,

No problem, you're so welcome to create all the issues you need. 🤗