Maison > Article > développement back-end > Conteneurs de test Golang, impossible de faire fonctionner le réseau
l'éditeur php Strawberry a rencontré un problème lors de l'utilisation des conteneurs de test Golang, c'est-à-dire qu'il n'a pas pu faire fonctionner le réseau correctement. Golang testcontainers est un outil permettant d'exécuter des conteneurs dans des tests, qui aide les développeurs à démarrer et à détruire rapidement des conteneurs dans un environnement de test. Cependant, en utilisation réelle, l'éditeur PHP Strawberry a constaté que la fonction réseau ne pouvait pas être utilisée normalement dans le conteneur, ce qui a provoqué certains problèmes lors du test. Ensuite, nous explorerons ensemble la solution à ce problème.
J'essaie de créer des tests dans mon microservice et je souhaite créer un réseau auquel j'attacherai mon conteneur de test de base de données (postgres) et mon conteneur de test de microservice. Peu importe ce que j'essaie, je n'arrive pas à connecter mon microservice à la base de données. Mon microservice est Golang utilisant Fiber et Gorm. J'essaie de me connecter à la base de données dans le fichier de configuration db.go comme ceci :
func SetupDB(port string, host string) *gorm.DB { dsn := "host=" + host + " user=postgres password=password dbname=prescription port=" + port + " sslmode=disable" db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { panic("error connecting to database") } db.AutoMigrate(&model.Prescription{}) return db }
Voici à quoi ressemble mon conteneur de test :
prescriptionDBContainer, err := testcontainers.GenericContainer(context.Background(), testcontainers.GenericContainerRequest{ ContainerRequest: testcontainers.ContainerRequest{ Image: "postgres", ExposedPorts: []string{postgresPort.Port()}, Env: map[string]string{ "POSTGRES_USER": "postgres", "POSTGRES_PASSWORD": "password", "POSTGRES_DB": "prescription", }, Networks: []string{network.Name}, NetworkAliases: map[string][]string{ network.Name: {"db-network"}, }, WaitingFor: wait.ForAll( wait.ForLog("database system is ready to accept connections"), wait.ForListeningPort(postgresPort), ), }, Started: true, })
prescriptionContainer, err := testcontainers.GenericContainer(context.Background(), testcontainers.GenericContainerRequest{ ContainerRequest: testcontainers.ContainerRequest{ FromDockerfile: testcontainers.FromDockerfile{Context: "../../../../prescription"}, Networks: []string{network.Name}, NetworkAliases: map[string][]string{ network.Name: {"db-network"}, }, Env: map[string]string{ "POSTGRES_USER": "postgres", "POSTGRES_PASSWORD": "password", "POSTGRES_DB": "prescription", "HOST": prescriptionDBHost, "DB_PORT": prescriptionDBPort.Port(), }, ExposedPorts: []string{pMicroPort.Port()}, WaitingFor: wait.ForListeningPort("8080"), }, Started: true, })
C'est peut-être parce que je ne comprends tout simplement pas ce qui se passe pendant le processus de connexion réseau dans Docker, mais je suis vraiment perdu et lorsque j'ai configuré l'environnement pour HOST et DB_PORT (j'ai essayé toutes les combinaisons sous le soleil), il refuse les microservices connectés à la base de données
Dans le conteneur de test du microservice j'ai essayé :
"HOST": prescriptionDBHost, "DB_PORT": prescriptionDBPort.Port(),La méthode d'extraction de
prescriptionDBHost est :
prescriptionDBHost, err := prescriptionDBContainer.Name(context.Background())
entraîne le message d'erreur :
failed to initialize database, got error failed to connect to `host=/stoic_heyrovsky user=postgres database=prescription`: dial error (dial unix /stoic_heyrovsky/.s.PGSQL.53802: connect: no such file or directory) panic: error connecting to database
Ensuite, j'ai essayé de supprimer le "/" du nom d'hôte, par exemple :
"HOST": strings.Trim(prescriptionDBHost,"/"), "DB_PORT": prescriptionDBPort.Port(),
J'ai aussi essayé :
"HOST": "localhost", "DB_PORT": prescriptionDBPort.Port(),
"HOST": "127.0.0.1", "DB_PORT": prescriptionDBPort.Port(),
prescriptionDBHost, err := prescriptionDBContainer.ContainerIP(context.Background()) "HOST": prescriptionDBHost, "DB_PORT": prescriptionDBPort.Port(),
Les 4 derniers exemples ici entraînent tous une sorte d'erreur TCP de connexion, par exemple :
failed to initialize database, got error failed to connect to `host=localhost user=postgres database=prescription`: dial error (dial tcp [::1]:53921: connect: cannot assign requested address)
J'ai également débogué et arrêté le testcontainer après avoir créé le conteneur de base de données, puis je suis allé sur mon microservice et j'ai codé en dur une connexion au conteneur avec DB_HOST=localhost et port= et cela a fonctionné, donc je suis vraiment perdu sur ce qui se passe. Quelque chose ne va pas . La seule chose à laquelle je peux penser est que le conteneur de microservices n'est pas connecté au réseau avant d'essayer de se connecter à la base de données ? J'ai effectué une vérification du réseau Docker et je peux voir que le conteneur de base de données est attaché, mais le microservice ne s'attache jamais (mais peut-être est-ce juste pour d'autres raisons ?).
Vous pouvez faire ceci :
prescriptionDBContainer, err := testcontainers.GenericContainer(context.Background(), testcontainers.GenericContainerRequest{ ContainerRequest: testcontainers.ContainerRequest{ Image: "postgres", ExposedPorts: []string{"5432/tcp"}, Env: map[string]string{ "POSTGRES_USER": "postgres", "POSTGRES_PASSWORD": "password", "POSTGRES_DB": "prescription", }, Networks: []string{networkName}, NetworkAliases: map[string][]string{networkName: []string{"postgres"}}, WaitingFor: wait.ForAll( wait.ForLog("database system is ready to accept connections"), wait.ForListeningPort("5432/tcp"), ), }, Started: true, }) if err != nil { t.Fatal(err) } prescriptionContainer, err := testcontainers.GenericContainer(context.Background(), testcontainers.GenericContainerRequest{ ContainerRequest: testcontainers.ContainerRequest{ FromDockerfile: testcontainers.FromDockerfile{Context: "./testapp"}, ExposedPorts: []string{"8080/tcp"}, Networks: []string{networkName}, NetworkAliases: map[string][]string{networkName: []string{"blah"}}, Env: map[string]string{ "DATABASE_URL": "postgres://postgres:password@postgres:5432/prescription", }, WaitingFor: wait.ForListeningPort("8080/tcp"), }, Started: true, })
AttentionNetworkAliases
的配置方式;在您的代码中,您将两者都设置为 db-network
但是,我想,这是由于误解。该设置配置了一个可以引用容器的别名(在本例中,我使用 postgres
作为 postgres 容器;这意味着当连接 HOST
时,根据上面示例中使用的 URL,postgres
将是 postgres
).
Comme alternative, vous pouvez utiliser le port, err :=处方DBContainer.MappedPort(context.Background(), "5432/tcp")
获取主机上公开的端口,然后连接到端口上的 host.docker.internal
port.Port()
.当被测试的应用程序在主机上而不是在容器中运行时,经常使用此方法(但在这种情况下,您将连接到 localhost
并使用从 MappedPort()
rapport renvoyé).
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!