Docker中使用Golang连接PostgreSQL的方法

Docker中使用Golang连接PostgreSQL的方法 我想将我的项目容器化,并在Docker容器中将我的Golang代码与PostgreSQL连接起来,但不知道具体该怎么做。我已经分别创建了独立的容器(一个用于Golang,另一个用于PostgreSQL),它们各自运行正常,但我不知道如何将它们连接起来。

3 回复

补充Johan的回答:我认为您实际上可以使用DNS来查找链接容器的IP地址……因此,如果PostgreSQL容器名为"postgres",那么在Go容器中应该能够通过DNS记录查找"postgres"。

参见https://docs.docker.com/docker-cloud/apps/service-links/#hostnames-vs-service-links

更多关于Docker中使用Golang连接PostgreSQL的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好

我真的是使用Docker的新手,但我认为应该这样做:

如果你的Go容器和Postgres容器在同一个网络中,你应该能够通过以下地址连接到Postgres容器:

容器ID 名称 IP地址

你可以通过运行以下命令获取这些信息:

$ docker ps -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS                     PORTS                               NAMES
39ff0c62c984        mysql:5.7             "docker-entrypoint.s…"   31 hours ago        Up 31 hours                0.0.0.0:3306->3306/tcp, 33060/tcp   mysql

这里是一个MySQL容器的例子,但Docker ID和名称已用粗体标出

通过检查容器连接的网络可以找到IP地址:

$ docker network inspect my-network

使用以下命令登录到你的Go容器:

$ docker exec -it my-golang-container /bin/bash

然后尝试ping上述地址之一,你就能看到是否连接成功

在Docker环境中连接Golang容器和PostgreSQL容器,需要使用Docker网络或链接机制。以下是具体实现方法:

1. 创建Docker网络

首先创建一个共享网络让容器能够通信:

docker network create myapp-network

2. 运行PostgreSQL容器

docker run -d --name postgres-container \
  --network myapp-network \
  -e POSTGRES_USER=myuser \
  -e POSTGRES_PASSWORD=mypassword \
  -e POSTGRES_DB=mydb \
  -p 5432:5432 \
  postgres:latest

3. Golang连接代码示例

package main

import (
    "database/sql"
    "fmt"
    "log"
    "time"

    _ "github.com/lib/pq"
)

const (
    host     = "postgres-container" // 使用容器名作为主机名
    port     = 5432
    user     = "myuser"
    password = "mypassword"
    dbname   = "mydb"
)

func main() {
    connStr := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
        host, port, user, password, dbname)

    var db *sql.DB
    var err error

    // 重试连接,等待PostgreSQL容器完全启动
    for i := 0; i < 10; i++ {
        db, err = sql.Open("postgres", connStr)
        if err != nil {
            log.Printf("连接失败,重试中... (%d/10)", i+1)
            time.Sleep(2 * time.Second)
            continue
        }

        err = db.Ping()
        if err == nil {
            break
        }
        time.Sleep(2 * time.Second)
    }

    if err != nil {
        log.Fatal("无法连接到数据库:", err)
    }
    defer db.Close()

    fmt.Println("成功连接到PostgreSQL!")

    // 创建测试表
    _, err = db.Exec(`
        CREATE TABLE IF NOT EXISTS users (
            id SERIAL PRIMARY KEY,
            name VARCHAR(100),
            email VARCHAR(100)
        )
    `)
    if err != nil {
        log.Fatal("创建表失败:", err)
    }

    // 插入测试数据
    _, err = db.Exec("INSERT INTO users (name, email) VALUES ($1, $2)", 
        "张三", "zhangsan@example.com")
    if err != nil {
        log.Fatal("插入数据失败:", err)
    }

    fmt.Println("数据操作完成!")
}

4. Dockerfile for Golang应用

FROM golang:1.21-alpine

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY . .

RUN go build -o main .

EXPOSE 8080

CMD ["./main"]

5. 构建和运行Golang容器

# 构建Golang镜像
docker build -t my-golang-app .

# 运行Golang容器
docker run -d --name golang-app \
  --network myapp-network \
  -p 8080:8080 \
  my-golang-app

6. 使用docker-compose的替代方案

创建docker-compose.yml文件:

version: '3.8'

services:
  postgres:
    image: postgres:latest
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword
      POSTGRES_DB: mydb
    ports:
      - "5432:5432"
    networks:
      - myapp-network

  app:
    build: .
    depends_on:
      - postgres
    ports:
      - "8080:8080"
    networks:
      - myapp-network

networks:
  myapp-network:
    driver: bridge

运行:

docker-compose up

关键点在于使用容器名称作为主机名进行连接,当容器在同一网络中时,Docker会自动进行DNS解析。确保在连接字符串中使用postgres-container而不是localhost

回到顶部