Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot get connection between containers

I have included the code here.. https://github.com/vinceyoumans/achal

PROBLEM: Two containers in a docker compose file. one is standard Postgress container. The second is a goLang Scratch container. The GoLang main.go file panics when the postgres connection fails. you can see the code on github.

The error is:

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

REQUEST: look over the main.go and dockercompose file to see what is wrong with this network.. what I am missing.

main.go

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

if err != nil {
    fmt.Println("============   exiting ==========")
    fmt.Println(err)
    panic("failed to connect database e")
    //  the error i get... dial tcp: lookup postgres on 127.0.0.11:53: no such host
    // panic("failed to connect database: " + err)
}

The 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/

  todo:
    build: ./go_amex/
    # ports:
    #   - "8000:8080"

# sudo docker-compose -f docker-compose.yml up

#  HELP:  how would I add the goLang service from this point?
like image 635
IrishGringo Avatar asked Dec 12 '18 04:12

IrishGringo


People also ask

Can 2 containers communicate with each other?

If you are running more than one container, you can let your containers communicate with each other by attaching them to the same network. Docker creates virtual networks which let your containers talk to each other. In a network, a container has an IP address, and optionally a hostname.

Why is it difficult for Docker containers to communicate with each other?

Containers can only communicate with each other if they share a network. Containers that don't share a network cannot communicate with one another. That's one of the isolation features provided by Docker. A container can belong to more than one network, and a network can have multiple containers inside.


2 Answers

You have a typo in your compose file. A DNS alias is automatically configured for the service name, and a default docker network is also created for your project. So all that should be needed is to connect to the service name, which in your case was "postgre" instead of "postgres". To fix that, try this compose file:

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/

  todo:
    build: ./go_amex/
    # ports:
    #   - "8000:8080"

For more details on compose file networking, see: https://docs.docker.com/compose/networking/

Note that the next error you will likely see is a connection refused. Compose will start both containers simultaneously, and your application will likely be running before the database finishes starting. To solve that, you will want a retry loop with a short delay between retries, and a timeout or retry limit, in your application code.

like image 143
BMitch Avatar answered Sep 19 '22 13:09

BMitch


You're missing the networking configuration. This is required if you want to communicate between containers.

version: '3.6'
services:
  postgres: # you were missing the 's'
    image: postgres:11.1-alpine
    ports:
      - '5432:5432'
    networks:
      - mynet

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

  todo:
    build: ./go_amex/
    ports:
      - "8000:8000" # I looked at your main.go file, it's port 8000!
    networks:
      - mynet

networks:
  mynet:
    driver: bridge

Now you can see (via dns resolution) each service from within the containers by using the service name as the hostname.

like image 29
yomateo Avatar answered Sep 20 '22 13:09

yomateo