我正在尝试设置我的基本 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
运行我的应用程序(不在容器中运行)并确保切换 host
至 localhost
在 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/