猿问

如何在 Docker 容器之间建立连接

当我尝试将我的 goLang GORM 服务连接到 Docker Postgress 容器时遇到连接问题。我相信问题出在连接字符串底部的 golang 代码上。


docker-compose up

Recreating postgress_postgre_1 ... done

Attaching to postgres

postgres   | 2018-12-11 21:08:48.283 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432

postgres   | 2018-12-11 21:08:48.283 UTC [1] LOG:  listening on IPv6 address "::", port 5432

postgres   | 2018-12-11 21:08:48.291 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"

postgres   | 2018-12-11 21:08:48.316 UTC [20] LOG:  database system was shut down at 2018-12-11 21:08:44 UTC

postgres   | 2018-12-11 21:08:48.328 UTC [1] LOG:  database system is ready to accept connections

=== 当我运行 golang 时,我得到...恐慌:无法连接数据库


=============== docker-compose.yml


version: '3.6'

services:

  postgre:

    image: postgres:11.1-alpine

    ports:

      - '5432:5432'

    network_mode: bridge

    container_name: postgres


    environment:

      POSTGRES_USER: 'user'

      POSTGRES_PASSWORD: 'password'

      POSTGRESS_DB: 'db_amex01'

    volumes:

      - ./init:/docker-entrypoint-initdb.d/

==== 主.go


包主


import (

    "fmt"

    "log"

    "net/http"


    "github.com/gorilla/mux"

    "github.com/jinzhu/gorm"


    // _ "github.com/jinzhu/gorm/dialects/sqlite"

    _ "github.com/jinzhu/gorm/dialects/postgres"

)


// _ "github.com/jinzhu/gorm/blob/master/dialects/postgres"


type ToDo struct {

    gorm.Model

    ID          int    `json:"id"`

    TASK_STRING string `json:"task_string"`

    DONE        bool   `json:"done"`

}


var db *gorm.DB

var err error


func main() {

    const (

        host     = "localhost"

        port     = 5432

        user     = "postgres"

        password = "password"

        dbname   = "db_amex01"

    )



// this is the problem I believe I am having...


    db, err := gorm.Open("postgres", "host='postgres' port=5432 user=user dbname='db_amex01' password='password'")




    defer db.Close()


    if err != nil {

        panic("failed to connect database")

    }


    defer db.Close()


人到中年有点甜
浏览 113回答 2
2回答

德玛西亚99

您的撰写文件中有错字,您将服务命名为 postgre 但连接到 postgres。Docker 在共享网络上使用服务名称作为 DNS 别名,因此这会中断您的连接尝试。要修复,只需重命名您的服务:version: '3.6'services:  postgres:    image: postgres:11.1-alpine    ports:      - '5432:5432'    environment:      POSTGRES_USER: 'user'      POSTGRES_PASSWORD: 'password'      POSTGRESS_DB: 'db_amex01'    volumes:      - ./init:/docker-entrypoint-initdb.d/

叮当猫咪

看起来好像您正在丢弃从返回的错误gorm.Open()。要确切知道 gorm 无法打开连接的原因,您需要输出错误。代替:panic("failed to connect database")使用:panic("failed to connect database: " + err)一眼看去,可能是你的主机配置错误host='postgres' port=5432 user=user dbname='db_amex01' password='password'应该:host=localhost port=5432 user=user dbname=db_amex01 password=password但是如果没有来自的错误就很难说gorm.Open()还有一件事要注意;db.Close()在第一次检查错误之前不要打电话。在出现错误的情况下,可能db会nil导致对任何db方法的调用出现恐慌。您还在db.Close()发布的代码片段中调用了两次。不要这样做。Golang 的文档io.Closer:Closer 是包装基本 Close 方法的接口。第一次调用后 Close 的行为未定义。具体的实现可能会记录他们自己的行为。编辑(12/12/2018):当我在本地运行你的代码时,我从 gorm 得到的错误是关于 SSL 的,因为你正在通过 docker-compose 运行你的 postgres 服务器而没有任何 SSL 配置。您可以将sslmode=disable标志添加到连接字符串以解决此问题。docker-compose.yml您的: POSTGRESS_DBshould be也有错字POSTGRES_DB。这是我在本地运行的完整工作示例:docker-compose.yml:version: '3.6'services:  postgres:    image: postgres:11.1-alpine    ports:      - '5432:5432'    environment:      POSTGRES_USER: 'test_user'      POSTGRES_PASSWORD: 'test_password'      POSTGRES_DB: 'test_database'    volumes:      - ./init:/docker-entrypoint-initdb.d/main.go:package mainimport (    "fmt"    "log"    "github.com/jinzhu/gorm"    _ "github.com/jinzhu/gorm/dialects/postgres")const (    host     = "localhost"    port     = "5432"    user     = "test_user"    password = "test_password"    dbname   = "test_database")func main() {    url := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable",        user,        password,        host,        port,        dbname,    )    db, err := gorm.Open("postgres", url)    if err != nil {        log.Fatalf("error connecting to database: %v", err)    }    defer db.Close()    if err := db.DB().Ping(); err != nil {        log.Fatalf("error pinging database: %v", err)    }    fmt.Println("Success!")}
随时随地看视频慕课网APP

相关分类

Go
我要回答