ruby-on-railsdockerdocker-composedockerfile

Unable to make requests to server within container from host machine when starting container with docker-compose


I can successfully do this task without docker-compose, but I want to leverage docker-compose for a bit more simplicity.

Without docker-compose (which works as expected)

My app has a Dockerfile. From the root of my app I run this command:

docker build -t some_app . && docker run -i -t --rm -p 3000:3000 -p 3306:3306 some_app

What this does:

Everything works as expected. When the container starts, it interactively puts me in a bash shell within the container. I can then run rails s -b 0.0.0.0 from the container. This kicks off a puma server within the container that is serving a rails app. From a web browser on the host machine I can run localhost:3000 and successfully make requests to the app.

I want to mention that this is the last line of my Dockerfile which is probably relevant:

ENTRYPOINT ["/bin/bash"]

With docker-compose (not working as expected)

I have the same Dockerfile at the root of my app. I also have a docker-compose.yml file at the root of my app with the following:

services:
  some_app:
    build: .
    ports:
      - "3000:3000"
      - "3306:3306"
    stdin_open: true
    tty: true

I then run docker-compose run some_app. I expect all the same functionality as the above code example where I did not use docker-compose.

Running docker-compose run some_app does successfully start the container and puts me in an interactive shell within the container. I then run rails s -b 0.0.0.0 to start the server, and it appears the server successfully starts. rails server started

However, when I go to the host and try to makes requests via localhost:3000 I get a "Safari can't connect to the server".

It appears as though the binding of 3000 and 3306 between container and host aren't working when I attempt to kick things off with the docker-compose way.


Solution

  • I was missing the --service-ports flag

    -P, --service-ports            Run command with all service's ports enabled and mapped to the host

    # corrected docker-compose.yml
    
    services:
      some_app:
        build: .
        ports:
          - "3000:3000"
          - "3306:3306"
        stdin_open: true
        tty: true
    

    To kick things off successfully with docker-compose:

    docker-compose run --service-ports some_app