ruby-on-rails windows service redmine

ruby on rails - cómo configurar una aplicación de rieles(redmine) para ejecutar como un servicio en Windows?



ruby-on-rails service (6)

Estoy usando redmine como administrador de tickets, y me gustaría configurarlo para que se ejecute automáticamente cuando Windows se inicia.

¿Cómo puedo configurarlo para que se ejecute como un servicio?

-

Acabo de hacer la pregunta para documentarla, espero que alguien la encuentre útil ...


1. usando webrick:

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

  • Descargue e instale el Kit de recursos de Windows NT en http://www.microsoft.com/downloads/details.aspx?familyid=9d467a69-57ff-4ae7-96ee-b18c4790cffd&displaylang=en

  • Crea el servicio ejecutando este comando:

    path/INSTSRV.EXE your_service_name path/SRVANY.EXE

    en mi caso, la path es:

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

    podría ser también C:/Program Files/Windows Resource Kits/Tools/ .

  • Ejecute regedit (Inicio -> Ejecutar -> regedit)

    • Agregue la siguiente clave de registro si aún no está allí:

      HKEY_LOCAL_MACHINE / SYSTEM / CurrentControlSet / Services / your_service_name

    • Haga clic derecho en esta clave de registro y seleccione Nuevo -> Clave. Nómbrelo Parameters .

    • Agregue dos valores a la clave de Parameters . Haga clic derecho en la clave de parámetros, Nuevo -> Valor de cadena. Nómbrelo Application . Ahora crea otro llamado AppParameters . Deles los siguientes valores:

      • Aplicación: PathToRuby.exe , ej. C:/ruby/bin/Ruby.exe
      • AppParameters: C:/RUBYAPP/script/server -e production , donde RUBYAPP es el directorio que contiene el sitio web redmine.

      Ejemplo: C:/redmine/script/server -p 2000 -e production (-p indica el puerto que webrick estará escuchando, y -e el entorno utilizado)

Ahora puede ir a Herramientas administrativas -> Servicios. Allí puede comenzar su servicio (el que tiene el nombre your_service_name ) y probar si está funcionando correctamente. Cabe señalar que el servicio se marcará como iniciado antes de que WEBrick finalice su procedimiento de arranque. Debe darle 1 minuto o más antes de intentar ingresar al servicio para verificar que esté funcionando correctamente.

2. usando mongrel:

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

primero instale la gema mongrel y mongrel_service

gem install mongrel gem install mongrel_service

luego crea el servicio

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

3. usando delgado:

Referencias

Instrucciones:

  1. La primera instalación es delgada (deberá instalar la gema del rack, si no está ya instalada)

    gem install rack gem install thin

  2. Siga los mismos pasos indicados para webrick, pero agregue otro valor llamado "AppDirectory". Esto es necesario para evitar el uso de c: / ruby ​​/ bin / thin.bat. Si solo apuntara al archivo bat, no podría detener el servicio.

    En HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/redmine_thin/Parameters agregue las siguientes claves:

    Aplicación: c: / ruby ​​/ bin / ruby.exe

    AppDirectory: c: / redmine

    AppParameters: c: / ruby ​​/ bin / thin start -p 4000 -e producción

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

Puede controlar cualquiera de sus servicios con los siguientes comandos:

net start redmine_xxx

net stop redmine_xxx

sc config redmine_xxx start = auto

sc config redmine_xxx start = auto dependency = MySql

sc borrar redmine_xxx



Para aplicaciones Rails 3.0.x (probado en 3.0.10 y Windows 7)

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($0)).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

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

coloca ambos archivos en el mismo directorio y ejecuta

ruby demo_daemon_ctl.rb install


Para las aplicaciones de Rails 4.0.x según lo sugerido por Bohdan, tenemos que reemplazar

CONFIG [''bindir''] con RbConfig :: CONFIG [''bindir'']

Remmber para: gem install win32-service


  • gem install win32-service
  • colocar debajo del código de Ruby en un archivo service.rb y actualizar la ruta REDMINE_DIR para que se ajuste a su instalación de Redmine
  • crear el servicio, por ejemplo con sc create redmine binPath= "C:/Ruby23-x64/bin/rubyw -CE:/www/redmine-3.3.2/ service.rb" donde E:/www/redmine-3.3.2/ es la ruta del directorio donde se encuentra el archivo service.rb y C:/Ruby23-x64/bin/rubyw su ruta de instalación de Ruby

begin require ''win32 / daemon'' incluye Win32

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

  • Tenga en cuenta que Process.spawn en service.rb usa la ruta completa.

Hace algún tiempo, traté de instalar Redmine en Windows también. Pero no pude hacerlo funcionar, probablemente debido a la falta de conocimiento de Rails .

Entonces descubrí Bitnami Redmine Stack . Tienen un instalador de Windows, que instala Redmine con todas las dependencias necesarias, y simplemente funciona .