使用Go与Docker部署时无法连接PostgreSQL数据库的问题
问题:Go模块无法连接Docker中的PostgreSQL数据库
尝试构建包含Go模块和PostgreSQL的Docker容器,但Go模块无法连接到PostgreSQL,相关配置与报错如下:
.env 文件配置
HOST=0.0.0.0 SERVER_PORT=3000 DB_USER=postgres DB_PASSWORD=12345 DB_NAME=unity DB_PORT=5432
docker-compose.yaml 配置
version: "3.8" services: scraper: build: . restart: unless-stopped depends_on: postgres: condition: service_healthy env_file: - .env ports: - "${SERVER_PORT}:${SERVER_PORT}" volumes: - .:/usr/src/app command: go run cmd/main.go air: image: cosmtrek/air:latest working_dir: /usr/src/app ports: - 3001:3001 environment: - ENV_A=${ENV_A} - ENV_B=${ENV_B} - ENV_C=${ENV_C} volumes: - .:/usr/src/app postgres: image: postgres:latest restart: unless-stopped environment: - POSTGRES_USER=${DB_USER} - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_DB=${DB_NAME} ports: - "${DB_PORT}:${DB_PORT}" volumes: - postgres_db:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -d ${DB_NAME} -U ${DB_USER}"] interval: 3s timeout: 3s retries: 5 volumes: postgres_db:
database.go 连接代码
package databases import ( "fmt" "log" "os" "github.com/DespairServices/despair-services-scrapper/internal/models" "gorm.io/driver/postgres" "gorm.io/gorm" "gorm.io/gorm/logger" ) var db *gorm.DB var dsn string = fmt.Sprintf( "host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Shanghai", os.Getenv("HOST"), os.Getenv("DB_USER"), os.Getenv("DB_PASSWORD"), os.Getenv("DB_NAME"), os.Getenv("DB_PORT"), ) func Connect() { db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{ Logger: logger.Default.LogMode(logger.Info), }) if err != nil { log.Fatal("Failed to connect to database. \n", err) os.Exit(2) } log.Println("Database Connected!") log.Println("Running Migrations...") db.AutoMigrate(&models.Asset{}) log.Println("Migrations Done!") }
PostgreSQL就绪日志
2024-04-05 21:03:27 2024-04-06 01:03:27.074 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 2024-04-05 21:03:27 2024-04-06 01:03:27.074 UTC [1] LOG: listening on IPv6 address "::", port 5432 2024-04-05 21:03:27 2024-04-06 01:03:27.083 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" 2024-04-05 21:03:27 2024-04-06 01:03:27.093 UTC [29] LOG: database system was shut down at 2024-04-06 01:00:11 UTC 2024-04-05 21:03:27 2024-04-06 01:03:27.103 UTC [1] LOG: database system is ready to accept connections
Go模块连接报错
2024-04-05 21:04:48 2024/04/06 01:04:48 /usr/src/app/internal/databases/database.go:26 2024-04-05 21:04:48 [error] failed to initialize database, got error failed to connect to `host=0.0.0.0 user=postgres database=unity`: dial error (dial tcp 0.0.0.0:5432: connect: connection refused)
解决方案
核心问题是Docker容器间的网络寻址方式错误:在Docker Compose创建的默认网络中,容器需要通过服务名称互相访问,而不是0.0.0.0。0.0.0.0表示容器自身监听所有接口,但不是其他容器用来连接的地址。
具体修改步骤:
修改.env文件中的HOST值:
将.env里的HOST=0.0.0.0改为HOST=postgres(对应docker-compose中PostgreSQL服务的名称):HOST=postgres SERVER_PORT=3000 DB_USER=postgres DB_PASSWORD=12345 DB_NAME=unity DB_PORT=5432或者在docker-compose中覆盖环境变量:
如果不想修改.env文件,可以在scraper服务的environment中添加HOST=postgres,覆盖.env的值:scraper: build: . restart: unless-stopped depends_on: postgres: condition: service_healthy env_file: - .env environment: - HOST=postgres # 新增这一行,覆盖.env中的HOST ports: - "${SERVER_PORT}:${SERVER_PORT}" volumes: - .:/usr/src/app command: go run cmd/main.go验证修改效果:
重新启动容器:docker-compose down && docker-compose up --build此时Go模块会通过服务名
postgres访问PostgreSQL容器,Docker的DNS服务会自动解析到对应的容器IP,连接即可成功。
内容的提问来源于stack exchange,提问作者Dennis Solomon
相关产品推荐
相关产品推荐

