简体   繁体   English

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

[英]How to make connection between Docker Containers

I am having connection issues when I try to connect my goLang GORM service to a Docker Postgress container. 尝试将goLang GORM服务连接到Docker Postgress容器时遇到连接问题。 I believe the problem is my golang code at the bottom at the connection string. 我相信问题是我在连接字符串底部的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

=== when I run the golang I get... panic: failed to connect database ===当我运行golang时,我得到...恐慌:无法连接数据库

=============== docker-compose.yml ============== 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 ==== main.go

package main 包主

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()

There's a typo in your compose file, you name the service postgre but connect to postgres. 撰写文件中有一个错字,您将服务命名为postgre,但连接到postgres。 Docker uses the service name for the DNS alias on a shared network, so this will break your connection attempt. Docker在共享网络上使用服务名称作为DNS别名,因此这将中断您的连接尝试。 To fix, just rename your service: 要解决此问题,只需重命名服务:

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/

It appears as though you're discarding the error returned from gorm.Open() . 似乎您正在舍弃gorm.Open()返回的错误。 To know exactly why gorm failed to open the connection, you'd need to output the error. 要确切知道gorm为什么无法打开连接,您需要输出错误。

Instead of: 代替:

panic("failed to connect database")

Use: 采用:

panic("failed to connect database: " + err)

At a glance, it could be that your host is misconfigured 乍一看,可能是您的主机配置错误

host='postgres' port=5432 user=user dbname='db_amex01' password='password'

Should be: 应该:

host=localhost port=5432 user=user dbname=db_amex01 password=password

But it's hard to tell without the error from gorm.Open() 但是没有gorm.Open()的错误很难分辨

One other thing to note, too; 还要注意另一件事; don't call db.Close() before first checking the error. 在首先检查错误之前,请勿调用db.Close() It's possible that in the case of an error, db may be nil , causing calls to any of db 's methods to panic. 在发生错误的情况下, db可能为nil ,从而导致对db的任何方法的调用都陷入恐慌。 You're also calling db.Close() twice in the code snippet you posted. 您还要在发布的代码片段中两次调用db.Close() Don't do this. 不要这样 Golang's documentation on io.Closer : Golang在io.Closer上的文档:

Closer is the interface that wraps the basic Close method. Closer是包装基本Close方法的接口。

The behavior of Close after the first call is undefined. 第一次调用后关闭的行为是不确定的。 Specific implementations may document their own behavior. 特定的实现可以记录自己的行为。

Edit (12/12/2018): 编辑(12/12/2018):

When I ran your code locally, the error I got from gorm was regarding SSL, because you're running your postgres server via docker-compose without any SSL configuration. 当我在本地运行代码时,我从gorm得到的错误是关于SSL的,因为您是在没有任何SSL配置的情况下通过docker-compose运行postgres服务器的。 You can add the sslmode=disable flag to your connection string to fix this issue. 您可以在连接字符串中添加sslmode=disable标志来解决此问题。

Also there's a typo in your docker-compose.yml : POSTGRESS_DB should be POSTGRES_DB . docker-compose.yml也有一个错字: POSTGRESS_DB应该是POSTGRES_DB

Here's a full working example that I got running locally: 这是我在本地运行的完整示例:

docker-compose.yml : 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 : 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!")
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM