Search code examples
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:

  • builds the image from the Dockerfile and names the repository of the image "some_app".
  • creates and starts a container from that "some_app" image in interactive mode. That container is set to be automatically deleted when the container stops, and the container has binding ports of 3000 and 3306 with the host.

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