0

I am having connection issues when I try to connect my goLang GORM service to a Docker Postgress container. I believe the problem is my golang code at the bottom at the connection string.

docker-compose up
Recreating postgress_postgre_1 ... done
Attaching to postgres
postgres   | 2018-12-11 21:08:48.283 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
postgres   | 2018-12-11 21:08:48.283 UTC [1] LOG:  listening on IPv6 address "::", port 5432
postgres   | 2018-12-11 21:08:48.291 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres   | 2018-12-11 21:08:48.316 UTC [20] LOG:  database system was shut down at 2018-12-11 21:08:44 UTC
postgres   | 2018-12-11 21:08:48.328 UTC [1] LOG:  database system is ready to accept connections

=== when I run the golang I get... panic: failed to connect database

=============== docker-compose.yml

version: '3.6'
services:
  postgre:
    image: postgres:11.1-alpine
    ports:
      - '5432:5432'
    network_mode: bridge
    container_name: postgres

    environment:
      POSTGRES_USER: 'user'
      POSTGRES_PASSWORD: 'password'
      POSTGRESS_DB: 'db_amex01'
    volumes:
      - ./init:/docker-entrypoint-initdb.d/

==== main.go

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/gorilla/mux"
    "github.com/jinzhu/gorm"

    // _ "github.com/jinzhu/gorm/dialects/sqlite"
    _ "github.com/jinzhu/gorm/dialects/postgres"
)

// _ "github.com/jinzhu/gorm/blob/master/dialects/postgres"

type ToDo struct {
    gorm.Model
    ID          int    `json:"id"`
    TASK_STRING string `json:"task_string"`
    DONE        bool   `json:"done"`
}

var db *gorm.DB
var err error

func main() {
    const (
        host     = "localhost"
        port     = 5432
        user     = "postgres"
        password = "password"
        dbname   = "db_amex01"
    )


// this is the problem I believe I am having...

    db, err := gorm.Open("postgres", "host='postgres' port=5432 user=user dbname='db_amex01' password='password'")



    defer db.Close()

    if err != nil {
        panic("failed to connect database")
    }

    defer db.Close()
1
  • Do you run you go program outside docker? Did you try to changing the host from postgres to localhost or postgre? What system you are using? Commented Dec 11, 2018 at 21:51

2 Answers 2

3

There's a typo in your compose file, you name the service postgre but connect to postgres. Docker uses the service name for the DNS alias on a shared network, so this will break your connection attempt. To fix, just rename your service:

version: '3.6'
services:
  postgres:
    image: postgres:11.1-alpine
    ports:
      - '5432:5432'
    environment:
      POSTGRES_USER: 'user'
      POSTGRES_PASSWORD: 'password'
      POSTGRESS_DB: 'db_amex01'
    volumes:
      - ./init:/docker-entrypoint-initdb.d/
Sign up to request clarification or add additional context in comments.

Comments

3

It appears as though you're discarding the error returned from gorm.Open(). To know exactly why gorm failed to open the connection, you'd need to output the error.

Instead of:

panic("failed to connect database")

Use:

panic("failed to connect database: " + err)

At a glance, it could be that your host is misconfigured

host='postgres' port=5432 user=user dbname='db_amex01' password='password'

Should be:

host=localhost port=5432 user=user dbname=db_amex01 password=password

But it's hard to tell without the error from gorm.Open()

One other thing to note, too; don't call db.Close() before first checking the error. It's possible that in the case of an error, db may be nil, causing calls to any of db's methods to panic. You're also calling db.Close() twice in the code snippet you posted. Don't do this. Golang's documentation on io.Closer:

Closer is the interface that wraps the basic Close method.

The behavior of Close after the first call is undefined. Specific implementations may document their own behavior.

Edit (12/12/2018):

When I ran your code locally, the error I got from gorm was regarding SSL, because you're running your postgres server via docker-compose without any SSL configuration. You can add the sslmode=disable flag to your connection string to fix this issue.

Also there's a typo in your docker-compose.yml: POSTGRESS_DB should be POSTGRES_DB.

Here's a full working example that I got running locally:

docker-compose.yml:

version: '3.6'
services:
  postgres:
    image: postgres:11.1-alpine
    ports:
      - '5432:5432'
    environment:
      POSTGRES_USER: 'test_user'
      POSTGRES_PASSWORD: 'test_password'
      POSTGRES_DB: 'test_database'
    volumes:
      - ./init:/docker-entrypoint-initdb.d/

main.go:

package main

import (
    "fmt"
    "log"

    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/postgres"
)

const (
    host     = "localhost"
    port     = "5432"
    user     = "test_user"
    password = "test_password"
    dbname   = "test_database"
)

func main() {
    url := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable",
        user,
        password,
        host,
        port,
        dbname,
    )

    db, err := gorm.Open("postgres", url)
    if err != nil {
        log.Fatalf("error connecting to database: %v", err)
    }
    defer db.Close()

    if err := db.DB().Ping(); err != nil {
        log.Fatalf("error pinging database: %v", err)
    }

    fmt.Println("Success!")
}

3 Comments

In a Docker context localhost is almost always wrong. You probably want postgre, the name of the other server block in the docker-compose.yml file; it will be resolvable as a host name to a private IP address for the other container.
I was using local host when I was trying to make connection from outside of the docker container. I have tried a lot of combinations and updated my github page with the latest code... and description of issue. I also include the connection error.
@IrishGringo I've updated my answer to include the correct solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.