dongliu5475 2017-10-06 09:00
浏览 115
已采纳

使用docker-compose时如何从golang应用连接到Postgres?

My docker-compose file

version: "2" 
services:   db:
   restart: always
   image: postgres:latest
   ports:
     - "5435:5432"
   environment:
      POSTGRES_PASSWORD: password
      POSTGRES_USER: user
      POSTGRES_DB: db   adminer:    
   web:
      image: golang:1.7
      working_dir: /go/src/app
      command: go run bot.go
      ports:
        - "3000:3000"
      volumes:
        - ./bot:/go/src/app
      links:
        - db
      environment:
      PORT: 3000
      CONNECTION_STRING_DEV: postgres://user:password@db/db

and my bot.go, where I try connect

db, err = sql.Open("postgres", "user=user password=password host=db dbname=db port=5432 sslmode=verify-full ")

When I bring up my containers, I see errors:

panic: dial tcp 5.61.14.99:5432: getsockopt: connection refused

I changed the port on 5432 and tried connect like this:

db, err = sql.Open("postgres", "postgres://user:password@db/db")

but I get the same errors

What's wrong with my docker-compose setup?

  • 写回答

2条回答 默认 最新

  • dtk31564 2017-10-06 09:44
    关注

    Your docker-compose looks a little messy but that's probably from copy and pasting. It's likely that postgres is not yet up and running when Go tries to connect. To test if that's the problem, first:

    docker-compose up -d db
    

    Then wait until postgres is ready by checking:

    docker-compose logs -f db
    

    and look out for a log line like:

    db_1   | LOG:  database system is ready to accept connections
    

    When that line appears, quit the log command (Ctrl+C) and run your bot:

    docker-compose up web
    

    If it is now working, that was indeed your problem.

    Solution: Wait until postgres is ready. Easy ways to achieve this are:

    • sleep for an amount of time (e.g. 1 min) before running web
    • sleep inside web before connecting
    • when connecting fails, sleep for 5 seconds and retry indefinitely

    The disadvantage of these are that you don't know when postgres is ready, so you could wait too long or not long enough. A better solution is to run your bot only after a successful connection to postgres has been made.

    Example from https://docs.docker.com/compose/startup-order/:

    #!/bin/bash
    # wait-for-postgres.sh
    
    set -e
    
    host="$1"
    shift
    cmd="$@"
    
    until psql -h "$host" -U "postgres" -c '\l'; do
      >&2 echo "Postgres is unavailable - sleeping"
      sleep 1
    done
    
    >&2 echo "Postgres is up - executing command"
    exec $cmd
    

    Add this script as wait-for-postgres.sh and in you docker-compose.yml change the command for web like so:

    command: ["./wait-for-postgres.sh", "db", "go", "run", "bot.go"]
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥30 Matlab打开默认名称带有/的光谱数据
  • ¥50 easyExcel模板 动态单元格合并列
  • ¥15 res.rows如何取值使用
  • ¥15 在odoo17开发环境中,怎么实现库存管理系统,或独立模块设计与AGV小车对接?开发方面应如何设计和开发?请详细解释MES或WMS在与AGV小车对接时需完成的设计和开发
  • ¥15 CSP算法实现EEG特征提取,哪一步错了?
  • ¥15 游戏盾如何溯源服务器真实ip?需要30个字。后面的字是凑数的
  • ¥15 vue3前端取消收藏的不会引用collectId
  • ¥15 delphi7 HMAC_SHA256方式加密
  • ¥15 关于#qt#的问题:我想实现qcustomplot完成坐标轴
  • ¥15 下列c语言代码为何输出了多余的空格