1
votes

So I'm building an Elixir/Phoenix application and I've got the following docker-compose service:

dev:
    extends:
      service: common
    environment:
      POSTGRES_HOST: "postgres.dev"
      MIX_ENV: dev
    ports:
      - "4000:4000"
    depends_on:
      - postgres
    command: >
      bash -c '
      cd $$APP_HOME \
      && mix ecto.create \
      && mix ecto.migrate \
      && iex -S mix phx.server'

and this effectively runs the app on 0.0.0.0:4000:

Erlang/OTP 20 [erts-9.1.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

[info] Running MyApp.Endpoint with Cowboy using http://0.0.0.0:4000

Checking with docker ps the ports are not exposed:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
7a1d80cf0511        app_dev         "bash -c ' cd $APP..."   4 minutes ago       Up 4 minutes                                 app_dev_run_2
ef7bed51cf24        postgres:10.0       "docker-entrypoint..."   16 minutes ago      Up 16 minutes       0.0.0.0:5432->5432/tcp   app_postgres_1

While the Postgres service has the exposed port and I effectively can connect to it via a GUI:

postgres:
    image: postgres:10.0
    ports:
      - "5432:5432"
    networks:
      default:
        aliases:
          - postgres.dev
    restart: always

I don't understand why the dev service does not expose the ports when they're the exact same command/definitions but using 4000 instead of 5432.

I've tried stopping, deleting all containers, networks and images but this still persists.

I don't have any EXPOSE commands in my Dockerfile and I'm running the service with docker-compose run dev.

Any help?

1
You just said it, you are not exposing any PORTS so therefore, your container doesn't talk to the outside world. Try exposing a port in your dockerfile and then use it in your docker-compose file and see what happens - Sergiu
I thought EXPOSE is just meant to open ports between containers? As per the docs: The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published. To actually publish the port when running the container, use the -p flag on docker run to publish and map one or more ports, or the -P flag to publish all exposed ports and map them to to high-order ports. - Sasha Fonseca
EXPOSING a port means opening that port on your host, so for example I have an NGINX container which listens on port 443, therefore in my docker file I will have something like EXPOSE 443 and then when I run my container, i will run it as docker run -p 1234:443 sergiu/nginx, which allow me to connect to 1234 OUTSIDE and 443 INSIDE the container - Sergiu
Like in your example postgres is exposing 5432 :) - Sergiu
Thank you for your comment. EXPOSE 4000 resulted in CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5806f4c39387 app_dev "bash -c ' cd $APP..." About a minute ago Up About a minute 4000/tcp app_dev_run_1 But the port still isn't exposed to the host. To actually expose it (i.e., obtain 0.0.0.0:4000->4000/tcp in docker ps) I can do it running docker run -p 4000:4000 app_dev but I'd like to obtain the same behaviour with a docker-compose service - Sasha Fonseca

1 Answers

3
votes

So I finally solved this, I just had to pass the --service-ports in docker run:

https://docs.docker.com/compose/reference/run/