Gorm应用程序在Mac上无法连接到运行在Docker容器中的PostgreSQL,忽略了DSN。

huangapple go评论76阅读模式
英文:

Gorm application fails to connect to PostgreSQL in docker container on Mac, ignores DSN

问题

我尝试创建一个简单的Go REST API。我使用Gorm库来处理数据库,但它无法连接到容器中的数据库。我觉得这可能是Docker在Apple Silicon上的问题,但不确定。我有另一个项目,基本上使用相同的设置,但数据库连接没有任何问题。

基本上,连接参数在运行时似乎完全改变,忽略了DSN字符串。

这是docker-compose.yml文件的内容:

version: '3'

services:
  db:
    image: 'postgres:latest'
    container_name: bazos-watcher-db
    ports:
      - '5420:5432'
    volumes:
      - dbdata:/var/lib/postgresql/data
      - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
    env_file:
      - 'docker.env'
    restart: always

volumes:
  dbdata:

这是进行数据库连接的部分:

dsn := "bazos:kokos@tcp(localhost:5420)/bazos?charset=utf8mb4&parseTime=True&loc=Local"

dbOpen, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})

DSN参数与docker.env中配置的参数相匹配。pgAdmin在建立连接时没有问题。

这是我得到的错误,连接参数似乎因某种原因完全改变:

[error] failed to initialize database, got error failed to connect to `host=/private/tmp user=tassilo database=`: dial error (dial unix /private/tmp/.s.PGSQL.5432: connect: no such file or directory)
2023/03/15 17:20:59 failed to connect to `host=/private/tmp user=tassilo database=`: dial error (dial unix /private/tmp/.s.PGSQL.5432: connect: no such file or directory)
exit status 1

我尝试更改DSN字符串的最后部分,并删除并重新创建容器,但仍然没有成功。

英文:

I tried creating a simple go rest api. I use the Gorm library for DB handling, but it fails connecting to the DB in the container. I feel like this could be an issue of Docker on Apple silicon, but not sure. I have another project, which uses basically the same setup, but there's no problem with DB connections at all.

Basically the connection parameters seem to change completely at runtime ignoring the DSN string

Here's the docker-compose.yml:

version: '3'

services:
  db:
    image: 'postgres:latest'
    container_name: bazos-watcher-db
    ports:
      - '5420:5432'
    volumes:
      - dbdata:/var/lib/postgresql/data
      - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
    env_file:
      - 'docker.env'
    restart: always

volumes:
  dbdata:

Here's the part that does the DB connection:

dsn := "bazos:kokos@tcp(localhost:5420)/bazos?charset=utf8mb4&parseTime=True&loc=Local"

dbOpen, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})

The DSN parameters match those configured in docker.env. pgAdmin has no problem making a connection.

Here's the error I get, the connection parameters seem change completely for some reason:

[error] failed to initialize database, got error failed to connect to `host=/private/tmp user=tassilo database=`: dial error (dial unix /private/tmp/.s.PGSQL.5432: connect: no such file or directory)
2023/03/15 17:20:59 failed to connect to `host=/private/tmp user=tassilo database=`: dial error (dial unix /private/tmp/.s.PGSQL.5432: connect: no such file or directory)
exit status 1

I have tried changing the last part of the DSN string and deleting and recreating the container but still no success.

答案1

得分: 0

我相信你的问题出在@tcp(localhost:5420)上 - 在Docker中,你的数据库服务被指定为db,所以你的dsn应该是@tcp(db)。你可能还需要在docker compose中指定本地驱动程序:

volumes:
  dbdata:
    driver: local
英文:

I believe your problem is with @tcp(localhost:5420) - in Docker, your database service is specified as db and so your dsn should be @tcp(db). You may also need to specify the local driver in your docker compose:

volumes:
  dbdata:
    driver: local

答案2

得分: 0

我天真地以为 DSN 字符串的格式与 MySQL 的格式相同。实际上,它应该像这样:

dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"
英文:

I naively assumed the format for DSN string is the same as for MySQL. Instead it should look like this:

dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"

答案3

得分: 0

  1. 首先关闭正在运行的数据库服务

docker-compose down db

  1. 使用以下参数更新compose文件中的network_mode参数
    version: '3'
    
    services:
      db:
        image: 'postgres:latest'
        container_name: bazos-watcher-db
        network_mode: "host"
        ports:
          - '5420:5432'
        volumes:
          - dbdata:/var/lib/postgresql/data
          - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
        env_file:
          - 'docker.env'
        restart: always
    
    volumes:
      dbdata:
  1. 使用-d选项以分离模式运行您的数据库服务

docker-compose up db -d

  1. 使用以下内容更新您的dsn字符串(不要忘记填入您的数据库密码)
    dsn := "host=localhost user=bazos password=<YOUR PASSWORD> dbname=bazos port=5420 sslmode=disable"

    dbOpen, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})

希望这样能够正常工作。

英文:
  1. first shutdown running database service

docker-compose down db

  1. Update the compose file with network_mode parameter as below
    version: &#39;3&#39;
    
    services:
      db:
        image: &#39;postgres:latest&#39;
        container_name: bazos-watcher-db
        network_mode: &quot;host&quot;
        ports:
          - &#39;5420:5432&#39;
        volumes:
          - dbdata:/var/lib/postgresql/data
          - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
        env_file:
          - &#39;docker.env&#39;
        restart: always
    
    volumes:
      dbdata:
  1. Run your db service in detached mode with -d option

docker-compose up db -d

  1. update your dsn string with below ( do not forget to put your db password )
    dsn := &quot;host=localhost user=bazos password=&lt;YOUR PASSWORD&gt; dbname=bazos port=5420 sslmode=disable&quot;

    dbOpen, err := gorm.Open(postgres.Open(dsn), &amp;gorm.Config{})

I hope it would work.

huangapple
  • 本文由 发表于 2023年3月16日 00:54:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/75747818.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定