I'm not sure how to a correctly expose the Sinatra port 4567
from Docker back to the host. Running the app locally has no issues.
The following repository show cases the issue https://gitlab.com/davidhooey/sinatra-docker
From searching I noticed the following issue Running Ruby Sinatra inside a Docker container not able to connect (via Mac host) or find commands (in different scenario)? where the --host 0.0.0.0
is passed into the rackup
command. However, I'm launching the site programmatically through using Site.run!
.
File tree
.
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── README.md
├── app.rb
├── docker-compose.yml
├── site.rb
└── views
└── index.erb
app.rb
module App
class App
def initialize(args)
# Do some stuff before launching site.
# Launch site
Site.run!
end
end
end
App::App.new(ARGV)
In site.rb
the :bind
Sinatra setting is set to 0.0.0.0
.
site.rb
require 'sinatra'
module App
class Site < Sinatra::Base
set :bind, '0.0.0.0'
set :static, true
set :public_dir, File.expand_path(__dir__)
get '/' do
erb :'/index'
end
end
end
Even still the site is inaccessible when run within a Docker container.
Dockfile
FROM ruby:2.2.6
EXPOSE 4567
RUN mkdir /app
WORKDIR /app
COPY . /app
RUN gem install bundler && bundle install
CMD ["/bin/bash"]
docker-compose.yml
version: '3.2'
services:
app:
build: .
hostname: app
ports:
- "4567:4567"
environment:
- RUBYOPT=-W0 -KU -E utf-8:utf-8
volumes:
- type: bind
source: .
target: /app
Local works:
ruby app.rb
Docker not so much:
docker-compose build
docker-compose run --rm app ruby app.rb
Docker run example.
$ docker-compose run --rm app ruby app.rb
[2018-07-27 14:21:10] INFO WEBrick 1.3.1
[2018-07-27 14:21:10] INFO ruby 2.2.6 (2016-11-15) [x86_64-linux]
== Sinatra (v2.0.3) has taken the stage on 4567 for development with backup from WEBrick
[2018-07-27 14:21:10] INFO WEBrick::HTTPServer#start: pid=1 port=4567
Launch a bash shell into the running container to access Sinatra within the container.
$ docker exec -it aa8f64b009b0 bash
root@app:/app# curl localhost:4567
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sinatra Docker</title>
</head>
<body>
<h1>Sinatra Docker</h1>
</body>
</html>
root@app:/app#
Any ideas are more than welcome on how to access the Sinatra port running within the container from the localhost when Sinatra is launched programmatically.
Need of exposing ports. In order to make a port available to services outside of Docker, or to Docker containers which are not connected to the container's network, we can use the -P or -p flag. This creates a firewall rule which maps a container port to a port on the Docker host to the outside world.
Accessing the Host With the Default Bridge Mode You just need to reference it by its Docker network IP, instead of localhost or 127.0. 0.1 . Your host's Docker IP will be shown on the inet line. Connect to this IP address from within your containers to successfully access the services running on your host.
Docker Compose exposes all specified container ports, making them reachable internally and externally from the local machine. Once again, in the PORTS column, we can find all the exposed ports. The value to the left of the arrow shows the host address where we can reach the container externally.
The Docker client will default to connecting to unix:///var/run/docker.sock on Linux, and tcp://127.0.0.1:2376 on Windows. For example: tcp:// -> TCP connection to 127.0. 0.1 on either port 2376 when TLS encryption is on, or port 2375 when communication is in plain text.
When running an app with docker-compose run
, service ports will not be mapped. This is by design, because run
is meant for one-off tasks and not for booting the whole compose stack.
See documentation here:
https://docs.docker.com/compose/reference/run/
The second difference is that the docker-compose run command does not create any of the ports specified in the service configuration. This prevents port collisions with already-open ports.
To map the ports you either need to use run
with --service-ports
, or add a command
section to your docker-compose.yml
and then use docker-compose up
:
Option 1 (using run):
docker-compose run --service-ports --rm app ruby app.rb -o 0.0.0.0
Option 2 (booting the whole stack):
services:
app:
build: .
hostname: app
command: ruby app.rb -o 0.0.0.0 # <-- Add this
ports:
- "4567:4567"
...
And then:
docker-compose up
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With