cockroachdb

Using Golang with Gin, pgxpool and issue when connecting from docker container


I have a written a simple golang CRUD example connecting to cockroachdb using pgxpool/pgx. All the CRUD operations are exposed as REST api using Gin framework. By using curl command or Postman, the operations (GET/POST/DELETE) are working good and the data reflect in the database. Next I dockerized this simple app and trying to run. The application seems to get struck in the below code

func Connection(conn_string string) gin.HandlerFunc {
  log.Println("Connection: 0", conn_string)
  config, err := pgxpool.ParseConfig(conn_string)
  log.Println("Connection: 1", config.ConnString())
  if err != nil {
      log.Fatal(err)
  }
  log.Println("Connection: 2")
  pool, err := pgxpool.ConnectConfig(context.Background(), config) // gets struck here
  if err != nil {
      log.Fatal(err)
  }
  log.Println("Connection: 3")
  return func(c *gin.Context) {
      c.Set("pool", pool)
      c.Next()
  }
}

The code seems to get frozen after printing Connection: 2 at the line pool, err := pgxpool.ConnectConfig(context.Background(), config)

After few minutes, I am getting a error FATA[0120] failed to connect to host=192.165.xx.xxx user=user_name database=dbname`: dial error (timeout: dial tcp 192.165.xx.xxx:5432: i/o timeout).

Below is my docker file

FROM golang as builder
WORKDIR /catalog
COPY main.go ./
COPY go.mod ./
COPY go.sum ./
RUN go get .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o catalog .

# deployment image
FROM scratch
#FROM alpine:3.17.1
# copy ca-certificates from builder
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
WORKDIR /bin/
COPY --from=builder /catalog .
CMD [ "./catalog" ]
#CMD go run /catalog/main.go
EXPOSE 8080

Note, I tried getting into the container bash shell and could ping the target ip 192.165.xx.xxx.

Please let me know why the pgxpool fails to connect to DB in the docker container but work in host (ubuntu) without any issue.


Solution

  • Update-2 : The real issue is passing the arguments while starting the application. When the arguments are passed correctly, this is started working.

    Update-1: I still see issues while running the query and could produce it outside the docker as well.

    I could fix it with upgraded pgxpool v5 instead of v4. All I did is go get -u github.com/jackc/pgx/v5/pgxpool, used it in the code as well and it worked as expected. This could be a known bug but could not find any related issue to include it in this post. Below is the final code that is working

    func Connection(conn_string string) gin.HandlerFunc {
        log.Println("Connection: 0", conn_string)
        config, err := pgxpool.ParseConfig(conn_string)
        log.Println("Connection: 1", config.ConnString())
        if err != nil {
            log.Fatal(err)
        }
        log.Println("Connection: 2")
        //pool, err := pgxpool.ConnectConfig(context.Background(), config)
        pool, err := pgxpool.NewWithConfig(context.Background(), config)
        if err != nil {
            log.Fatal(err)
        }
        log.Println("Connection: 3")
        return func(c *gin.Context) {
            c.Set("pool", pool)
            c.Next()
        }
    }