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

I am having connection issues when I try to connect my goLang GORM service to a Docker Postgress container. I believe the problem is my golang code at the bottom at the connection string.

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

=============== 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

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()
dooo61733
dooo61733 您是否在docker外部运行go程序?您是否尝试将主机从postgres更改为localhost或postgre?您正在使用什么系统?
一年多之前 回复

2个回答



撰写文件中有一个错字,您将服务命名为postgre但连接到postgres。 Docker在共享网络上使用服务名称作为DNS别名,因此这将中断您的连接尝试。 要解决此问题,只需将服务重命名:</ p>

 版本:'3.6'
services:
postgres:
图片:postgres:11.1-alpine
端口:
  • '5432:5432' 环境: POSTGRES_USER:'用户' POSTGRES_PASSWORD:'密码' POSTGRESS_DB:'db_amex01' 卷: -./init:/docker-entrypoint-initdb.d/
    </ code> </ pre> </ div>

展开原文

原文

There's a typo in your compose file, you name the service postgre but connect to postgres. Docker uses the service name for the DNS alias on a shared network, so this will break your connection attempt. 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(). To know exactly why gorm failed to open the connection, you'd need to output the error.

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

One other thing to note, too; don't call db.Close() before first checking the error. It's possible that in the case of an error, db may be nil, causing calls to any of db's methods to panic. You're also calling db.Close() twice in the code snippet you posted. Don't do this. Golang's documentation on io.Closer:

Closer is the interface that wraps the basic Close method.

The behavior of Close after the first call is undefined. Specific implementations may document their own behavior.

Edit (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. You can add the sslmode=disable flag to your connection string to fix this issue.

Also there's a typo in your docker-compose.yml: POSTGRESS_DB should be POSTGRES_DB.

Here's a full working example that I got running locally:

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!")
}
dongxian1921
dongxian1921 我已经更新了答案,以包含正确的解决方案。
一年多之前 回复
donglian1384
donglian1384 当我尝试从Docker容器外部建立连接时,我正在使用本地主机。 我尝试了很多组合,并用最新的代码更新了我的github页面...以及问题的描述。 我还包括连接错误。
一年多之前 回复
doudi4621
doudi4621 在Docker上下文中,localhost几乎总是错误的。 您可能需要docker-compose.yml文件中其他服务器块的名称postgre; 它可以作为主机名解析为另一个容器的专用IP地址。
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐