I'm using Docker Compose to run an Elixir/Phoenix app in development. The setup is pretty standard, with a postgres container and a web container.
However, I'm having a hard time getting the web container to talk to the database container.
Here is my web container Dockerfile
:
FROM ubuntu:14.04
MAINTAINER [email protected]
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
Here's my docker-compose.yml
:
db:
image: postgres
web:
build: .
command: mix phoenix.server
volumes:
- .:/src/blog
ports:
- "4000:4000"
links:
- db
When I run docker-compose up
, things appear to work okay. However, when I try to run (to create the database):
$ docker run blogphoenix_web mix ecto.create
I get the following error:
** (Mix) The database for Blog.Repo couldn't be created, reason given: psql: could not translate host name "db" to address: Name or service not known
Then, if I inspect the hosts file of the web container with:
$ docker run blogphoenix_web cat /etc/hosts
... I get this output:
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
Isn't Docker Compose supposed to create a hostname entry for the db
container?
Here are some relevant version numbers for my Docker tooling:
$ 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
EDIT
Okay, I just noticed something that may help someone else reading this. This command, docker run blogphoenix_web cat /etc/hosts
enters a new container, whereas this command docker exec 845f9d69cb1e cat /etc/hosts
enters a running container. 845f9d69cb1e
is the container ID for the running version of the blogphoenix_web
image.
$ 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
Running the exec
command I get the expected output from the hosts file, showing the appropriate hostname linkage for the db
container:
$ 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
In other words, when I ran the docker run blogphoenix_web mix ecto.create
command, I was executing mix ecto.create
in a new container based on the blogphoenix_web
image. This new container wasn't started with docker-compose
and thus did not have the appropriate host file linkage to the db
container setup.