Docker Compose 的链接似乎无法工作

4
我正在使用Docker Compose在开发中运行一个Elixir/Phoenix应用程序。设置非常标准,包括一个postgres容器和一个web容器。
然而,我很难让web容器与数据库容器通信。
这是我的web容器 Dockerfile:
FROM ubuntu:14.04
MAINTAINER me@example.com

RUN locale-gen en_US.UTF-8  
ENV LANG en_US.UTF-8  
ENV LANGUAGE en_US:en  
ENV LC_ALL en_US.UTF-8 

ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y wget
RUN apt-get install -y curl
RUN apt-get install -y inotify-tools
RUN apt-get install -y postgresql-client
RUN wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb \
    && dpkg -i erlang-solutions_1.0_all.deb
RUN curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -
RUN apt-get install -y nodejs
RUN apt-get update
RUN apt-get install -y esl-erlang 
RUN apt-get install -y elixir
RUN mix local.rebar
RUN mix local.hex --force

ADD . src/blog/
WORKDIR src/blog/

RUN mix deps.get
RUN mix deps.compile

这是我的docker-compose.yml文件:
db:
  image: postgres
web:
  build: .
  command: mix phoenix.server
  volumes:
    - .:/src/blog
  ports:
    - "4000:4000"
  links:
    - db

当我运行docker-compose up时,一切似乎都正常。但是,当我尝试运行(创建数据库)时:
$ docker run blogphoenix_web mix ecto.create

我遇到了以下错误:

** (Mix) Blog.Repo 数据库无法创建,原因是:psql: could not translate host name "db" to address: Name or service not known

如果我检查 web 容器的 hosts 文件:

$ docker run blogphoenix_web cat /etc/hosts

当我运行这段代码时,我得到了以下输出:

127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.4      a86e4f02ea56

Docker Compose不应该为db容器创建主机名条目吗?

这里是我的Docker工具的一些相关版本号:

$ docker-machine --version
#=> docker-machine version 0.6.0, build e27fb87
$ docker-compose --version
#=> docker-compose version 1.6.0, build unknown
$ docker --version
#=> Docker version 1.10.0, build 590d510

编辑

好的,我刚刚注意到了一些可能对其他人有帮助的东西。这个命令 docker run blogphoenix_web cat /etc/hosts 进入一个新的容器,而这个命令 docker exec 845f9d69cb1e cat /etc/hosts 进入一个正在运行的容器。 845f9d69cb1e 是正在运行的 blogphoenix_web 镜像的容器ID。

$ docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
845f9d69cb1e        blogphoenix_web     "mix phoenix.server"     About an hour ago   Up 2 minutes        0.0.0.0:4000->4000/tcp   blogphoenix_web_1
21a6f48dfc3b        postgres            "/docker-entrypoint.s"   About an hour ago   Up 2 minutes        5432/tcp                 blogphoenix_db_1

运行exec命令后,我可以从主机文件中获取预期的输出,显示了db容器的适当主机名链接:
$ docker exec 845f9d69cb1e cat /etc/hosts

127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      db_1 21a6f48dfc3b blogphoenix_db_1
172.17.0.2      blogphoenix_db_1 21a6f48dfc3b
172.17.0.2      db 21a6f48dfc3b blogphoenix_db_1
172.17.0.3      845f9d69cb1e

换句话说,当我运行 docker run blogphoenix_web mix ecto.create 命令时,我是在一个基于 blogphoenix_web 镜像的新容器中执行了 mix ecto.create 命令。这个新容器没有使用 docker-compose 启动,因此没有适当的主机文件链接到 db 容器设置。

1
尝试运行命令 "docker-compose run web mix ecto.create",然后您应该可以使用已链接的容器。 - TopperH
1
哇,好的,这个可行。谢谢你。但是,我以为Docker Compose会为各个容器创建主机条目,以便它们之间可以通信。如果不是这样,那么这种链接存在于哪里? - Elliot Larson
1
链接存在于容器之间,而不是镜像之间。我在下面的答案中通过示例进行了解释。 - TopperH
1个回答

4

您需要使用docker-compose运行它:

docker-compose run web mix ecto.create

Docker Compose可以创建链接的容器,但镜像本身并没有相互链接。这意味着blogphoenix_web与blogphoenix_db之间没有链接,但是当你运行以下命令时:
docker-compose up

新创建的容器 "blogphoenix_web_1" 和 "blogphoenix_db_1" 将会被链接在一起。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接