【问题标题】:How to access Sinatra port using Docker with docker-compose run如何使用 Docker 和 docker-compose run 访问 Sinatra 端口
【发布时间】:2020-12-23 03:46:19
【问题描述】:

我不确定如何正确地将 Sinatra 端口 4567 从 Docker 公开回主机。在本地运行应用程序没有问题。

以下存储库显示问题https://gitlab.com/davidhooey/sinatra-docker

通过搜索,我注意到以下问题Running Ruby Sinatra inside a Docker container not able to connect (via Mac host) or find commands (in different scenario)?,其中--host 0.0.0.0 被传递到rackup 命令中。但是,我通过使用Site.run! 以编程方式启动该站点。

文件树

.
├── 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)

site.rb 中,:bind Sinatra 设置设置为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

在 Docker 容器中运行时,即使网站仍然无法访问。

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

本地作品:

ruby app.rb

Docker 没那么多:

docker-compose build
docker-compose run --rm app ruby app.rb

Docker 运行示例。

$ 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

在正在运行的容器中启动一个 bash shell 以访问容器内的 Sinatra。

$ 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#

欢迎任何关于在以编程方式启动 Sinatra 时如何从 localhost 访问容器内运行的 Sinatra 端口的想法。

【问题讨论】:

  • 您是否登录到 docker 镜像以检查您的应用是否正常运行并绑定到某个界面?
  • 我已经添加了 Docker Run,展示了 Sinatra 在容器中的启动。似乎它在端口上启动没有问题。

标签: ruby docker docker-compose sinatra


【解决方案1】:

使用docker-compose run 运行应用程序时,服务端口将不会被映射。这是设计使然,因为run 用于一次性任务,而不是用于启动整个撰写堆栈。

在此处查看文档:
https://docs.docker.com/compose/reference/run/

第二个区别是 docker-compose run 命令不会创建服务配置中指定的任何端口。这可以防止端口与已打开的端口发生冲突。

要映射您需要使用run--service-ports 的端口,或者将command 部分添加到您的docker-compose.yml,然后使用docker-compose up

选项 1(使用运行):

docker-compose run --service-ports --rm app ruby app.rb -o 0.0.0.0

选项 2(引导整个堆栈):

services:
  app:
    build: .
    hostname: app
    command: ruby app.rb -o 0.0.0.0  # <-- Add this
    ports:
      - "4567:4567"
    ...

然后:

docker-compose up

【讨论】:

  • 我还发现有必要使用 command: ruby app.rb -o 0.0.0.0 将 Sinatra 绑定到任意主机(参见 *.com/a/41673831/18706 - 令人困惑,因为 Rails 不需要这样的 docker-compose 配置)。之后,就可以从主机连接到localhost:4567