2016-03-27 5 views
4

Я занимаюсь созданием веб-приложения Golang, которое взаимодействует с базой данных PostgreSQL, каждая из которых работает в своем собственном контейнере.Как подключить контейнер веб-приложений Docker к контейнеру Docker PostgreSQL?

Я бегу контейнеры с docker-compose up

Но я, кажется, терпит неудачу на получении Postgres контейнер правильно настроить.

Для краткости ссылки на Dockerfile s и другие файлы настроек - on this gist (сообщите мне, если вы хотите это здесь).

version: '2' 
services: 
    web_app: 
    build: dockerfiles/web_app 
    ports: 
     - "9000:9000" 
    volumes: 
     - .:/go/src/gitlab.com/repo/web_app 
    # links might be replaced by depends_on. 
    # links: 
    # - db 
    depends_on: 
     - db 
    # tty and stdin_open cause docker-compose to disconnect from docker-machine after 60sec. 
    # A fix is on the way. 
    # tty: true 
    # stdin_open: true 
    db: 
    build: dockerfiles/db 
    volumes: 
     - data:/var/lib/postgresql/data 
volumes: 
    data: {} 

docker-compose up работает нормально. Но когда приложение пытается открыть подключение к базе данных с:

var pgConf string = "user=web_app dbname=web_app sslmode=verify-full password=password" 

db, err := sql.Open("postgres", pgConf) 

Я получаю следующее сообщение об ошибке из Докер композе:

Error creating new user: dial tcp [::1]:5432: getsockopt: connection refused 

Что я могу сделать, чтобы оба контейнера разговаривать друг с другом?

Заранее спасибо.

+0

Причина заключается в том, что 'depends_on' не может заменить' links'. Первый определяет порядок запуска, в то время как последний также обеспечивает доступ между контейнерами по имени. –

ответ

7

При использовании docker-compose v2 не требуется создавать связи между службами. Docker 1.9 и 1.10 позволяют вам подключаться к другим контейнерам в одной и той же (пользовательской) сети через свое имя.

Вы должны иметь возможность подключиться, используя либо имя службы или имя контейнера в качестве имени хоста. Учитывая, что имя контейнера генерируется командой docker-compose, это не очень удобно использовать, поэтому по этой причине docker-compose также добавляет псевдоним с именем службы в каждый контейнер.

Возьмите этот очень простой пример. Я использовал контейнер Nginx для удобства, но то же самое должно быть применимо к вашей ситуации;

version: '2' 
services: 
    web_app: 
    image: nginx 
    db: 
    image: nginx 

Первый запуск проекта (предполагается, что;

$ docker-compose --project-name=test up -d 
Creating network "test_default" with the default driver 
Creating test_db_1 
Creating test_web_app_1 

Затем пинг сервис "DB" внутри test_web_app_1 контейнера:

$ docker exec -it test_web_app_1 ping -c 2 db 
PING db (172.18.0.2): 56 data bytes 
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.108 ms 
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.243 ms 
--- db ping statistics --- 
2 packets transmitted, 2 packets received, 0% packet loss 
round-trip min/avg/max/stddev = 0.108/0.175/0.243/0.068 ms 

Если вы осмотрите test_db_1 контейнер, вы можете см., что сборщик докеров автоматически добавляет псевдоним «db» для контейнера test_db_1;

$ docker inspect test_db_1 

дает: (только NetworkSettings.Networks часть)

"Networks": { 
    "test_default": { 
     "IPAMConfig": null, 
     "Links": null, 
     "Aliases": [ 
      "db", 
      "002b1875e61f" 
     ], 
     "NetworkID": "0f9e2cddeca79e5a46c08294ed61dee273828607f99014f6410bda887626be70", 
     "EndpointID": "a941ab95586a8fdafc5075f9c5c44d745f974e5790ef6048b9e90115a22fb31f", 
     "Gateway": "172.18.0.1", 
     "IPAddress": "172.18.0.2", 
     "IPPrefixLen": 16, 
     "IPv6Gateway": "", 
     "GlobalIPv6Address": "", 
     "GlobalIPv6PrefixLen": 0, 
     "MacAddress": "02:42:ac:12:00:02" 
    } 
} 
+0

Благодарим вас за удивительные идеи. Из вашего ответа я меняю код подключения на строке 'user.go' 20, чтобы быть:' var pgConf string = "user = web_app dbname = web_app sslmode = verify-full password = password host = 172.18.0.2", и я получил успешный подключение. Итак, в конце концов, 'docker-compose.yaml' был хорошим.Все, что мне было нужно, это дополнительная информация, которую вы мне дали о внутреннем IP-адресе, который соединял контейнеры. – sargas

+1

Вы должны иметь возможность изменить это на 'host = db', это идея встроенного DNS в Docker и лучший подход, поскольку IP-адрес может измениться – thaJeztah