如何配置 Rails 应用程序(redmine)在 Windows 上作为服务运行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/877943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:31:09  来源:igfitidea点击:

how to configure a rails app (redmine) to run as a service on windows?

ruby-on-railswindowsserviceredmine

提问by opensas

I'm using redmine as a ticket manager, and I'd like to configure it to be run automatically when windows starts up.

我使用 redmine 作为票务管理器,我想将它配置为在 Windows 启动时自动运行。

How can I configure it to be run as a service?

如何将其配置为作为服务运行?

--

——

Just asked the question to document it, I hope somebody may find it useful...

刚刚问了这个问题来记录它,我希望有人会觉得它有用......

回答by opensas

1. using webrick:

1.使用webrick:

ref: http://www.redmine.org/boards/1/topics/4123

参考:http: //www.redmine.org/boards/1/topics/4123

  • Download and install the Windows NT Resource Kit from http://www.microsoft.com/downloads/details.aspx?familyid=9d467a69-57ff-4ae7-96ee-b18c4790cffd&displaylang=en

  • Create the service by running this command:

    path\INSTSRV.EXE your_service_name path\SRVANY.EXE
    

    in my case pathis:

    "C:\Program Files\Windows NT Resource Kit\INSTSRV.EXE" redmine_webrick "C:\Program Files\Windows NT Resource Kit\SRVANY.EXE"
    

    could be also C:\Program Files\Windows Resource Kits\Tools\.

  • Run regedit (Start -> Run -> regedit)

    • Add the following registry key if it's not already there:

      HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\your_service_name

    • Right click on this registry key and select New -> Key. Name it Parameters.

    • Add two values to the Parameterskey. Right click on the parameters key, New -> String Value. Name it Application. Now create another one named AppParameters. Give them the following values:

      • Application: PathToRuby.exe, eg. C:\ruby\bin\Ruby.exe
      • AppParameters: C:\RUBYAPP\script\server -e production, where RUBYAPPis the directory that contains the redmine website.

      Example: C:\redmine\script\server -p 2000 -e production(-p indicates the port webrick will be listening to, and -e the environment used)

  • http://www.microsoft.com/downloads/details.aspx?familyid=9d467a69-57ff-4ae7-96ee-b18c4790cffd&displaylang=en下载并安装 Windows NT Resource Kit

  • 通过运行以下命令创建服务:

    path\INSTSRV.EXE your_service_name path\SRVANY.EXE
    

    在我的情况下path是:

    "C:\Program Files\Windows NT Resource Kit\INSTSRV.EXE" redmine_webrick "C:\Program Files\Windows NT Resource Kit\SRVANY.EXE"
    

    也可以C:\Program Files\Windows Resource Kits\Tools\

  • 运行 regedit(开始 -> 运行 -> regedit)

    • 添加以下注册表项(如果尚不存在):

      HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\your_service_name

    • 右键单击此注册表项并选择新建 -> 项。命名它Parameters

    • Parameters键添加两个值。右键单击参数键,新建 -> 字符串值。命名它Application。现在创建另一个名为AppParameters. 给他们以下值:

      • 应用:PathToRuby.exe,例如。C:\ruby\bin\Ruby.exe
      • AppParameters: C:\RUBYAPP\script\server -e production,其中RUBYAPP包含redmine网站的目录。

      示例:C:\redmine\script\server -p 2000 -e production(-p 表示 webrick 将监听的端口,-e 表示使用的环境)

Now you can go to Administrative Tools -> Services. There you can start your service (the one with name your_service_name) and test whether or not it is working properly. It should be noted that the service will be marked as started prior to WEBrick finishing its boot procedure. You should give it 1min or so before trying to hit the service to verify that it is working correctly.

现在您可以转到管理工具 -> 服务。在那里,您可以启动您的服务(具有 name 的服务your_service_name)并测试它是否正常工作。应该注意的是,在 WEBrick 完成其启动过程之前,该服务将被标记为已启动。在尝试访问服务以验证它是否正常工作之前,您应该给它 1 分钟左右的时间。

2. using mongrel:

2.使用杂种:

ref: http://mongrel.rubyforge.org/wikiref: http://mongrel.rubyforge.org/wiki/Win32

参考:http: //mongrel.rubyforge.org/wiki参考:http: //mongrel.rubyforge.org/wiki/Win32

first install mongrel and mongrel_service gem

首先安装 mongrel 和 mongrel_service gem

gem install mongrel

gem install mongrel_service

then create the service

然后创建服务

mongrel_rails service::install -N redmine_mongrel -c c:\redmine -p 3000 -e production

3. using thin:

3.使用薄:

References:

参考:

Instructions:

指示:

  1. First install thin (you'll need to install rack gem, if not already installed)

    gem install rack     
    gem install thin
    
  2. Follow the same steps indicated for webrick, but add another value named "AppDirectory". This is needed in order to avoid using c:\ruby\bin\thin.bat If I just pointed to the bat file, I couldn't stop the service.

    In HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\redmine_thin\Parametersadd the following keys:

    Application: c:\ruby\bin\ruby.exe

    AppDirectory: c:\redmine

    AppParameters: c:\ruby\bin\thin start -p 4000 -e production

  1. 首先安装thin(如果尚未安装,则需要安装rack gem)

    gem install rack     
    gem install thin
    
  2. 按照为 webrick 指示的相同步骤进行操作,但添加另一个名为“AppDirectory”的值。这是需要的,以避免使用 c:\ruby\bin\thin.bat 如果我只是指向 bat 文件,我无法停止服务。

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\redmine_thin\Parameters添加下列键:

    应用程序:c:\ruby\bin\ruby.exe

    应用程序目录:c:\redmine

    应用参数:c:\ruby\bin\thin start -p 4000 -e production

------------------------------------------------------------------------------------------

-------------------------------------------------- ----------------------------------------

You can control any of your service with the following commands:

您可以使用以下命令控制您的任何服务:

net start redmine_xxx

net stop redmine_xxx

sc config redmine_xxx start= auto

sc config redmine_xxx start= auto dependency= MySql

sc delete redmine_xxx

网络启动 redmine_xxx

网络停止 redmine_xxx

sc 配置 redmine_xxx start= auto

sc config redmine_xxx start= 自动依赖= MySql

sc 删除 redmine_xxx

回答by Bohdan

For Rails 3.0.x applications (tested on 3.0.10 & Windows 7)

对于 Rails 3.0.x 应用程序(在 3.0.10 和 Windows 7 上测试)

demo_daemon_ctl.rb

demo_daemon_ctl.rb

############################################################################
# demo_daemon_ctl.rb
#
# This is a command line script for installing and/or running a small
# Ruby program as a service.  The service will simply write a small bit
# of text to a file every 20 seconds. It will also write some text to the
# file during the initialization (service_init) step.
#
# It should take about 10 seconds to start, which is intentional - it's a test
# of the service_init hook, so don't be surprised if you see "one moment,
# start pending" about 10 times on the command line.
#
# The file in question is C:\test.log.  Feel free to delete it when finished.
#
# To run the service, you must install it first.
#
# Usage: ruby demo_daemon_ctl.rb <option>
#
# Note that you *must* pass this program an option
#
# Options:
#    install    - Installs the service.  The service name is "DemoSvc"
#                 and the display name is "Demo".
#    start      - Starts the service.  Make sure you stop it at some point or
#                 you will eventually fill up your filesystem!.
#    stop       - Stops the service.
#    pause      - Pauses the service.
#    resume     - Resumes the service.
#    uninstall  - Uninstalls the service.
#    delete     - Same as uninstall.
#
# You can also used the Windows Services GUI to start and stop the service.
#
# To get to the Windows Services GUI just follow:
#    Start -> Control Panel -> Administrative Tools -> Services
############################################################################
require 'win32/service'
require 'rbconfig'
include Win32
include Config

# Make sure you're using the version you think you're using.
puts 'VERSION: ' + Service::VERSION

SERVICE_NAME = 'DemoSvc'
SERVICE_DISPLAYNAME = 'Demo'

# Quote the full path to deal with possible spaces in the path name.
ruby = File.join(CONFIG['bindir'], 'ruby').tr('/', '\')
path = ' "' + File.dirname(File.expand_path(
APP_ROOT_CUSTOM = 'your app root dir'
LOG_FILE = APP_ROOT_CUSTOM + 'log/win32_daemon_test.log'
APP_PATH = File.expand_path( APP_ROOT_CUSTOM  + 'config/application', APP_ROOT_CUSTOM  + 'script/rails')

begin  
    require 'rubygems'
    require 'win32/daemon'
    include Win32
    require File.expand_path( APP_ROOT_CUSTOM  + 'config/boot', APP_ROOT_CUSTOM  + 'script/rails')
    require 'rails/commands/server'
    module ::Rails
        class Server
            def default_options
                super.merge({
                    :Port        => 3000,
                    :environment => (ENV['RAILS_ENV'] || "development").dup,
                    :daemonize   => false,
                    :debugger    => false,
                    :pid         => File.expand_path( APP_ROOT_CUSTOM + "tmp/pids/server.pid" ),
                    :config      => File.expand_path( APP_ROOT_CUSTOM + "config.ru" )
                })
            end
        end
    end

    class DemoDaemon < Daemon       
        # This method fires off before the +service_main+ mainloop is entered.
        # Any pre-setup code you need to run before your service's mainloop
        # starts should be put here. Otherwise the service might fail with a
        # timeout error when you try to start it.
        #
        def service_init
        end

        # This is the daemon's mainloop. In other words, whatever runs here
        # is the code that runs while your service is running. Note that the
        # loop is not implicit.
        #
        # You must setup a loop as I've done here with the 'while running?'
        # code, or setup your own loop. Otherwise your service will exit and
        # won't be especially useful.
        #
        # In this particular case, I've setup a loop to append a short message
        # and timestamp to a file on your C: drive every 20 seconds. Be sure
        # to stop the service when you're done!
        #
        def service_main(*args)

            Rails::Server.new.tap { |server|
                require APP_PATH
                Dir.chdir( APP_ROOT_CUSTOM )
                server.start
            }

            msg = 'application started at: ' + Time.now.to_s

            File.open(LOG_FILE, 'a'){ |f|
                f.puts msg
                f.puts "Args: " + args.join(',')
            }

            # While we're in here the daemon is running.
            while running?
                if state == RUNNING
                    sleep 20 
                    msg = 'Service is running as of: ' + Time.now.to_s
                    File.open(LOG_FILE, 'a'){ |f| f.puts msg }
                else # PAUSED or IDLE
                    sleep 0.5
                end
            end

            # We've left the loop, the daemon is about to exit.

            File.open(LOG_FILE, 'a'){ |f| f.puts "STATE: #{state}" }

            msg = 'service_main left at: ' + Time.now.to_s

            File.open(LOG_FILE, 'a'){ |f| f.puts msg }
        end

        # This event triggers when the service receives a signal to stop. I've
        # added an explicit "exit!" here to ensure that the Ruby interpreter exits
        # properly. I use 'exit!' instead of 'exit' because otherwise Ruby will
        # raise a SystemExitError, which I don't want.
        #
        def service_stop
            msg = 'Received stop signal at: ' + Time.now.to_s
            File.open(LOG_FILE, 'a'){ |f| f.puts msg }
            exit!
        end

        # This event triggers when the service receives a signal to pause. 
        #
        def service_pause
            msg = 'Received pause signal at: ' + Time.now.to_s
            File.open(LOG_FILE, 'a'){ |f| f.puts msg }
        end

        # This event triggers when the service receives a signal to resume
        # from a paused state.
        #
        def service_resume
            msg = 'Received resume signal at: ' + Time.now.to_s
            File.open(LOG_FILE, 'a'){ |f| f.puts msg }
        end
    end

    # Create an instance of the Daemon and put it into a loop. I borrowed the
    # method name 'mainloop' from Tk, btw.
    #
    DemoDaemon.mainloop
rescue Exception => err
    File.open(LOG_FILE, 'a'){ |fh| fh.puts 'Daemon failure: ' + err }
    raise
end
)).tr('/', '\') path += '\demo_daemon.rb"' cmd = ruby + path # You must provide at least one argument. raise ArgumentError, 'No argument provided' unless ARGV[0] case ARGV[0].downcase when 'install' Service.new( :service_name => SERVICE_NAME, :display_name => SERVICE_DISPLAYNAME, :description => 'Sample Ruby service', :binary_path_name => cmd ) puts 'Service ' + SERVICE_NAME + ' installed' when 'start' if Service.status(SERVICE_NAME).current_state != 'running' Service.start(SERVICE_NAME, nil, 'hello', 'world') while Service.status(SERVICE_NAME).current_state != 'running' puts 'One moment...' + Service.status(SERVICE_NAME).current_state sleep 1 end puts 'Service ' + SERVICE_NAME + ' started' else puts 'Already running' end when 'stop' if Service.status(SERVICE_NAME).current_state != 'stopped' Service.stop(SERVICE_NAME) while Service.status(SERVICE_NAME).current_state != 'stopped' puts 'One moment...' + Service.status(SERVICE_NAME).current_state sleep 1 end puts 'Service ' + SERVICE_NAME + ' stopped' else puts 'Already stopped' end when 'uninstall', 'delete' if Service.status(SERVICE_NAME).current_state != 'stopped' Service.stop(SERVICE_NAME) end while Service.status(SERVICE_NAME).current_state != 'stopped' puts 'One moment...' + Service.status(SERVICE_NAME).current_state sleep 1 end Service.delete(SERVICE_NAME) puts 'Service ' + SERVICE_NAME + ' deleted' when 'pause' if Service.status(SERVICE_NAME).current_state != 'paused' Service.pause(SERVICE_NAME) while Service.status(SERVICE_NAME).current_state != 'paused' puts 'One moment...' + Service.status(SERVICE_NAME).current_state sleep 1 end puts 'Service ' + SERVICE_NAME + ' paused' else puts 'Already paused' end when 'resume' if Service.status(SERVICE_NAME).current_state != 'running' Service.resume(SERVICE_NAME) while Service.status(SERVICE_NAME).current_state != 'running' puts 'One moment...' + Service.status(SERVICE_NAME).current_state sleep 1 end puts 'Service ' + SERVICE_NAME + ' resumed' else puts 'Already running' end else raise ArgumentError, 'unknown option: ' + ARGV[0] end

demo_daemon.rb

demo_daemon.rb

ruby demo_daemon_ctl.rb install

place both files in same dir and run

将两个文件放在同一个目录中并运行

  class RedmineService < Daemon

    def service_init
      File.open(LOG_FILE, 'a'){ |f| f.puts "Initializing service #{Time.now}" } 

      #@server_pid = Process.spawn 'ruby script/rails s -e production', :chdir => REDMINE_DIR, :err => [LOG_FILE, 'a']
      # use full path
      @server_pid = Process.spawn 'C:\Ruby23-x64\bin\ruby E:\www\redmine-3.3.2\bin\rails s -e production -p 3000', :chdir => REDMINE_DIR, :err => [LOG_FILE, 'a']
    end

    def service_main
      File.open(LOG_FILE, 'a'){ |f| f.puts "Service is running #{Time.now} with pid #{@server_pid}" }
      while running?
        sleep 10
      end
    end

    def service_stop
      File.open(LOG_FILE, 'a'){ |f| f.puts "Stopping server thread #{Time.now}" }
      system "taskkill /PID #{@server_pid} /T /F" 
      Process.waitall
      File.open(LOG_FILE, 'a'){ |f| f.puts "Service stopped #{Time.now}" }
      exit!
    end
  end

  RedmineService.mainloop

rescue Exception => e
  File.open(LOG_FILE,'a+'){ |f| f.puts " ***Daemon failure #{Time.now} exception=#{e.inspect}\n#{e.backtrace.join($/)}" }
  raise
end

回答by Christian Specht

Some time ago, I tried to install Redmine on Windows as well. But I wasn't able to get it to work, probably because of lack of Rails knowledge.

前段时间,我也尝试在 Windows 上安装 Redmine。但我无法让它工作,可能是因为缺乏 Rails 知识

Then I discovered Bitnami Redmine Stack. They have a Windows installer, which installs Redmine with all needed dependencies, and it just works.

然后我发现了Bitnami Redmine Stack。他们有一个 Windows 安装程序,可以安装 Redmine 和所有需要的依赖项,并且它可以正常工作

回答by James Tan

For Rails 4.0.x applications as suggested by Bohdan, we have to replace

对于 Bohdan 建议的 Rails 4.0.x 应用程序,我们必须替换

CONFIG['bindir'] with RbConfig::CONFIG['bindir']

CONFIG['bindir'] 与 RbConfig::CONFIG['bindir']

Remmber to: gem install win32-service

记住: gem install win32-service

回答by haiwuxing

  • gem install win32-service
  • drop below Ruby code in a service.rb file and update REDMINE_DIR path to fit your Redmine installation
  • create the service, for example with sc create redmine binPath= "C:\Ruby23-x64\bin\rubyw -C E:\www\redmine-3.3.2\ service.rb"where E:\www\redmine-3.3.2\is the path of the directory where the service.rb file is located and C:\Ruby23-x64\bin\rubywyour Ruby installation path
  • gem install win32-service
  • 放到 service.rb 文件中的 Ruby 代码下方并更新 REDMINE_DIR 路径以适合您的 Redmine 安装
  • 创建服务,例如与sc create redmine binPath= "C:\Ruby23-x64\bin\rubyw -C E:\www\redmine-3.3.2\ service.rb"地方E:\www\redmine-3.3.2\是在service.rb文件所在的目录和路径C:\Ruby23-x64\bin\rubywRuby安装路径

begin require 'win32/daemon' include Win32

开始需要 'win32/daemon' 包括 Win32

Path: C:\RailsInstaller\Ruby2.3.3\bin\ruby.exe
Startup directory: C:\Program Files\redmine-3.4.6
Arguments: C:\RailsInstaller\Ruby2.3.3\bin\thin start -e production -p 3000
  • Note that Process.spawn in the service.rb use the full path.
  • 请注意,service.rb 中的 Process.spawn 使用完整路径。

回答by Gico

Hope this will help to anyone. I defined the windows service that starts the redmine with the thin server.

希望这对任何人都有帮助。我定义了用瘦服务器启动 redmine 的 Windows 服务。

Use http://nssm.cc/usagefor windows service creation. Set the path to ruby.exe, your redmine's working directory and define the starting parameters:

使用http://nssm.cc/usage创建 windows 服务。将路径设置为 ruby​​.exe,您的 redmine 的工作目录并定义启动参数:

##代码##