Как подключить контейнер веб-приложения Docker к контейнеру Docker PostgreSQL?

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

Я запускаю контейнеры с docker-compose up

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

Для краткости ссылки на Dockerfiles и другие файлы настроек находятся в этой сути (дайте мне знать, если вы хотите здесь вместо этого).

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)

Я получаю следующую ошибку от docker compose:

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

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

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

1 ответ

Решение

При использовании 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 Контейнер, вы можете видеть, что docker-compose автоматически добавил псевдоним "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"
    }
}
Другие вопросы по тегам