Невозможно подключиться к хосту db в контейнерах докера от api-сервиса к db-сервису, чтобы выполнить миграцию с помощью goose in golang - PullRequest
0 голосов
/ 06 апреля 2019

goose - это инструмент миграции, который помогает мне запускать все файлы * sql и выполнять запросы в базе данных.Я хочу автоматизировать миграцию (создавать таблицы и прочее) с помощью этого инструмента в контейнере Docker моей службы API.Проблема в том, что когда docker запускает команду "goose run", он выдает ошибку: -goose run: dial tcp: lookup db на 192.168.63.6:53: такого хоста нет.

docker-compose

services:
  db:
    build: ./db
    volumes:
      - ./db/pgdata:/pgdata
    image: postgres
    ports:
      - "5432"
    restart: always
    environment:
      - POSTGRES_USER=user
      - POSTGRES_DB=dbname
      - POSTGRES_PASSWORD=123
      - PGDATA=/pgdata

  api:
    build:
      context: ./api
    restart: always
    volumes:
      - ./api:/go/src/github.com/gitlees/todoapp/api
    ports:
      - "5000:8080"
    links: 
      - "db"

Api Dockerfile

RUN go get -u github.com/pressly/goose/cmd/goose

RUN goose postgres "host=db user=user dbname=dbname sslmode=disable password=123" up

Ответы [ 2 ]

0 голосов
/ 06 апреля 2019

Прежде всего, давайте более подробно рассмотрим Dockerfile.Для этого вопроса я также настроил репозиторий для демо-целей. .

# We use a so called two stage build.
# Basically this means we build our go binary in one image
# which has the go compiler and all the required tools and libraries.
# However, since we do not need those in our production image,
# we copy the binary created into a basic alpine image
# resulting in a much smaller image for production.

# We define our image for the build environment...
FROM golang:1.11-alpine3.8 as build

# ...and copy our project directory tp the according place.
COPY . "/go/src/github.com/mwmahlberg/so-postgres-compose"
# We set our work directory...
WORKDIR /go/src/github.com/mwmahlberg/so-postgres-compose
# ...and add git, which - forever reason, is not included into the golang image.
RUN apk add git

# We set up our dependency management and make sure all dependencies outside
# the standard library are installed.
RUN set -x && \
    go get github.com/golang/dep/cmd/dep && \
    dep ensure -v
# Finally, we build our binary and name it accordingly    
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /apiserver

# Now for the second stage, we use a basic alpine image...
FROM alpine:3.8
# ... update it...
RUN apk --no-cache upgrade
# .. and take the binary from the image we build above.
# Note the location: [/usr]{/bin:/sbin} are reserved for
# the OS's package manager. Binaries added to an OS by
# the administrator which are not part of the OS's package
# mangement system should always go below /usr/local/{bin,sbin}
COPY --from=build /apiserver /usr/local/bin/apiserver
# Last but not least, we tell docker which binary to execute.
ENTRYPOINT ["/usr/local/bin/apiserver"]

Последняя строка должна действительно выполнять трюк: ENTRYPOINT указывает команду, которая будет выполнена, когдаКонтейнер запущен.Аргументы прилагаются к этой команде.Таким образом, чтобы добавить строку подключения, вы можете сделать следующее:

api:
  build: .
  restart: always
  command: "host=db user=user dbname=dbname sslmode=disable password=123"
  ports:
    - 8080:8080
  links:
    - db

Последнее, что вы должны сделать, - это иметь статическую конфигурацию для образа докера, как показано в вашем примере.Вы в основном устанавливаете статическую строку соединения, которая лишает вас большей гибкости при использовании контейнеров.

Однако, imho, это плохая практика - использовать флаги командной строки для настройки контейнеров, в первую очередь.Гораздо более гибкий способ - использовать переменные окружения.Например, в kubernetes вы бы использовали карту конфигурации для настройки переменных среды, которые, в свою очередь, настраивают модуль.Однако переменные окружения также могут использоваться с docker-compose или docker swarm.

Следовательно, я бы изменил docker-compose.yml на что-то вроде этого:

version: '3'
services:
  db:
    volumes:
      - ./db/pgdata:/pgdata
    image: postgres
    ports:
      - "5432"
    restart: always
    environment:
      - POSTGRES_USER=user
      - POSTGRES_DB=dbname
      - POSTGRES_PASSWORD=123
      - PGDATA=/pgdata

  # adminer added for convenience
  adminer:
    image: adminer
    restart: always
    ports:
      - 8081:8080
    depends_on:
      - db

  api:
    build: .
    restart: always
    ports:
      - 8080:8080
    depends_on:
      - db
    environment:
      - POSTGRES_USER=user
      - POSTGRES_DB=dbname
      - POSTGRES_PASSWORD=123
      - POSTGRES_HOST=db
      - POSTGRES_PORT=5432    

и использовал бы средуПеременные для настройки двоичного файла.

Я добавил простой пример использования переменных среды в Go для репозитория.Обратите внимание, что такие проекты, как https://github.com/spf13/cobra/cobra или https://gopkg.in/alecthomas/kingpin.v2, значительно упрощают работу с переменными среды, поскольку они обеспечивают автоматическое преобразование типов, возможность легко устанавливать значения по умолчанию и многое другое.

Что касается более глубоких рассуждений о том, почему использовать переменные среды, вы можете прочитать часть 3 методологии 12-факторного приложения .

hth

0 голосов
/ 06 апреля 2019

Команды RUN выполняются на этапе сборки.На этом этапе еще нет контейнера.

Команды, предназначенные для подключения к другим контейнерам, должны быть определены в CMD или ENTRYPOINT в Dockerfile.

...