... czyli jak szybko i bezproblemowo uzyskać działające Redmine oraz Tracks.
Poniższa notatka to zasadniczo wyciąg z kilku dokumentacji instalacyjnych. Publikuję, bo ilekroć musiałem przeprowadzić tą instalację, pozbieranie potrzebnych czynności kosztowało mnie kilka godzin.
Uwaga: nie programuję w Ruby on Rails, moje podejście tutaj to zainstalować, uruchomić, używać. Programista Rubiego zapewne pieściłby środowisko w inny sposób.
Redmine to przyjemny program do zarządzania projektem informatycznym (issue tracker, wiki, forum, podgląd kodu, ...) o którym parę ciepłych słów pisałem w zeszłym roku. Tracks to indywidualna lista zadań. Większość poniższego opisu powinna być przydatna także przy instalowaniu innych aplikacji Ruby on Rails.
Narzędzia
Wielokrotnie reklamowałem na tym blogu Nginksa ale za najbardziej bezproblemowy sposób uruchamiania aplikacji RoR uważam w tej chwili kombinację Apache, Phusion Passenger i Ruby Enterprise.
Ruby Enterprise to po prostu kompletna, dobrze przygotowana
dystrybucja Ruby w połączeniu z obszernym zestawem bibliotek, zawierająca
też trochę optymalizacji (zwłaszcza wykorzystania pamięci).
Phusion Passenger to inaczej mod_rails
- wydajny moduł
interfejsujący serwer WWW z aplikacjami RoR.
Phusion Passenger pojawił się niedawno także w wersji dla Nginksa. Nie miałem jeszcze czasu wypróbować tego rozwiązania (jest trochę kłopotliwe, bo wymaga instalowania zmodyfikowanego nginksa). Jeśli ktoś korzystał już z tej konfiguracji, chętnie poznałbym opinię na jej temat.
Opisywaną dalej instalację przeprowadzałem na Ubuntu 9.04, na 8.04 czy 8.10 powinna przebiegać bardzo podobnie.
Pliki do pobrania
Pobrać należy:
-
dystrybucję Ruby Enterprise ze strony autorów - ja wykorzystywałem plik ruby-enterprise_1.8.6-20090520_i386.deb
-
dystrybucje instalowanych aplikacji, w moim wypadku
tracks-1.7.zip
ze strony Tracks oraz redmine-0.8.4.tar.gz ze strony Redmine
Nie ma potrzeby pobierać dystrybucji Phusion Passengera, znajduje się ona w pakiecie Ruby Enterprise.
Elementy instalowane z pakietów
Instalujemy Apache
$ sudo apt-get install apache
Dowolny MPM powinien działać, ja testowałem wykorzystując domyślny (worker).
Jeśli Apache koegzystuje z innym webserwerem (np. nginksem), trzeba pamiętac
o przestawieniu go na inny port (/etc/apache2/ports.conf
i przegląd
/etc/apache2/sites-available
).
Ponadto do instalacji Phusion Passengera potrzebny jest kompilator oraz pliki nagłówkowe Apache. Wystarczy:
$ sudo apt-get install build-essential \
apache2-prefork-dev libapr1-dev
Instalacja Ruby Enterprise
Proste
$ sudo dpkg -i ruby-enterprise_1.8.6-20090520_i386.deb
Uwaga: najlepiej nie instalować przy tym żadnych elementów Rubiego czy
Rails z normalnej dystrybucji. Ewentualne brakujące biblioteki można
później doinstalowywać via gem install
.
Ruby Enterprise instaluje się w katalogu
/opt/ruby-enterprise
. Po instalacji warto dodać
/opt/ruby-enterprise/bin
do ścieżki, np. dopisując
ten katalog do PATH
w /etc/environment
.
Instalacja Phusion Passengera
W ramach instalacji Ruby Enterprise pojawia się między innymi skrypt
passenger-install-apache2-module
. Po prostu uruchamiamy go (mając
/opt/ruby-enterprise/bin
w ścieżce):
$ sudo -i
# export PATH=/opt/ruby-enterprise/bin:$PATH
# passenger-install-apache2-module
Skrypt może zaraportować brakujące pakiety (kompilator, nagłówki Apache itp). Sam podaje co trzeba doinstalować, np:
Welcome to the Phusion Passenger Apache 2 module installer, v2.2.2.
(...)
--------------------------------------------
Checking for required software...
* GNU C++ compiler... not found
* Ruby development headers... found
* OpenSSL support for Ruby... found
(...)
* Apache Portable Runtime Utility (APU) development headers... not found
Some required software is not installed.
(...)
--------------------------------------------
Installation instructions for required software
* To install GNU C++ compiler:
Please run apt-get install build-essential as root.
(...)
* To install Apache Portable Runtime Utility (APU) development headers:
Please download it from http://httpd.apache.org/
(APR Utility is an integrated part of Apache.)
Ostatnia uwaga jest myląca, niczego nie trzeba ściągać
ze strony Apache, w zupełności wystarcza pakiet libapr1-dev
.
O ile niczego nie brakowało, rozpoczyna się kilkuminutowa kompilacja zakończona sugestią:
--------------------------------------------
The Apache 2 module was successfully installed.
Please edit your Apache configuration file, and add these lines:
LoadModule passenger_module /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/passenger-2.2.2/ext/apache2/mod_passenger.so
PassengerRoot /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/passenger-2.2.2
PassengerRuby /opt/ruby-enterprise/bin/ruby
After you restart Apache, you are ready to deploy any number of Ruby on Rails
applications on Apache, without any further Ruby on Rails-specific
configuration!
Press ENTER to continue.
Robimy dokładnie to, ale nieco inaczej. Tworzymy plik /etc/apache2/mods-available/passenger.load
o treści:
LoadModule passenger_module /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/passenger-2.2.2/ext/apache2/mod_passenger.so
oraz /etc/apache2/mods-available/passenger.conf
o treści:
<IfModule mod_passenger.c>
PassengerRoot /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/passenger-2.2.2
PassengerRuby /opt/ruby-enterprise/bin/ruby
</IfModule>
a potem aktywujemy stworzone moduły przez
$ sudo a2enmod passenger
Uwaga: dyrektywa PassengerRuby
jest ważna, decyduje o tym z którego
Ruby korzysta Passenger. Można próbować instalować samego Passengera
i podawać tu ścieżkę do Ruby z dystrybucji.
Instalacja Tracks
Pobraną dystrybucję rozpakowujemy:
$ cd /apps
$ sudo unzip ~/tracks-1.7.zip
$ sudo ln -s tracks-1.7 tracks
$ sudo chown -R www-ruby.www-ruby \
tracks/public tracks/log tracks/config
Oczywiście umieszczenie aplikacji w /apps
jest tylko jedną z
możliwych konwencji, podobnie jak uruchamianie ich na koncie
www-ruby
(które przed powyższym trzeba założyć).
Dość istotna jest sprawa własności plików. Phusion Passenger
będzie uruchamiał aplikację na koncie właściciela pliku
config/environment.rb
(można tą konwencję nadmazać
na poziomie konfiguracji Apache, ale jest dosyć wygodna).
Aplikacja musi też miec prawo zapisywać log oraz tworzyć
pliki w podkatalogach tracks/public
.
Uruchomienie się aplikacji bez CSS i javascriptu to zwykle efekt braku praw zapisu do
public/stylesheets
orazpublic/javascripts
. Aplikacja (a raczej stos RoR) tworzy tam zagregowane (skonkatenowane) pliki, w starszych wersjach o nazwach typutracks_1225808747.css
w tu opisywanej w podkatalogucache
.
Baza danych
Tworzymy bazę danych dla aplikacji oraz konto jej właściciela. W wersji dla PostgreSQL:
$ sudo -u postgres createuser \
--no-superuser --no-createdb --no-createrole --pwprompt \
tracks
$ sudo -u postgres createdb \
--encoding utf-8 --owner tracks \
tracks "Baza Tracks"
(tu i baza, i konto noszą nazwę tracks
, oczywiście mogą być
dowolne inne).
Można używać także mysql albo sqlite.
Konfiguracja
Następnie konfigurujemy samą aplikację, czyli edytujemy
pliki w katalogu tracks/config
.
W pliku site.yml
wpisujemy coś losowego jako salt
oraz
ustawiamy time_zone
na "Warsaw"
.
Uwaga: przy upgrade aplikacji, przenoszeniu na inną maszynę itp
salt
trzeba zachować! Zmianasalt
unieważnia zapisane w bazie danych skróty hasła użytkowników.
W pliku database.yml
definiujemy charakterystykę połączenia
z bazą danych, np:
production:
adapter: postgresql
database: tracks
host: localhost
username: tracks
password: hasloPodanePrzyCreateUser
encoding: utf8
Stworzenie lub upgrade bazy danych
Uruchamiamy
$ cd tracks
$ rake db:migrate RAILS_ENV=production
Polecenie to tworzy potrzebne tabele bazodanowe a w razie upgrade modyfikuje strukturę tabel dostosowując je do nowej wersji.
LDAP (opcjonalnie)
Tracks ma opcję autoryzowania w LDAP (zamiast utrzymywania
osobnych haseł). Jest ona dosyć ograniczona: nie ma automatycznego
tworzenia użytkowników. Danej osobie musimy założyć konto
(o nazwie zgodnej z LDAPowym uid
), nadać tymczasowe hasło,
zalogować się na to konto i w preferencjach przestawić formę
autentyfikacji z hasła na LDAP, dopiero od tej chwili będzie
mogła się logować hasłem LDAPowym. Użytkownik próbujący się
logować bez tych przygotowań dostanie po prostu informację o błędnym
identyfikatorze lub haśle.
Zamiast tej ręcznej procedury można oczywiście stworzyć niezależny formularz, czy to bezpośrednio tworzący użytkowników w bazie danych, czy to używający do tego XML-owego API Tracks.
Albo dodać obsługę dynamicznego tworzenia użytkowników w ramach obsługi logowania (i przekazać jako patch autorom aplikacji).
Aby włączyć obsługę LDAP, edytujemy site.yml
:
- odkomentowujemy opcję
"ldap"
w ramachauthentication_schemes
, - dodajemy blok konfiguracji LDAP
Ten drugi może wyglądać następująco:
ldap:
library: 'net/ldap'
servers:
- 'ldap.firma.com'
use_ssl: true
login_format: 'uid=%s,ou=Accounts,dc=firma,dc=com'
Oczywiście adres a także format identyfikatora zależy
od wykorzystywanego serwera. Zamiast %s
zostanie wpisana
nazwa podana przez logującego się użytkownika.
Trzeba też doinstalować bibliotekę ruby-net-ldap
:
# gem install ruby-net-ldap
Konfiguracja Apache
Dodajemy serwis aplikacji w ramach konfiguracji Apache.
Na przykład, jeśli uruchamiamy ją jako osobny wirtualny
host na dedykowanym porcie, możemy stworzyć
plik /etc/apache2/sites-available/tracks
:
NameVirtualHost *:8080
<VirtualHost *:8080>
ServerName nazwa.local:8080
ServerAdmin "Jan.Kowalski@firma.com.pl"
DocumentRoot /apps/tracks/public
</VirtualHost>
a także dopisać port do /etc/apache2/ports.conf
. Konfiguracja
wirtualnego serwera rozróżnianego nazwą jest bardzo podobna.
Bardzo ważne jest, by DocumentRoot
wskazywał na katalog public
(a
nie np. główny katalog aplikacji)!
Reszta konfiguracji Apache (trochę dyrektyw rewrite
) znajduje się w
pliku public/.htaccess
.
Na koniec
$ sudo a2ensite tracks
$ sudo a2enmod rewrite
$ sudo invoke-rc.d apache2 restart
i nasza aplikacja powinna działać.
Diagnozowanie problemów
W razie problemów warto czasowo podnieść poziom logowania.
Robimy to wpisując w config/environments/production.rb
config.log_level = :debug
Instalacja Redmine
Instalacja Redmine przebiega bardzo podobnie i w sume zgodnie z podręcznikiem.
Podobnie jak wyżej rozpakowujemy kod i ustawiamy odpowiednie prawa własności:
$ cd /apps
$ sudo tar xzvf ~/redmine-0.8.4.tar.gz
$ sudo ln -s redmine-0.8.4 redmine
$ sudo chown -R www-ruby.www-ruby \
redmine/public redmine/log redmine/config
Baza danych
Tworzymy bazę danych i jej właściciela
$ sudo -u postgres createuser \
--no-superuser --no-createdb --no-createrole --pwprompt \
redmine
$ sudo -u postgres createdb \
--encoding utf-8 --owner redmine
redmine "Redmine"
Weryfikujemy poprawność składni dat:
$ psql --user redmine redmine
redmine=> SHOW DATESTYLE;
i jeśli wyjdzie coś innego niż ISO, MDY
, robimy:
redmine=> ALTER DATABASE "redmine" SET datestyle="ISO,MDY";
Konfiguracja
W katalogu redmine/config
edytujemy database.yml
, które
może wyglądać tak:
production:
adapter: postgresql
database: redmine
host: localhost
username: redmine
password: hasloPodanePrzyCreateUser
encoding: utf8
a także email.yml
:
production:
delivery_method: :smtp
smtp_settings:
address: firmowy.serwer.smtp
port: 25
domain: nasza.firma.pl
# authentication: :login
# user_name: user_smtp
# password: haslo_smtp
Stworzenie lub upgrade bazy danych
Po prostu
$ cd /apps/redmine
$ rake db:migrate RAILS_ENV="production"
Jeżeli jest to nowa instalacja, odpalamy także:
$ rake redmine:load_default_data RAILS_ENV="production"
To polecenie tworzy listę możliwych stanów błędu,
możliwych ról w projekcie, związanych z nimi uprawnień itp
(patrz redmine/lib/redmine/default_data/loader.rb
).
Wszystko to można później zmieniać ale znacznie wygodniej
zacząć od sensownej wersji i ją korygować, niż zaczynać od zera.
Wersje Redmine nowsze niż 0.8.* (tj. w tej chwili trunk
) wymagają też
$ rake config/initializers/session_store.rb
(przy braku tej operacji pojawią się błędy dotyczące braku secret potrzebnego do tworzenia ciasteczek)
Aktywacja Apache
Standardowo tworzymy /etc/apache2/sites-available/redmine
, np.
NameVirtualHost *:9090
<VirtualHost *:9090>
ServerName nasz.serwer:9090
ServerAdmin "Jan.Kowalski@firma.com"
DocumentRoot /apps/redmine/public
ErrorLog /var/log/apache2/redmine-error.log
LogLevel info
</VirtualHost>
po czym aktywujemy wirtualny serwer przez
$ sudo a2ensite redmine
$ sudo invoke-rc.d apache2 restart
Musimy też poprawić lub usunąć plik redmine/public/.htaccess
!
W domyślnej formie odpowiada on uruchamianiu aplikacji przez cgi lub
FastCGI, działaniu w Phusion Passengerze znajdujące się tam dyrektywy
Rewrite
najzwyczajniej szkodzą (błędy 404 przy próbie używania
aplikacji). Jeśli nie chcemy usuwać .htaccess
, trzeba przynajmniej
zakomentować - jak niżej - regułki
#RewriteRule ^$ index [QSA]
#RewriteRule ^([^.]+)$ $1.html [QSA]
I to już wszystko. Dalsza konfiguracja aplikacji (min. obsługa LDAP) odbywa się w ramach paneli administracyjnych, nie będę jej tu opisywał.
Alternatywy
Powyższy opis to instalacja na własnym serwerze (czy to firmowym, czy to VPSie lub podobnym). Zamiast tego można skorzystać z serwisów hostujących aplikacje Ruby. Jeden z moich znajomych jest zadowolony z Tracks hostowanych na MorphExchange.
A pełne prekonfigurowane pakiety obejmujące wszystkie elementy potrzebne do działania aplikacji (od Apache i bazy danych po same Tracks czy Redmine) udostępnia Bitnami. Niezbyt mi się podoba ten model instalacji izolujący aplikację od standardowej dystrybucji, ale czasem może być wygodny.