20

I build a Rails app container with the following Dockerfile:

$ cat Dockerfile
FROM ruby:2.2

MAINTAINER Luca G. Soave <luca.soave@gmail.com>

RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y mysql-client postgresql-client sqlite3 --no-install-recommends && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY . /usr/src/app/
RUN bundle install

EXPOSE 3000
CMD ["rails", "server"]

the build succeed:

$ docker build -t querier .
Sending build context to Docker daemon 46.75 MB
Sending build context to Docker daemon 
...
Step 10 : CMD rails server
 ---> Running in 8eb62f8a579a
 ---> 65eee929d518
Removing intermediate container 8eb62f8a579a
Successfully built 65eee929d518

the container is running:

$ docker logs -f 89ff3bb8c584
=> Booting WEBrick
=> Rails 4.2.0 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2015-01-06 19:56:56] INFO  WEBrick 1.3.1
[2015-01-06 19:56:56] INFO  ruby 2.2.0 (2014-12-25) [x86_64-linux]
[2015-01-06 19:56:56] INFO  WEBrick::HTTPServer#start: pid=1 port=3000

and it's exporting 3000/tcp port:

$ docker ps -al
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
89ff3bb8c584        querier:latest      "rails server"      16 minutes ago      Up 16 minutes       0.0.0.0:3000->3000/tcp   gloomy_babbage   

but the server is not reachable 'internally' or 'externally' Docker:

$ curl 0.0.0.0:3000
curl: (56) Recv failure: Connection reset by peer
$ curl 172.17.0.24:3000
curl: (7) Failed to connect to 172.17.0.24 port 3000: Connection refused

but everything seems ok:

$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' 89ff3bb8c584
172.17.0.24
$ netstat -r
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
default         10.36.32.1      0.0.0.0         UG        0 0          0 wlan0
10.0.3.0        *               255.255.255.0   U         0 0          0 lxcbr0
10.36.32.0      *               255.255.248.0   U         0 0          0 wlan0
172.17.0.0      *               255.255.0.0     U         0 0          0 docker0

$ ping 0.0.0.0
PING 0.0.0.0 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.061 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.069 ms
^C
--- 0.0.0.0 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.061/0.066/0.069/0.007 ms

$ ping 172.17.0.24
PING 172.17.0.24 (172.17.0.24) 56(84) bytes of data.
64 bytes from 172.17.0.24: icmp_seq=1 ttl=64 time=0.085 ms
64 bytes from 172.17.0.24: icmp_seq=2 ttl=64 time=0.107 ms
64 bytes from 172.17.0.24: icmp_seq=3 ttl=64 time=0.076 ms
^C

I tried also in the browser but nothing. The host sistem is:

$ docker -v
Docker version 1.4.1, build 5bc2ff8
$ uname -a 
Linux basenode 3.11.0-18-generic #32-Ubuntu SMP Tue Feb 18 21:11:14 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Any idea?

Luca G. Soave
  • 12,271
  • 12
  • 58
  • 109

2 Answers2

58

Rails server documentation states that the server by default binds to localhost, and this usually prevents dockerized application to accept connections. Try changing it to 0.0.0.0.

Mykola Gurov
  • 8,517
  • 4
  • 29
  • 27
  • of course, i already tried localhost:3000 as well as 127.0.0.1:3000 and they fail too – Luca G. Soave Jan 07 '15 at 15:09
  • 2
    I guess you were changing the way the rails starts, not the way you were calling it? Will the connection also be reset when you access it by the docker's IP, in your example `curl 172.17.0.24:3000 ` ? Will you be able to ping the app from within the container : `docker exec -it curl localhost:3000` ? – Mykola Gurov Jan 07 '15 at 18:10
  • yes, from inside it works, I get back the html page by doing 'docker exec -it 89ff3bb8c584 curl localhost:3000' – Luca G. Soave Jan 08 '15 at 20:33
  • I was having the same problem running nodejs in docker. This saved my day. Thanks. – rudolfson Apr 01 '16 at 13:15
  • Isn't localhost, 127.0.0.1, and 0.0.0.0 the same thing? – Richard May 11 '16 at 10:57
  • 2
    No - 0.0.0.0 means bind to all interfaces. 127.0.0.1 is the loopback interface which is relative to the networking of the docker machine, not your machine. – Routhinator Mar 01 '17 at 16:24
  • 127.0.0.1, 0.0.0.0 reference the same machine ; but aren't necessarily the same thing from a routing perspective. – jayunit100 Jul 31 '17 at 16:32
  • @Routhinator That comment should be marked as the answer. Just spent 4 hours trying to figure out why docker was resetting my connections. Your comment hit me in the face and made me see the error of my ways :) – Twifty May 24 '18 at 19:00
4

I just flagged Mykola Gurov answer because is the right 'cause' of my issue, anyway I'd also like to add the solution I implemented to work around that cause, just for tracking pourpose.

I modified config/boot.rb by adding default option:

$ cat config/boot.rb
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])

########  added lines  ########
require 'rails/commands/server' 

module Rails
  class Server
    alias :default_options_alias :default_options
    def default_options
      default_options_alias.merge!(:Host => '0.0.0.0')
    end
  end
end
###############################

If you don't want modify config/boot.rb, another solution could be forcing Dockerfile to bind 0.0.0.0 host as an ENTRYPOINT/CMD parameter:

$ cat Dockerfile
FROM ruby:2.2

RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y mysql-client postgresql-client sqlite3 --no-install-recommends && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY . /usr/src/app/
RUN bundle install

EXPOSE 3000
ENTRYPOINT ["rails", "server", "-b", "0.0.0.0"]
Luca G. Soave
  • 12,271
  • 12
  • 58
  • 109