无法从api服务连接到docker容器中的db主机到db服务以便使用golang中的goose进行迁移

时间:2019-04-06 08:23:25

标签: docker go docker-compose

goose是一种迁移工具,可以帮助我运行所有* sql文件并在数据库中运行查询。我想在我的api服务上的docker容器内使用此工具自动进行迁移(创建表和填充物)。问题是,当docker运行命令“ goose run”时,它得到一个错误-goose run:拨号tcp:在192.168.63.6:53上查找db:没有这样的主机。

docker-compose

JTable

Api Dockerfile

int modelRow = table.convertRowIndexToModel(table.getSelectedRow());
int value = (Integer)table.getModel().getValueAt(modelRow,0);

2 个答案:

答案 0 :(得分:0)

RUN命令在构建阶段执行。在此阶段,还没有容器。

用于连接到其他容器的命令应在Dockerfile中的CMD或ENTRYPOINT中定义。

答案 1 :(得分:0)

首先,让我们更深入地研究Dockerfile。我也设置了repository for demo purposes for this question

# 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

您应该做的最后一件事是为Docker映像进行静态配置,如您的示例所示。基本上,您设置了一个静态连接字符串,这使您在使用容器时失去了很多灵活性。

但是,恕我直言,使用命令行标志来配置容器是个坏习惯。一种更灵活的方法是使用环境变量。例如,在kubernetes中,您将use a config map设置环境变量,这些环境变量又配置了pod。但是,环境变量也可以与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    

并使用环境变量配置二进制文件。

我在仓库中添加了simple example how to use environment variables in Go。请注意,https://github.com/spf13/cobra/cobrahttps://gopkg.in/alecthomas/kingpin.v2之类的项目使环境变量的使用变得更加容易,因为它们提供了自动类型转换,易于设置默认值的功能等等。

关于使用环境变量的更深入的推理,您可能需要阅读part 3 of the 12 factor app methodology

hth