[英]Docker-compose communication issues between a Go app and Postgres
I'm trying to set up my basic Go app to make a connection to a Postgres database. 我正在尝试设置我的基本Go应用程序以建立与Postgres数据库的连接。 I have both being spun up as services using docker-compose.
我使用docker-compose作为服务进行了旋转。 When I run
docker-compose up
, I end up getting a timeout error when the Go app tries to connect to Postgres. 当我运行
docker-compose up
,当Go应用程序尝试连接到Postgres时,我最终会收到超时错误。 Something is wrong or missing that is preventing my Go app from being able to make a connection to Postgres. 有些东西是错误的或遗漏的,这阻止了我的Go应用程序能够与Postgres建立连接。
docker-compose.yml 泊坞窗,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
main.go main.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...")
}
I expect to make the connection and get to the end of main.go
. 我期望建立连接并到达
main.go
。 Instead, I get the following error: error opening connection to database: dial tcp <container-ip>:5432: i/o timeout
相反,我收到以下错误:
error opening connection to database: dial tcp <container-ip>:5432: i/o timeout
I've tried starting the Postgres container first ( docker-compose up db
), to make sure it was ready, then spinning up my Go app ( docker-compose up api
). 我已经尝试首先启动Postgres容器(
docker-compose up db
),以确保它已准备好,然后启动我的Go应用程序( docker-compose up api
)。 Same error. 同样的错误。
I've logged into the Postgres container and connected to Postgres by using the connection string, manually: psql "sslmode=disable host=localhost port=5432 user=postgres dbname=postgres connect_timeout=30"
(notice that only the host
field changed from db
to localhost
, as compared to the connection string used in the main.go
code, above). 我已经登录到Postgres容器并通过连接字符串手动连接到Postgres:
psql "sslmode=disable host=localhost port=5432 user=postgres dbname=postgres connect_timeout=30"
(注意只有host
字段从db
到localhost
,与上面main.go
代码中使用的连接字符串相比。 This works, so the connection string is fine. 这有效,所以连接字符串很好。
When logged in to the Postgres container, I've verified that there is a database named postgres
that I use in the dbname
field in the connection string: 登录到Postgres容器后,我已经验证了在连接字符串的
dbname
字段中有一个名为postgres
的数据库:
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)
I've also tried making my own database and using that in my connection string. 我也尝试创建自己的数据库并在我的连接字符串中使用它。
In the main.go
code, above, I've also tried switching the sql.Open
line out for the alternative approach: 在上面的
main.go
代码中,我也尝试将sql.Open
行sql.Open
替代方法:
c, err := pq.NewConnector("sslmode=disable host=db port=5432 user=postgres dbname=postgres connect_timeout=30")
dbConn = sql.OpenDB(c)
If I run my app with go run main.go
(not running in a container) and make sure to switch the host
to localhost
in the Postgres connection string, it works fine. 如果我使用
go run main.go
运行我的应用程序(不在容器中运行)并确保将host
切换到Postgres连接字符串中的localhost
,它可以正常工作。 So, it's something to do with the communication between my app's container and the Postgres container. 所以,这与我的应用程序容器和Postgres容器之间的通信有关。
Your docker-compose.yml misses a link to db
, ie, it should look like 你的docker-compose.yml错过了一个
db
的链接,即看起来应该是这样的
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
links:
- db
db:
image: postgres:11.3
ports:
- 5432:5432
volumes:
- ../db/postgres/data:/var/lib/postgresql/data
Take a look to my example docker-compose file (with mysql, postgres is the same way) 看看我的示例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
And then I connect by following (we connect to mysql db by host name now is mysql container name - truyencotichDB) 然后我通过以下连接(我们通过主机名连接到mysql db现在是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())
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.