我正在编写一个基于 Ruby 的守护进程,以便在我的一台 Ubuntu 服务器上运行。我希望它在启动时运行,因此将为其编写一个新贵作业文件。但是,我使用捆绑器来管理它使用的各种 gem,并打算在将其部署到服务器后执行此操作:
bundle install --deployment
这会将捆绑器置于所谓的“部署模式”,从而设置各种选项并安装所有 gem进入“供应商”目录而不是系统范围。然而,这会在运行它时产生一个问题,它必须从自己的目录执行,因为这是宝石最终的位置:
<in the app's dir>
$ ./runmyapp
<it runs>
如果我cd
到不同的位置,然后尝试使用它的完整目录来运行它路径,它失败了:
<in another directory>
$ /path/to/runmyapp
<it crashes as it can't locate its gems>
我已经阅读了大量捆绑程序文档,但整个场景从未被涵盖?我应该只将 gems 安装到系统中吗?还有什么我应该做的吗?
I'm in the process of writing a Ruby-based daemon to sit and run on one of my Ubuntu servers. I'll be wanting this to run on startup, so will be writing an upstart job file for it. However, I've used bundler for managing the various gems it uses and intend to do this after deploying it to the server:
bundle install --deployment
This puts bundler into the so-called 'deployment mode', whereby various options are set and all the gems are installed into a 'vendor' directory rather than system-wide. However this creates a problem with running it, whereby it must be executed from its own directory as this is where the gems end up:
<in the app's dir>
$ ./runmyapp
<it runs>
If I cd
to a different location and then try to run it using it's full path, it fails:
<in another directory>
$ /path/to/runmyapp
<it crashes as it can't locate its gems>
I've read through lots of bundler documentation and this entire scenario is never even covered? Should I just install the gems to the system instead? Is there something else I ought to do?
发布评论
评论(3)
您使用捆绑器作为应用程序的 gem 管理器。我认为在这种情况下使用
bundle exec
是运行可执行文件的最佳方法。如果您从包含 Gemfile 的目录以外的目录运行应用程序,则应通过设置 BUNDLE_GEMFILE 来设置 Gemfile 位置(请参阅
bundle help exec
)。以下将对您有所帮助:You use bundler as gem manager for your app. I think in this case using
bundle exec
is the best way to run executables.If you run your app from different directory than directory that contains Gemfile you should set Gemfile location by setting BUNDLE_GEMFILE (see
bundle help exec
). Following will help you:我自己解决了类似的问题,最终创建了一个包装器脚本,
这里
app.rb
是应用程序的“主”入口点。您可以调用包装器脚本runmyapp
或应用程序的名称或其他名称。注意:
$0
由 bash 设置为包装器脚本的文件位置,例如/home/foo/app/runmyapp
或./runmyapp
bundle exec
“执行命令,使 Gemfile 中指定的所有 gem 都可以在 Ruby 程序中使用。” (文档)Tackling a similar problem myself I ended up creating a wrapper script,
Here
app.rb
is the app's "main" entry point. You might call the wrapper scriptrunmyapp
or the app's name or whatever.Note:
$0
is set by bash to the wrapper script's file location, e.g./home/foo/app/runmyapp
or./runmyapp
bundle exec
"executes the command, making all gems specified in the Gemfile available to require in Ruby programs." (docs)这里有一些很好的答案,但我想我应该添加一个适用于我的场景的快速答案,其中我通过调用
Bundler.require
Bundler >,并且不经常通过bundle exec
执行脚本。如果您执行此操作,并且
Gemfile
/Gemfile.lock
文件与脚本位于同一目录中,则可以使用Dir.chdir
和Kernel.__dir__
如下所示:这可以通过更改返回原始目录之前调用
Bundler.require
的目录(因为这期望相关文件存在于当前工作目录中)。There are some good answers here, but I thought I'd add a quick answer that works in my scenario, where I am explicitly setting up
Bundler
with a call toBundler.require
, and don't often execute the script viabundle exec
.If you are doing this, and the
Gemfile
/Gemfile.lock
files are in the same directory as the script, you can use a combination ofDir.chdir
andKernel.__dir__
like so:This works by changing the directory for the call to
Bundler.require
(as this expects the relevant files to exist in the current working directory) before returning to the original directory.