postgresql - Go 应用程序和 Postgres 之间的 Docker-compose 通信问题
问题描述
我正在尝试设置我的基本 Go 应用程序以连接到 Postgres 数据库。我都使用 docker-compose 作为服务启动。当我运行docker-compose up
时,当 Go 应用程序尝试连接到 Postgres 时,我最终会收到超时错误。某些错误或缺失导致我的 Go 应用程序无法连接到 Postgres。
码头工人-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
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
并确保在 Postgres 连接字符串中切换host
到,它可以正常工作。localhost
因此,这与我的应用程序容器和 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 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())
}
推荐阅读
- ios - 切换到其他页面时,选中的单元格被取消选中
- memory - 内核内存是否可分页?
- android - 如何检查 JSON 变量是否存在
- odata - 将 MultiComboBox 的 selectedItems 绑定到 OData 导航属性
- magento2 - 如何确定要在 Magento2 中编辑的正确文件和块?
- javascript - 导出上下文不适用于 contextType
- r - 使用 R 的两列 X 和 Y 之间的唯一关系
- python - 如何处理 sci-kit 学习模型中不断变化的基数
- sql - JOIN 4 个表,如何将 SELECT 列限制为一个表?
- python - PySpark Builder 类与 builder 方法