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

时间:2018-12-11 21:19:47

标签: postgresql go docker-compose go-gorm

当我尝试将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/

==== main.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()

2 个答案:

答案 0 :(得分:2)

似乎您正在丢弃从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方法的接口。

     

第一次调用后关闭的行为是不确定的。具体   实现可能会记录自己的行为。

编辑(12/12/2018):

当我在本地运行代码时,我从gorm得到的错误是关于SSL的,因为您正在通过docker-compose运行您的postgres服务器,而没有任何SSL配置。您可以在连接字符串中添加sslmode=disable标志来解决此问题。

您的docker-compose.yml中也有错字:POSTGRESS_DB应该是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 main

import (
    "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!")
}

答案 1 :(得分:2)

撰写文件中有一个错字,您将服务命名为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/