- Log dich mit ssh in den Server ein, auf dem die Rails Applikation laufen soll.
- Wenn du dich nicht als root angemeldet hast, werde jetzt root (su -)
- Stell sicher, dass ein Editor wie vi richtig funktioniert. Wenn man von Mac OS X auf einen Linux Rechner geht kann es manchmal Probleme geben. Auf Debian Systemen schafft da oft
apt-get install ncurses-term
Abhilfe. - Aktualisiere die verfuegbaren Pakete:
apt-get update
- Installiere folgende Pakete:
apt-get install mysql-server apt-get install ruby apt-get install ruby1.8-dev apt-get install rubygems apt-get install subversion apt-get install make apt-get install build-essential apt-get install curl apt-get install apache2
- Installiere folgende Ruby Gems:
gem install --include-dependencies rails gem install --include-dependencies capistrano gem install --include-dependencies mongrel (jeweils die neuste ruby version nehmen) gem install --include-dependencies mongrel_cluster
- Gehe nochmal sicher, dass alles aktuell ist:
gem update --system
Wenn du irgendwo den Fehler/usr/bin/gem:23: uninitialized constant Gem::GemRunner (NameError)
bekommst ist das damit zu loesen, folgende Zeile in /usr/bin/gem einzufuegen:require 'rubygems/gem_runner'
Und um den Fehlerundefined method `require_gem' for main:Object
spaeter beim Deployment zu vermeiden solltest du nochmalgem install --remote rake
ausfuehren. Wenn das nicht hilft, in /var/lib/gems/1.8/bin/rakerequire_gem 'rake', version
ingem 'rake', version
abaendern. - Jetzt musst du die Datenbank einrichten. Wir nehmen hier MySQL und der Einfachheit halber nenne ich in dieser Anleitung die Datenbank, den Datenbank Benutzer und die Rails-Anwendung "springenwerk".
Root Passwort setzen:
mysqladmin -u root password ein_passwort_meiner_wahl
(danach am besten die bash_history loeschen) Dann die Datenbank anlegen und die Berechtigung setzen:mysql -u root -p CREATE DATABASE springenwerk; GRANT ALL PRIVILEGES ON springenwerk.* TO 'springenwerk'@'localhost' IDENTIFIED BY 'ein_password_meiner_wahl' WITH GRANT OPTION;
Die Angaben fuer die Produktions-Datenbank (Name, Username und Passwort) muessen den Angaben in der app/config/database.yml Datei der Rails Anwendung entsprechen. Jetzt kannst du den Mysql Client mit 'exit' verlassen. - Die ausfuehrbaren Ruby Gems willst du jetzt natuerlich gerne in deinem Pfad haben. Also
in der /etc/profile
/var/lib/gems/1.8/bin
an die PATH Variable haengen. Das kann man so machen:
PATH=$PATH:/var/lib/gems/1.8/bin
Du musst nur aufpassen, dass die das vor die Zeile "export PATH" schreibst. - Dann die Aenderungen in der aktuellen Session nutzbar machen:
source /etc/profile
Wenn du dannrails -v
ausfuehren kannst hat alles geklappt. - Jetzt solltest du einen eigenen User fuer deine Rails Anwendung anlegen:
useradd -m springenwerk
und das Passwort setzten:passwd springenwerk
Und ihn zu den sudoers packen:visudo
und dann unten folgende Zeile hinzufuegen (natuerlich "springenwerk" wieder mit deinem Produktions-Usernamen ersetzen):springenwerk ALL=(ALL) ALL
- Da sich Capistrano per SSH einloggt aber auch ein gewisse Benutzerumgebung braucht (z.B. den PATH) musst du in die /etc/ssh/sshd_config folgende Zeilen einfuegen:
# for capistrano PermitUserEnvironment yes
- Dann SSHD neu starten:
/etc/init.d/ssh restart
- In /home/springenwerk/.ssh/environment (ggf. ".ssh" Verzeichnis und Datei anlegen) folgende Zeilen einfuegen:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/var/lib/gems/1.8/bin RUBYOPT=rubygems
- Jetzt musst du auf dem CLIENT Capistrano und Mongrel Cluster installieren (ich gehe davon aus, dass Ruby und Rails schon installiert sind)
sudo gem install capistrano sudo gem install capistrano-ext sudo gem install mongrel_cluster
Ab Mac OS X Leopard ist capistrano schon dabei, aber stelle mitsudo gem update capistrano
sicher, dass du mindestens Version 2.1 hast. - Wechsle in dein Rails Projekt Verzeichnis:
cd /Users/johannes/Code/springenwerk/trunk/springenwerk
- Jetzt erstellst du eine Konfigurationsdatei fuer den Mongrel Cluster:
mongrel_rails cluster::configure -e production -p 8000 -a 127.0.0.1 -N 2 -c /home/springenwerk/springenwerk/current
-p 8000 sagt, dass die Server ab Port 8000 lauschen, -N 2 sagt, dass es zwei Instanzen geben wird (also eine auf Port 8000, eine auf 8001) und mit -c gibt man das Verzeichnis an, wo auf dem PRODUKTIONSSERVER die Applikation liegen wird (in diesem Fall ein Unterverzeichnis, das so heisst wie die Applikation im Home-Verzeichnis des Users, den wir angelegt haben (welcher auch so heisst wie die Applikation) und mit dem Zusatz "current". Das musst da stehen, denn das ist ein Symlink, den Capistrano anlegt und der immer auf die aktuelle Version zeigt. - Jetzt musst du dein Rails Projekt capistranofizieren ;-). Wechsle in dein Rails Projekt Verzeichnis:
cd /Users/johannes/Code/springenwerk/trunk/springenwerk
und fuehre capify aus:capify .
- Oeffne jetzt config/deploy.rb in deinem Editor und passe die Datei so an, dass sie so aussieht (mit deinen User- und Projektnamen und Passwoertern natuerlich):
require 'mongrel_cluster/recipes' default_run_options[:pty] = true # to make sure password prompts are forwarded to you, the user set :application, "springenwerk" set :repository_url, "svn://DEIN_SVN_USER@DEIN_SVN_SERVER/springenwerk/trunk/springenwerk" if ENV['svn_prompt'] and ENV['svn_prompt'] == '1' set :svn_user, Proc.new { Capistrano::CLI.password_prompt('SVN User: ') } set :svn_password, Proc.new { Capistrano::CLI.password_prompt('SVN Password: ') } set :repository, Proc.new { "--username #{svn_user} --password #{svn_password} #{repository_url}" } else set :repository, repository_url end set :deploy_to, "/home/#{application}/#{application}" # defaults to "/u/apps/#{application}" set :deploy_via, "export" set :user, application # in our case, the user and the application have the same name. set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml" role :app, "DEIN_PRODUCTION_SERVER" role :web, "DEIN_PRODUCTION_SERVER" role :db, "DEIN_PRODUCTION_SERVER", :primary => true # Task to copy production db config after deployment task :after_update_code, :roles => :app do db_config = "#{shared_path}/config/database.yml.production" run "cp #{db_config} #{release_path}/config/database.yml" end
Die Datei werde ich hier nicht gross erklaeren, dazu gibt es andere Stellen. Diese deploy.rb Datei hat aber eine kleine Besonderheit (Danke an Jonathan). Da Subversion natuerlich einen Benutzernamen und ein Passwort erwartet wird normalerweise empfohlen, einmal irgendwo auf dem Produktionsserver das Rails Projekt auszuchecken, damit die Credentials gecachet werden und Capistrano nicht mehr nach SVN Benutzernamen und Passwort fragt. Das koennen wir uns jetzt sparen. Wir koennen naemlich jetzt angeben, dass Capistrano uns beim ersten Mal einfach nach den Zugangsdaten fuer SVN fragt. Dazu gleich mehr. - Jetzt kann Capistrano die Verzeichnisse auf dem Produktionsserver anlegen. Auf deinem CLIENT fuehre folgendes aus:
cap deploy:setup
- Stelle die neuen Konfigurationsdateien unter Versionskontrolle und checke sie ein:
svn add Capfile config/mongrel_cluster.yml config/deploy.rb svn ci -m "capistrano config"
- Du willst aus Sicherheitsgruenden deine Produktionsdatenbank Passwoerter nicht ins SVN einchecken. Deshalb solltest du eine Datei namens database.yml.production anlegen, die die
Zugangsdaten fuer deine Produktionsdatenbank enthaelt. Unser "after_update_code" Task in deploy.rb erwartet diese Datei und kopiert sie dann ueber die ausgecheckte database.yml. Zum Beispiel koennte sie so aussehen:
development: adapter: mysql database: springenwerk_development username: root password: root host: localhost socket: /Applications/MAMP/tmp/mysql/mysql.sock # Warning: The database defined as 'test' will be erased and # re-generated from your development database when you run 'rake'. # Do not set this db to the same as development or production. test: adapter: mysql database: springenwerk_test username: root password: root host: localhost production: adapter: mysql database: springenwerk username: springenwerk password: DEIN_PASSWORT host: localhost socket: /var/run/mysqld/mysqld.sock
Diese packst du auf dem Produktionsserver in folgendes Verzeichnis:/home/springenwerk/springenwerk/shared/config
Das config Verzeichnis musst du vorher anlegen. - Jetzt kannst du mit Capistrano von deinem CLIENT ein Erst-Deployment (cold deployment) durchfuehren (in deinem Rails Projektverzeichnis)
svn_prompt=1 cap deploy:cold
"svn_prompt" ist einen Umgebungsvariable, die unserem deploy.rb Skript sagt, dass es nach den SVN Zugangsdaten fragen soll. Denke daran, dass wenn Capistrano dich nach dem Passwort fuer deinen Produktionsserver fragt das Passwort fuer den nicht-root User (in diesem Beispiel "springenwerk") fragt! Achte darauf, dass es keine Fehler gibt, am Ende solltecommand finished
stehen. - Pruefe auf dem SERVER, ob die Mongrel Dienste laufen:
curl -I http://127.0.0.1:8000
Wenn Mongrel laeuft, sollte die Ausgabe ungefaehr so aussehen:HTTP/1.1 302 Moved Temporarily Connection: close Date: Wed, 06 Feb 2008 11:42:33 GMT Set-Cookie: _springenwerk_session_id=f4a9b408f36d0df7561fd778e46d2c62; path=/ Status: 302 Found Location: http://127.0.0.1:8000/session/new Cache-Control: no-cache Server: Mongrel 1.1.3 Content-Type: text/html; charset=utf-8 Content-Length: 101
Sehr gut. Jetzt musst du nur noch Apache als Loadbalancer einrichten. Ein Kinderspiel ;-) - Ok, Apache. Bevor du die folgenden Sachen machst, ein kleiner Disclaimer: ich bin kein Apache-Config-Profi. Es kann gut sein, dass es elegantere Wege gibt, das gute Stueck zu konfigurieren. Alle Hinweise die zur Ergreifung des Taeters fuehren werden sehr geschaetzt.
Ans Ende von /etc/apache2/apache2.conf folgendes anfuegen (im vi mit G ans Ende der Datei springen):
<Proxy balancer://mongrel_cluster> BalancerMember http://127.0.0.1:8000 BalancerMember http://127.0.0.1:8001 </Proxy>
Der Inhalt der /etc/apache2/sites-available/000-default Datei muss so aussehen (ich gehe in dem Beispiel davon aus, dass der Apache nur fuer deine Rails Anwendung benutzt wird):<VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot /home/springenwerk/springenwerk/current/public <Directory /home/springenwerk/springenwerk/current/public> Options FollowSymLinks AllowOverride None Order allow,deny allow from all </Directory> RewriteEngine On RewriteLog /var/log/apache2/rewrite.log RewriteLogLevel 9 RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f RewriteCond %{SCRIPT_FILENAME} !maintenance.html RewriteRule ^.*$ /system/maintenance.html [L] RewriteRule ^/$ /index.html [QSA] RewriteRule ^([^.]+)$ $1.html [QSA] RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f RewriteRule ^/(.*)$ balancer://mongrel_cluster%{REQUEST_URI} [P,QSA,L] ErrorLog /var/log/apache2/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog /var/log/apache2/access.log combined ServerSignature Off </VirtualHost>
- Dann musst du in /etc/apache2/mods-enabled folgende Symlinks anlegen:
ln -s ../mods-available/proxy_balancer.load ln -s ../mods-available/proxy.conf ln -s ../mods-available/proxy_http.load ln -s ../mods-available/proxy.load ln -s ../mods-available/rewrite.load
Der Inhalt der proxy.conf muss so aussehen:<IfModule mod_proxy.c> #turning ProxyRequests on and allowing proxying from all may allow #spammers to use your proxy to send email. ProxyRequests Off <Proxy *> AddDefaultCharset off Order allow,deny Allow from all </Proxy> # Enable/disable the handling of HTTP/1.1 "Via:" headers. # ("Full" adds the server version; "Block" removes all outgoing Via: headers) # Set to one of: Off | On | Full | Block ProxyVia On </IfModule>
- Dann nur noch Apache neu starten:
/etc/init.d/apache2 restart
- Feierabend. Das wars.
cap deploybzw
cap deploy:migrationsausfuehren wenn es neue Datenbankmigrationen gibt. Capistrano macht dann den Rest! Bitte benutze die Kommentarfunktion wenn du beim Folgen dieser Schritte ein paar Tipps oder Probleme gefunden hast. Grosser Dank gilt noch dem grossartigen Tutorial von Coda. Da gibt es noch sehr viel Hintergrundinfos. Ich wollte das hier nicht alles wiederholen, sondern es eher kurz und knapp halten. Ich hoffe, dass es ganz hilfreich ist. Wenn das der Fall ist würde ich mich sehr über eine Empfehlung freuen:
Danke!
Comments
M said...
hallo johannes ...
vielen dank für die tolle anleitung!
leider habe ich ein problem:
- bis zu "cap deploy:check" sieht alles gut aus
- auch "cap deploy:setup" läuft ohne fehler ab
- bei "cap deploy:cold" erhalte ich allerdings folgende fehlermeldung:
-----
root@ubu804s-1:/var/www/rails/todo# cap deploy:cold
* executing `deploy:cold'
* executing `deploy:update'
** transaction: start
* executing `deploy:update_code'
* executing "svn export -q -r13 file:///subversion/projekte/todo/trunk /var/www/rails/todo/releases/20081102094125 && (echo 13 > /var/www/rails/todo/releases/20081102094125/REVISION)"
servers: ["192.168.2.44"]
Password:
[192.168.2.44] executing command
** [192.168.2.44 :: err] svn: No such revision 13
command finished
*** [deploy:update_code] rolling back
* executing "rm -rf /var/www/rails/todo/releases/20081102094125; true"
servers: ["192.168.2.44"]
[192.168.2.44] executing command
command finished
failed: "sh -c \"svn export -q -r13 file:///subversion/projekte/todo/trunk /var/www/rails/todo/releases/20081102094125 && (echo 13 > /var/www/rails/todo/releases/20081102094125/REVISION)\"" on 192.168.2.44
root@ubu804s-1:/var/www/rails/todo#
-----
was mache ich falsch? wo finde ich hilfe?
vielen dank vorab für deine unterstützung!
gruss markus
Johannes Fahrenkrug said...
Hallo Markus,
November 03, 2008 06:51 AMhmmm... das sieht so aus als ob das SVN auf deinem Server in dem Repository unter file:///subversion/projekte/todo/trunk keine Revision mit der Nr 13 finden kann. Kann es sein, dass du das SVN Repository bei dir auf deiner Lokalen Entwicklungsmaschine laufen hast, sodass der Server, auf dem die Anwendung deployt werden soll, da nicht rankommt?
Du muss dein SVN Repository so aufsetzten, dass es von deiner Entwicklungsmaschine und von deinem Server erreicht werden kann...
ODER...
du nimmst die copy deploy stategy:
set :deploy_via, :copy
set :copy_strategy, :export
dann wir der kram lokal auf deiner entwicklungsmaschine exportiert, getart und gegzipt und dann per sftp auf deinen server geschoben. Der Server braucht dann keinen SVN Zugang mehr. Siehe auch http://www.capify.org/upgrade/whats-new
Viel Erfolg!
- Johannes