comment configurer une application Rails (Redmine) pour qu'elle s'exécute en tant que service sous Windows ?
-
22-08-2019 - |
Question
J'utilise Redmine comme gestionnaire de tickets et j'aimerais le configurer pour qu'il s'exécute automatiquement au démarrage de Windows.
Comment puis-je le configurer pour qu'il soit exécuté en tant que service ?
--
Je viens de poser la question pour le documenter, j'espère que quelqu'un pourra le trouver utile...
La solution
1.en utilisant une webrick :
réf: http://www.redmine.org/boards/1/topics/4123
Téléchargez et installez le Kit de ressources Windows NT à partir dehttp://www.microsoft.com/downloads/details.aspx?familyid=9d467a69-57ff-4ae7-96ee-b18c4790cffd&displaylang=en
Créez le service en exécutant cette commande :
path\INSTSRV.EXE your_service_name path\SRVANY.EXE
dans mon cas
path
est:"C:\Program Files\Windows NT Resource Kit\INSTSRV.EXE" redmine_webrick "C:\Program Files\Windows NT Resource Kit\SRVANY.EXE"
pourrait être aussi
C:\Program Files\Windows Resource Kits\Tools\
.Exécutez regedit (Démarrer -> Exécuter -> regedit)
Ajoutez la clé de registre suivante si elle n'y est pas déjà :
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\votre_nom_service
Faites un clic droit sur cette clé de registre et sélectionnez Nouveau -> Clé.Nomme le
Parameters
.Ajoutez deux valeurs à
Parameters
clé.Faites un clic droit sur la clé des paramètres, Nouveau -> Valeur de chaîne.Nomme leApplication
.Créez maintenant un autre nomméAppParameters
.Donnez-leur les valeurs suivantes :- Application:
PathToRuby.exe
, par exemple.C:\ruby\bin\Ruby.exe
- Paramètres d'application :
C:\RUBYAPP\script\server -e production
, oùRUBYAPP
est le répertoire qui contient le site Web Redmine.
Exemple:
C:\redmine\script\server -p 2000 -e production
(-p indique le port que Webrick écoutera, et -e l'environnement utilisé)- Application:
Vous pouvez maintenant accéder à Outils d'administration -> Services.Là, vous pouvez démarrer votre service (celui avec le nom your_service_name
) et testez s'il fonctionne correctement ou non.Il convient de noter que le service sera marqué comme démarré avant que WEBrick ne termine sa procédure de démarrage.Vous devez lui accorder environ 1 minute avant d'essayer d'accéder au service pour vérifier qu'il fonctionne correctement.
2.en utilisant bâtard :
réf: http://mongrel.rubyforge.org/wikiréf: http://mongrel.rubyforge.org/wiki/Win32
installez d'abord mongrel et mongrel_service gem
gem install mongrel
gem install mongrel_service
puis créez le service
mongrel_rails service::install -N redmine_mongrel -c c:\redmine -p 3000 -e production
3.en utilisant mince :
Les références:
- http://code.macournoyer.com/thin/
- http://www.astarbe.com/es/trucos/windows/srvany_convierte_una_aplicacion_en_servicio
Instructions:
Installez d'abord mince (vous devrez installer une gemme de rack, si ce n'est pas déjà installé)
gem install rack gem install thin
Suivez les mêmes étapes indiquées pour webrick, mais ajoutez une autre valeur nommée « AppDirectory ».Ceci est nécessaire pour éviter d'utiliser c: uby\bin hin.bat. Si je pointais simplement le fichier bat, je ne pourrais pas arrêter le service.
Dans
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\redmine_thin\Parameters
ajoutez les clés suivantes :Application:c: uby\bin uby.exe
Répertoire d'applications :c: edmine
Paramètres d'application :c: uby\bin hin start -p 4000 -e production
------------------------------------------------------------------------------------------
Vous pouvez contrôler n'importe lequel de vos services avec les commandes suivantes :
démarrage net redmine_xxx
arrêt net redmine_xxx
sc config redmine_xxx start = auto
sc config redmine_xxx start= dépendance automatique= MySql
sc supprimer redmine_xxx
Autres conseils
Pour Rails applications 3.0.x __gVirt_NP_NNS_NNPS<__ (testé sur 3.0.10 et 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
Placez les deux fichiers dans la même répertoire et exécutez
ruby demo_daemon_ctl.rb install
Il y a quelque temps, j'ai essayé d'installer Redmine sous Windows ainsi. Mais je ne pouvais pas le faire fonctionner, probablement en raison du manque de connaissances Rails .
Alors j'ai découvert Bitnami Redmine Stack . Ils ont un programme d'installation de Windows, qui installe Redmine avec toutes les dépendances nécessaires, Il fonctionne .
Pour Rails applications 4.0.x comme suggéré par Bohdan, nous devons remplacer
CONFIG [ 'bindir'] avec RbConfig :: CONFIG [ 'bindir']
Remmber à: gem install win32 service
-
gem install win32-service
- baisse ci-dessous le code Ruby dans un fichier service.rb et mise à jour chemin REDMINE_DIR pour adapter votre installation Redmine
- créer le service, par exemple avec
sc create redmine binPath= "C:\Ruby23-x64\bin\rubyw -C E:\www\redmine-3.3.2\ service.rb"
oùE:\www\redmine-3.3.2\
est le chemin du répertoire dans lequel le fichier est situé service.rb etC:\Ruby23-x64\bin\rubyw
votre chemin d'installation Ruby
commencer require 'win32 / démon' inclure 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
- Notez que Process.spawn dans la service.rb utiliser le chemin complet.
Espérons que cela vous aidera à tout le monde. Je défini le service Windows qui démarre le Redmine avec le serveur mince.
Utilisez http://nssm.cc/usage pour les fenêtres création de services. Définissez le chemin à ruby.exe, le répertoire de travail de votre Redmine et définir les paramètres de départ:
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