postgresql - Docker-compose Go 应用程序和 Postgres 之间的通信问题

标签 postgresql docker go docker-compose

我正在尝试设置我的基本 Go 应用程序以连接到 Postgres 数据库。我都使用 docker-compose 作为服务启动。当我运行 docker-compose up ,当 Go 应用程序尝试连接到 Postgres 时,我最终收到超时错误。某些错误或缺失导致我的 Go 应用无法连接到 Postgres。

docker-compose.yml

services:
  api:
    build: .
    ports:
      - 8080:8080
    environment:
      - GOPATH=/go # set up GOPATH in container to reference modules
      - DB_USERNAME=${DB_USERNAME}  # this is `postgres`
      - DB_PASSWORD=${DB_PASSWORD}  # this is an empty string
    volumes:
      - $GOPATH/pkg/mod:/go/pkg/mod

  db:
    image: postgres:11.3
    ports:
      - 5432:5432
    volumes:
      - ../db/postgres/data:/var/lib/postgresql/data

主.go

import (
    "database/sql"
    "log"

    "github.com/lib/pq"
)

func main() {
    dbConn, err := sql.Open("postgres", "sslmode=disable host=db port=5432 user=postgres dbname=postgres connect_timeout=30")
    if err != nil {
        log.Fatalf("error defining connection to database: %v", err)
    }
    defer func() { _ = dbConn.Close() }()

    // This forces the connection to be created
    err = dbConn.Ping()
    if err != nil {
        log.Fatalf("error opening connection to database: %v", err)
    }
    log.Println("Never get here because we timeout...")
}

我希望建立连接并到达 main.go 的结尾.相反,我收到以下错误:error opening connection to database: dial tcp <container-ip>:5432: i/o timeout

我尝试先启动 Postgres 容器 ( docker-compose up db ),以确保它已准备就绪,然后启动我的 Go 应用程序 ( docker-compose up api )。同样的错误。

我已经登录到 Postgres 容器并使用连接字符串手动连接到 Postgres:psql "sslmode=disable host=localhost port=5432 user=postgres dbname=postgres connect_timeout=30" (请注意,与上面的 host 代码中使用的连接字符串相比,只有 db 字段从 localhost 更改为 main.go )。这行得通,所以连接字符串没问题。

当登录到 Postgres 容器时,我验证了有一个名为 postgres 的数据库。我在 dbname 中使用的连接字符串中的字段:

postgres=# \l
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges   
-----------+----------+----------+------------+------------+-----------------------
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(3 rows)

我还尝试创建自己的数据库并在我的连接字符串中使用它。

main.go上面的代码,我也试过切换 sql.Open列出替代方法:

c, err := pq.NewConnector("sslmode=disable host=db port=5432 user=postgres dbname=postgres connect_timeout=30")
dbConn = sql.OpenDB(c)

如果我使用 go run main.go 运行我的应用程序(不在容器中运行)并确保切换 hostlocalhost在 Postgres 连接字符串中,它工作正常。所以,这与我的应用程序容器和 Postgres 容器之间的通信有关。

最佳答案

看看我的示例docker-compose文件(mysql,postgres是一样的)

version: '3'
services:
  application:
    image: dangminhtruong/truyencotich:v1
    container_name: truyencotich
    ports:
    - 80:8080
    depends_on:
    - mysql
    volumes:
     - .:/app
    tty: true
    restart: always
    expose:
      - 8080
  mysql:
    image: mysql:5.7
    container_name: truyencotichDB
    environment:
      MYSQL_DATABASE: rivendell
      MYSQL_USER: truyencotich
      MYSQL_PASSWORD: 789852
      MYSQL_ROOT_PASSWORD: 789852
    volumes:
      - ./database/exported/exported.sql:/docker-entrypoint-initdb.d/rivendell.sql
    expose:
    - 3306
    ports:
    - 3306:3306

然后我通过以下连接(我们现在通过主机名连接到 mysql 数据库是 mysql 容器名称 - truyencotichDB)

package database 

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)

func DBConn() (db *sql.DB) {
    dbDriver := "mysql"
    dbUser := "root"
    dbPass := "789852"
    dbName := "rivendell"
    db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"@tcp(truyencotichDB)/"+dbName)
    if err != nil {
        panic(err.Error())
    }

关于postgresql - Docker-compose Go 应用程序和 Postgres 之间的通信问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56411821/

相关文章:

go - 如何获取go语言函数的注解?

go - beego中如何指定自定义迁移表

php - [拉维尔] : SQLSTATE[3F000]: Invalid schema name

sql - 创建自定义域 postgres 数组

PostgreSQL 异常 : “An I/O error occured while sending to the backend”

postgresql - 从 Spark/pyspark 连接到 PostgreSQL

mysql - Docker、MySQL - 在 .sh 文件中找不到命令

具有多个基础镜像的 Dockerfile

json - Go结构类型的可变JSON结构映射

docker - 在桥接模式下拒绝连接到Docker主机