4

I have a web server built using golang. It works successfully when I test it locally.

However, when I build a docker image for my web server, it can't connect to a running Postgres container.

Here is my docker-compose.yml:

version: '2'
services:
    go:
        image: golang:1.7
        volumes:
          - ./:/server/http
        ports:
            - "80:8080"
        links:
            - postgres
            - mongodb
            - redis
        environment:
            DEBUG: 'true'
            PORT: '8080'

    postgres:
        image: onjin/alpine-postgres:9.5
        restart: unless-stopped
        ports:
            - "5432:5432"
        environment:
            LC_ALL: C.UTF-8
            POSTGRES_USER: user
            POSTGRES_PASSWORD: pass
            POSTGRES_DB: mydb
    mongodb:
        image: mvertes/alpine-mongo:3.2.3
        restart: unless-stopped
        ports:
            - "27017:27017"

    redis:
        image: sickp/alpine-redis:3.2.2
        restart: unless-stopped
        ports:
            - "6379:6379"

My Dockerfile:

FROM golang:1.7

RUN mkdir -p /home/app

WORKDIR /home/app

COPY . /home/app

RUN make deps && make

ENTRYPOINT ["./bin/api-test"]

EXPOSE 8080

The Postgres connection string I am using:

postgresql://user:pass@host/mydb?sslmode=disable

For host, I tried localhost and it returns the following error:

dial tcp [::1]:5432: getsockopt: connection refused

Tried postgres and it returns the following:

dial tcp 202.71.99.194:5432: getsockopt: connection refused

Tried the IP address I get running this command which returns 172.19.0.3:

docker inspect apitest_postgres_1 | grep IPAddress

where apitest_postgres_1 is Postgres container name. It also returned this error:

dial tcp 172.19.0.3:5432: getsockopt: connection timed out

Can you please tell me what I am missing here? I am inexperienced with docker and this took a long time investigating for a solution.

Edit: I run my golang docker using this command:

docker run --env-file ./example.env --rm -it -p 8080:8080  api-test

example.env is the file contains my environment vars.

Edit 2: I changed the connection string to the following:

postgresql://user:pass@postgres:5432?sslmode=disable

It returns the following error:

dial tcp: lookup postgres on 192.168.65.1:53: no such host

I'm getting the idea that my mac is the issue here. My default DNS is 8.8.8.8 which should not be a problem.

6
  • have you tried set postgres as host in url postgresql://user:secret@postgres/mydb?sslmode=disable ? Just the same as the service name. Commented Apr 26, 2017 at 13:07
  • @Зелёный yup tried it and it returned the following error: dial tcp 202.71.99.194:5432: getsockopt: connection refused Commented Apr 26, 2017 at 13:13
  • Are you sure you allow All Connections Over TCP/IP Networks in the Postgres pg_hba.conf? Commented Apr 26, 2017 at 13:15
  • @Зелёный this is the solution! But how can I modify pg_hba.conf for a downloaded docker container? I could not run docker exec -it apitest_postgres_1 bash to change it. Commented Apr 26, 2017 at 13:51
  • You able to extend the base image and do what you wanna do. Give me some time I'll post an answer with Dockerfile. Commented Apr 26, 2017 at 13:53

4 Answers 4

5

Looks like you're pulling go image instead of building you're own image.

Instead of image: golang:1.7 replace it with build: . to build and use your Dockerfile.

Also you might need to pass postgres environment variables DB_HOST, DB_USER, DB_PASS etc. you can achieve that but creating for example docker.env file and then add env_file under your go app docker-compose.yml file:

Example docker.env :

DB_HOST=postgres
DB_USER=user
DB_PASS=pass
DB_NAME=mydb

Corrected docker-compose.yml :

version: '2'
services:
    app:
        build: .
        volumes:
          - ./:/server/http
        ports:
            - "80:8080"
        links:
            - postgres
            - mongodb
            - redis
        environment:
            DEBUG: 'true'
            PORT: '8080'
        env_file: 
          - docker.env

    postgres:
        image: onjin/alpine-postgres:9.5
        restart: unless-stopped
        ports:
            - "5432:5432"
        environment:
            LC_ALL: C.UTF-8
            POSTGRES_USER: user
            POSTGRES_PASSWORD: pass
            POSTGRES_DB: mydb

    mongodb:
        image: mvertes/alpine-mongo:3.2.3
        restart: unless-stopped
        ports:
            - "27017:27017"

    redis:
        image: sickp/alpine-redis:3.2.2
        restart: unless-stopped
        ports:
            - "6379:6379"
Sign up to request clarification or add additional context in comments.

Comments

4

In order to make a connection to postgres in docker compose becomes established, you need to replace localhost or 127.0.0.1 or postgres in your connection string with the name of the container being mentioned in your docker compose file.

For example, in your docker-compose.yaml file create database like this:

db:
    container_name: composepostgres
    image: postgres
    environment:

and then, in your code when creating your connection string, avoid using 127.0.0.1 or localhost or postgres, and instead use composepostgres in the place of them.

If not doing so, you will face with dial tcp 127.0.0.1:5432: connect: connection refused error.

Comments

2

Take a look a this documentation : https://docs.docker.com/engine/userguide/networking/default_network/configure-dns/

Then, regarding the links in you docker-compose file, replace "host" by "postgres" in you connection string :

postgresql://user:pass@postgres/mydb?sslmode=disable

Let the embedded DNS server do the mapping work because the ip address may change every time you recreate the container.

Also, ensure postgres allows connection (maybe limited to localhost)

Comments

-1

you can use docker.for.mac.localhost instead localhost or postgres ... postgresql://user:[email protected]/mydb?sslmode=disable

It worked for me but only for mac.

Comments

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.