Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 需要config.ru从Docker容器中启动Sinatra应用程序吗?_Ruby_Docker_Containers_Sinatra_Rack - Fatal编程技术网

Ruby 需要config.ru从Docker容器中启动Sinatra应用程序吗?

Ruby 需要config.ru从Docker容器中启动Sinatra应用程序吗?,ruby,docker,containers,sinatra,rack,Ruby,Docker,Containers,Sinatra,Rack,为什么简单的命令ruby my app.rb不能从Docker容器中启动我的Sinatra应用程序 我有一个非常简单的Sinatra应用程序: # myapp.rb require 'sinatra' get '/' do 'Hello world!' end 我使用ruby myapp.rb在本地运行它,并得到以下输出 == Sinatra (v2.1.0) has taken the stage on 4567 for development with backup from Pu

为什么简单的命令ruby my app.rb不能从Docker容器中启动我的Sinatra应用程序

我有一个非常简单的Sinatra应用程序:

# myapp.rb

require 'sinatra'

get '/' do
  'Hello world!'
end
我使用ruby myapp.rb在本地运行它,并得到以下输出

== Sinatra (v2.1.0) has taken the stage on 4567 for development with backup from Puma
Puma starting in single mode...
* Puma version: 5.1.1 (ruby 2.7.0-p0) ("At Your Service")
*  Min threads: 0
*  Max threads: 5
*  Environment: development
*          PID: 49242
* Listening on http://127.0.0.1:4567
* Listening on http://[::1]:4567
Use Ctrl-C to stop
打开了没有任何问题。当移动到Dockerize应用程序时,我使用Sinatra和以下Dockerfile创建了一个Gemfile

FROM ruby:2.7.0

WORKDIR /code
COPY . /code
RUN bundle install

CMD ["ruby", "myapp.rb"]
站起来的容器,似乎成功的Docker桌面是绿色的,没有终端错误,但点击了建议的链接http://localhost:4567/ 不加载悲伤的铬色脸。容器中的日志如下所示

[2020-12-27 18:04:52] INFO WEBrick 1.6.0
[2020-12-27 18:04:52] INFO ruby 2.7.0 (2019-12-25) [x86_64-linux]
== Sinatra (v2.1.0) has taken the stage on 4567 for development with backup from WEBrick
[2020-12-27 18:04:52] INFO WEBrick::HTTPServer#start: pid=1 port=4567
但是,当我添加下面的config.ru文件并将Dockerfile的最后一行更改为CMD[bundle,exec,rackup,-host,0.0.0.0,-p,4567]时,http://localhost:4567/ 打开时没有问题

# config.ru

require './myapp'
    
run Sinatra::Application
为什么这些调整是必要的,使应用程序的工作?来自容器的日志看起来几乎相同

[2020-12-27 18:01:49] INFO WEBrick 1.6.0
[2020-12-27 18:01:49] INFO ruby 2.7.0 (2019-12-25) [x86_64-linux]
[2020-12-27 18:01:49] INFO WEBrick::HTTPServer#start: pid=1 port=4567
172.17.0.1 - - [27/Dec/2020:18:02:44 +0000] "GET / HTTP/1.1" 200 12 0.0420
我不一定想知道这里的最佳实践,这是一个附带项目。我更多的是试图了解我可能缺少的关于对接应用程序如何工作的内容

Docker命令用于两种情况,我在运行之间清除图像/容器:

docker build --tag sinatra-img .
docker run --name sinatra-app -dp 4567:4567 sinatra-img
注:

以下答案与问题的前一个版本有关。新问题有不同的答案,使用-o 0.0.0.0 CLI参数修复绑定地址

Sinatra框架基于机架,需要机架兼容的服务器。。。或者,它也可以回退到Ruby语言包中包含的WEBrick服务器上

WEBrick是一个不错的服务器,但它不是为更重的负载或生产中运行的实际web应用程序的需要而设计的

因此,您应该使用机架兼容的服务器

但是,这并不意味着您必须使用rackup CLI帮助程序

一些服务器(如Puma、Iodio和passenger)包含自己的CLI,因此您可以使用以下命令运行应用程序:

CMD ["bundle", "exec", "puma", "-p", "4567"]
键入puma-h或碘-h以获取更多命令行选项。服务器特定的CLI可能提供备份无法提供的某些特定于服务器的功能。例如,Idio通过其CLI最大文件上载大小、最大总头长度、web套接字消息限制等公开了一些安全选项

使用服务器的CLI界面应该被视为更好的选择

此外,尽管我不推荐,但有些服务器还提供了Ruby API,允许您从Ruby脚本而不是config.ru文件启动服务器。i、 例如,我对碘有偏见:

ENV['PORT'] ||= "4567"
require 'iodine' # will test the `ENV['PORT']` value

require 'sinatra'

get '/' do
  'Hello world!'
end

Iodine.listen service: :http, public: './public', handler: Sinatra::Application
# Iodine.threads = 16 # or whatever.
# Iodine.workers = -2 # half the core count (negative value).
Iodine.start
我不会用这种方法。它往往更脆弱,而且还硬编码应用程序中的环境和服务器设置

我只想添加config.ru并使用一个我喜欢的像样的服务器,但Puma更受欢迎,除非您需要实时发布/订阅、WebSocket或某些特定的安全/性能功能,否则流行通常更安全

根据评论编辑:

如果您真正想要的是使用gemfile将命令bundle exec嵌入Ruby脚本以进行版本控制,那么可以使用以下行启动脚本

#!/usr/bin/env ruby
require 'bundler'
Bundler.require
或者,如果您根本不想使用gemfile或不需要版本控制,您可以从以下内容开始第一行:

#!/usr/bin/env ruby
然后,您可以直接启动服务器:

CMD ["puma", "-p", "4567"]
或者,不使用服务器的CLI,使用上面的示例脚本,运行:

CMD ["my_script.rb"]
注:

以下答案与问题的前一个版本有关。新问题有不同的答案,使用-o 0.0.0.0 CLI参数修复绑定地址

Sinatra框架基于机架,需要机架兼容的服务器。。。或者,它也可以回退到Ruby语言包中包含的WEBrick服务器上

WEBrick是一个不错的服务器,但它不是为更重的负载或生产中运行的实际web应用程序的需要而设计的

因此,您应该使用机架兼容的服务器

但是,这并不意味着您必须使用rackup CLI帮助程序

一些服务器(如Puma、Iodio和passenger)包含自己的CLI,因此您可以使用以下命令运行应用程序:

CMD ["bundle", "exec", "puma", "-p", "4567"]
键入puma-h或碘-h以获取更多命令行选项。服务器特定的CLI可能提供备份无法提供的某些特定于服务器的功能。例如,Idio通过其CLI最大文件上载大小、最大总头长度、web套接字消息限制等公开了一些安全选项

使用服务器的CLI界面应该被视为更好的选择

此外,尽管我不推荐,但有些服务器还提供了Ruby API,允许您从Ruby脚本而不是config.ru文件启动服务器。i、 例如,我对碘有偏见:

ENV['PORT'] ||= "4567"
require 'iodine' # will test the `ENV['PORT']` value

require 'sinatra'

get '/' do
  'Hello world!'
end

Iodine.listen service: :http, public: './public', handler: Sinatra::Application
# Iodine.threads = 16 # or whatever.
# Iodine.workers = -2 # half the core count (negative value).
Iodine.start
我不会用这种方法。它往往更脆弱,而且还硬编码应用程序中的环境和服务器设置 激动

我只想添加config.ru并使用一个我喜欢的像样的服务器,但Puma更受欢迎,除非您需要实时发布/订阅、WebSocket或某些特定的安全/性能功能,否则流行通常更安全

根据评论编辑:

如果您真正想要的是使用gemfile将命令bundle exec嵌入Ruby脚本以进行版本控制,那么可以使用以下行启动脚本

#!/usr/bin/env ruby
require 'bundler'
Bundler.require
或者,如果您根本不想使用gemfile或不需要版本控制,您可以从以下内容开始第一行:

#!/usr/bin/env ruby
然后,您可以直接启动服务器:

CMD ["puma", "-p", "4567"]
或者,不使用服务器的CLI,使用上面的示例脚本,运行:

CMD ["my_script.rb"]


当您在Docker容器中使用ruby myapp.rb启动应用程序时,您的应用程序正在本地主机上侦听,因为它正在开发模式下运行。如果您的Docker服务器在VM中运行,您将无法访问您的应用程序。要解决此问题,当您在Docker容器中运行应用程序时,请确保它正在侦听0.0.0:ruby myapp.rb-o 0.0.0.0

当您在Docker容器中使用ruby myapp.rb启动应用程序时,您的应用程序正在侦听localhost,因为它正在开发模式下运行。如果您的Docker服务器在VM中运行,您将无法访问您的应用程序。要解决此问题,当您在Docker容器中运行应用程序时,请确保它正在侦听0.0.0.0:ruby myapp.rb-o 0.0.0

您确定您的代码正在运行吗?您是否在容器中安装了Sinatra和依赖项?如果您这样做了,可能Ruby不在容器的路径中,您的容器没有web服务器,或者正在使用的web服务器正在绑定到其他端口。也许可以查看容器的进程列表和打开的端口。Sinatra应该通过上面添加的Gemfile进行安装,以清晰起见。我在构建时没有看到任何错误,因此我假设应该安装它可能具有的任何依赖项。我相信代码应该正在运行。容器日志显示[2020-12-22 21:45:21]INFO ruby 2.7.0 2019-12-25[x86_64-linux]==Sinatra v2.1.0已在4567上登场,并从WEBrick[2020-12-22 21:45:21]INFO WEBrick::HTTPServerstart:pid=8 port=4567奇怪的是,当我从CLI运行ps时,我没有看到pid=8。我只看到一个sh和我自己的ps搜索。你是否尝试访问http://localhost:4567?你确定你的代码正在运行吗?您是否在容器中安装了Sinatra和依赖项?如果您这样做了,可能Ruby不在容器的路径中,您的容器没有web服务器,或者正在使用的web服务器正在绑定到其他端口。也许可以查看容器的进程列表和打开的端口。Sinatra应该通过上面添加的Gemfile进行安装,以清晰起见。我在构建时没有看到任何错误,因此我假设应该安装它可能具有的任何依赖项。我相信代码应该正在运行。容器日志显示[2020-12-22 21:45:21]INFO ruby 2.7.0 2019-12-25[x86_64-linux]==Sinatra v2.1.0已在4567上登场,并从WEBrick[2020-12-22 21:45:21]INFO WEBrick::HTTPServerstart:pid=8 port=4567奇怪的是,当我从CLI运行ps时,我没有看到pid=8。我只看到一个sh和我自己的ps搜索。你尝试过访问http://localhost:4567吗?谢谢你提供的信息!我不一定在这里寻找最佳实践答案这是一个附带项目,我不关心规模,而是为什么从容器中运行ruby myapp.rb不起作用,而且您似乎需要bundle exec。。。启动它的方法。@stk1234 bundle exec从gem文件中加载所有gem,并在运行exec之后的命令之前将您锁定到gemfile.lock中的版本。您不必使用bundler,但它确实使版本控制变得更加容易。@stk1234-I已更新以提供这些附加变体。谢谢您提供的信息!我不一定在这里寻找最佳实践答案这是一个附带项目,我不关心规模,而是为什么从容器中运行ruby myapp.rb不起作用,而且您似乎需要bundle exec。。。启动它的方法。@stk1234 bundle exec从gem文件中加载所有gem,并在运行exec之后的命令之前将您锁定到gemfile.lock中的版本。您不必使用bundler,但它确实使版本控制变得更加容易。@stk1234-I更新为提供这些附加变体的答案。很有趣!正如预期的那样,该命令在本地和Dockerfile中都有效。在本地,我的应用程序在Docker桌面上和从Docker桌面打开。指定允许此操作的-o 0.0.0.0是什么?容器中的日志与ruby myapp.rb Docker案例看起来完全相同,但是它打开了。我不确定我是否理解您在VM中运行Docker服务器的意思。我只是在这里和本地做docker desktop。docker在某些系统(如Mac)的后台使用虚拟机。绑定到0.0.0.0意味着您的应用程序将侦听来自任何地方的连接,而不是o
f只是来自VM内部的本地连接。这里解释了0.0.0.0背后的网络概念:Docker使用自己的网络堆栈,除非您指定-net主机。除此之外,它在特定平台上的虚拟机上运行。太棒了!稍后我会再多说一点。我正在为一些资源添加书签,以防其他人对此有所了解:1-Docker连接被拒绝,2-容器本地主机端口映射,3-容器网络,4-Sinatra文档-很有趣!正如预期的那样,该命令在本地和Dockerfile中都有效。在本地,我的应用程序在Docker桌面上和从Docker桌面打开。指定允许此操作的-o 0.0.0.0是什么?容器中的日志与ruby myapp.rb Docker案例看起来完全相同,但是它打开了。我不确定我是否理解您在VM中运行Docker服务器的意思。我只是在这里和本地做docker desktop。docker在某些系统(如Mac)的后台使用虚拟机。绑定到0.0.0.0意味着您的应用程序将侦听来自任何地方的连接,而不仅仅是来自VM内部的本地连接。这里解释了0.0.0.0背后的网络概念:Docker使用自己的网络堆栈,除非您指定-net主机。除此之外,它在特定平台上的虚拟机上运行。太棒了!稍后我会再多说一点。我正在为一些资源添加书签,以防其他人对此进行调查:1-Docker连接被拒绝,2-容器本地主机端口映射,3-容器网络,4-Sinatra文档-o