Postgresql Docker撰写Go应用程序和Postgres之间的通信问题
我正在尝试设置我的基本Go应用程序,以连接到Postgres数据库。我已经使用docker compose将这两个组件都拆分为服务。当我运行Postgresql Docker撰写Go应用程序和Postgres之间的通信问题,postgresql,docker,go,docker-compose,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:
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
梅因,加油
导入(
“数据库/sql”
“日志”
“github.com/lib/pq”
)
func main(){
dbConn,err:=sql.Open(“postgres”,“sslmode=disable host=db port=5432 user=postgres dbname=postgres connect\u timeout=30”)
如果错误!=零{
log.Fatalf(“定义到数据库的连接时出错:%v”,错误)
}
defer func(){{uu=dbConn.Close()}()
//这将强制创建连接
err=dbConn.Ping()
如果错误!=零{
log.Fatalf(“打开到数据库的连接时出错:%v”,错误)
}
Println(“永远不要到这里,因为我们超时了…”)
}
我希望建立连接并到达main.go
的末尾。相反,我得到了以下错误:打开到数据库的连接时出错:拨号tcp:5432:I/o超时
我尝试先启动Postgres容器(docker compose up db
),以确保它已准备就绪,然后启动我的Go应用程序(docker compose up api
)。同样的错误
我已登录到Postgres容器并使用连接字符串手动连接到Postgres:psql“sslmode=disable host=localhost port=5432 user=Postgres dbname=Postgres connect\u timeout=30”
(请注意,与上面的main.go
代码中使用的连接字符串相比,只有host
字段从db
更改为localhost
)。这是有效的,因此连接字符串是正确的
登录到Postgres容器时,我已验证连接字符串中的dbname
字段中是否存在名为Postgres
的数据库:
postgres=#\l
数据库清单
姓名|所有者|编码|校对| Ctype |访问权限
-----------+----------+----------+------------+------------+-----------------------
博士后|博士后| UTF8 | en|u US.UTF8 | en|u US.UTF8 |
模板0 | postgres | UTF8 | en|u US.UTF8 | en|u US.UTF8 |=c/postgres+
|| | | | postgres=CTc/postgres
模板1 | postgres | UTF8 | en|u US.UTF8 | en|u US.UTF8 |=c/postgres+
|| | | | postgres=CTc/postgres
(3排)
我还尝试创建自己的数据库,并在连接字符串中使用它
在上面的main.go
code中,我还尝试了切换sql.Open
行以获得替代方法:
c,err:=pq.NewConnector(“sslmode=disable host=db port=5432 user=postgres dbname=postgres connect\u timeout=30”)
dbConn=sql.OpenDB(c)
如果我使用
运行我的应用程序,请运行main.go
(不在容器中运行)并确保在Postgres连接字符串中将主机
切换到本地主机
,它工作正常。因此,这与我的应用程序容器和Postgres容器之间的通信有关。您的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
看看我的示例docker compose文件(对于mysql,postgres也是如此) 然后我通过以下方式连接(我们通过主机名连接到mysql数据库,现在是mysql容器名-truyencotichDB)
尝试为数据库添加密码fotr superuser。作为
POSTGRES\u password
的文档说明PostgreSQL映像在本地设置信任身份验证,因此您可能会注意到从本地主机(在同一容器内)连接时不需要密码。但是,如果从不同的主机/容器连接,则需要密码
非常感谢!这很有效。但是,()看起来链接
功能已被弃用。您不知道如何使用“用户定义网络”设置此功能Docker推荐的功能,是吗?太好了!从这里有三件事修复了我的Docker-compose.yml.1)我没有指定正确的版本,以指示撰写文件版本(3.4)2)我在api
服务中添加了依赖
字段,让它等待db
启动,首先3)我为db
服务公开端口5432添加了一个expose
字段,以便api
服务访问谢谢!!:)
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
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())
}