Ruby on Rails III: instalacja

Opublikował siefca so 27 gru 2008 12:58:06 GMT

Ruby on Rails Opiszę przyjemną instalację RoR na systemie zgodnym z POSIX. Przy okazji poczynię tu kilka założeń, które zdeterminują trochę architekturę, to znaczy wybiorę konkretne wersje i konkretne oprogramowanie. Ruby on Rails, jako serwer aplikacji, zwykle „chowa się” za jakimś serwerem WWW, nawet jeśli korzysta z własnego, któremu na imię WEBrick. Spotyka się instalacje korzystające z technologii CGI lub FastCGI, spotyka się również kompaktowe rozwiązania polegające na użyciu specjalnego modułu serwera Apache o nazwie Passenger.

Instalacja

Wszystko zależy od upodobań i potrzeb użytkownika. Moim celem nie jest omawianie wszystkich możliwych kombinacji, ponieważ chciałbym szybko przejść do sedna, dlatego wybiorę konfigurację i w oparciu o nią pokażę, jak instalować Rails. Nie będą to ustawienia wymarzone, ale statystycznie mające największe szanse na zadziałanie. Gdybym miał typować komponenty do wydajnego środowiska produkcyjnego to wybrałbym serwer webowy Nginx odwołujący się do Thina, bazę Oracle albo PostgreSQL i użył jRails (jQuery on Rails) zamiast prototype.js do obsługi fajerwerków w JavaScripcie.

W celach szkoleniowych i drobno-produkcyjnych używam takiej konfiguracji:

  • system operacyjny: GNU/Linux
  • interpreter: Ruby
  • serwer WWW: Apache 2 lub wbudowany WEBrick
  • łączność z serwerem Apache: moduł Phusion Passenger (mod_rails) dla Apache’a
  • baza danych: MySQL
  • edytor programisty: TextMate (lub jaki wolisz)

Kolejne założenie dotyczy wersji. Będziemy instalować interpreter języka Ruby samodzielnie, a nie z pakietu. Chodzi nam o uniknięcie niespodzianek związanych z zainstalowaniem przez managera pakietów wersji interpretera niekompatybilnej z RoR i o większą kontrolę.

Polecam instalację RoR również na desktopie, czy innym komputerze, którego używasz często. W kolejnych odcinkach wyjaśnię, w jaki sposób tworzyć aplikację RoR z wykorzystaniem Vlada, czyli jak automatycznie wysyłać zmiany na serwer używając systemu kontroli wersji. Wtedy praca wygląda tak, że na desktopie robisz aplikację i sprawdzasz jak działa, natomiast co jakiś czas wysyłasz zmiany na host, który jest wspólnym systemem testowym lub produkcyjnym.

Instalacja interpretera

Instalacja interpretera polega na pobraniu źródeł, wypakowaniu ich, wywołaniu skryptu automatycznej konfiguracji, kompilacji i zainstalowaniu w odpowiednim katalogu. Tym katalogiem będzie /usr/local/ruby. Niektóre czynności wymagać mogą uprawnień administratora systemu.

Upewnij się, że w systemie masz pliki nagłówkowe dla bibliotek (g)libc (glibc-dev), pthread (libpthread-dev), OpenSSL (openssl-dev), ncurses, readline (libreadline-dev), MySQL (libmysql-dev), a także narzędzia do kompilacji: gcc, automake, m4, etc. Następnie pobierz stabilną, zalecaną wersję ze strony http://www.ruby-lang.org/pl/downloads/ do stworzonego katalogu i wypakuj:

  mkdir r && cd r
  wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p72.tar.gz
  tar xvzf ruby-1.8.7-p72.tar.gz

Potem wejdź do katalogu ze źródłami i uruchom tam skrypt konfigurujący i kompilujący. Dobra zasada: nie kompiluj z roota.

Zmień wartość opcji march na taką, która odpowiada Twojemu procesorowi lub usuń opcję, jeśli nie wiesz, jaki ma on symbol. Jeśli chcesz optymalizować, to zerknij na http://en.gentoo-wiki.com/wiki/Safe_Cflags/AMD. Jeśli masz kompilator gcc w wersji co najmniej 4.3 (aby poznać wersję napisz: gcc --version) to możesz zostawić flagę -march=native – jest to zalecane ustawnienie. Jeśli masz starszy kompilator, to zrezygnuj z optymalizacji lub skorzystaj z podanego wcześniej odnośnika, aby ustawić odpowiednią opcję.

A więc uruchamiamy w katalogu ze źródłami proces autokonfiguracji:

  cd ruby-1.8.7-p72
  CFLAGS="-march=native -O2 -pipe -fomit-frame-pointer"
  export CFLAGS
  ./configure --prefix=/usr/local/ruby --enable-pthread \
              --enable-shared --with-readline-dir=/usr \
              --enable-install-doc

Uwaga: jeśli instalujesz na systemie Mac OS X, to CFLAGS ustaw inaczej:

  cd ruby-1.8.7-p72
  CFLAGS="-D_XOPEN_SOURCE=1 -O2 -pipe -fomit-frame-pointer \
          -I/sw/include -I/sw/include -I/opt/local/include \
          -L/sw/lib -L/opt/local/lib"
  export CFLAGS
  ./configure --prefix=/usr/local/ruby --enable-pthread \
              --enable-shared --with-readline-dir=/usr \
              --enable-install-doc

Gdyby powyższy skrypt nie zadziałał, to doinstaluj brakujące pakiety z plikami nagłówkowymi (ich nazwy zwykle kończą się na -dev lub -devel). W przypadku wydania 1.9 interpretera należy usunąć --with-readline-dir.

Jeśli wszystko poszło dobrze to przeprowadź kompilację:

  make

Jeśli wciąż wszystko gra, to stań się superużytkownikiem i zainstaluj skompilowany interpreter w /usr/local/ruby/:

  sudo make install

Sprawdź czy to działa pisząc: /usr/local/ruby/bin/ruby --version. Jeśli tak jest, to jako superużytkownik przenieś katalog ze źródłami Ruby’ego do /usr/src/:

  sudo make clean
  cd ..
  sudo mv ruby-1.8.7-p72/ /usr/src/

Instalacja RubyGems

RubyGems to narzędzie służące do dystrybuowania i instalowania paczek zawierających moduły i rozszerzenia języka Ruby. Przypomina perlowego CPAN-a lub managery pakietów znane z wielu dystrybucji systemu GNU/Linux. Używając polecenia gem zainstalujemy Ruby on Rails i odpowiedni moduł serwera Apache. Ale żeby instalować gemy – bo tak nazywa się rozprowadzane za pomocą RubyGems paczki oprogramowania – najpierw trzeba zainstalować same Gems.

Będąc dalej w stworzonym poprzednio tymczasowym katalogu pobierz pakiet RubyGems ze strony http://rubyforge.org/frs/?group_id=126, skompiluj go i zainstaluj, a następnie spróbuj zaktualizować do najnowszego wydania:

  wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz
  tar xvzf rubygems-1.3.1.tgz
  cd rubygems-1.3.1
  CFLAGS="-march=native -O2 -pipe -fomit-frame-pointer"
  export CFLAGS
  sudo /usr/local/ruby/bin/ruby ./setup.rb
  sudo /usr/local/ruby/bin/gem update --system

Posprzątaj po źródłach:

  cd ..
  sudo mv rubygems-1.3.1/ /usr/src/

Wersjonowanie gemów

RubyGems i język Ruby mają ciekawe mechanizmy zarządzania wersjami pakietów i modułów. Możesz mieć w systemie zainstalowanych kilka różnych wydań tego samego gema, a potem używając go w swoim programie napisanym w Ruby jesteś w stanie wybrać, o jakie wydanie Ci chodzi. Dzięki temu łatwiej uniknąć kłopotów wynikających z aktualizacji. Polecenie gem oferuje nam w tym celu opcję -v.

W kolejnych odcinkach tej serii zobaczysz, że konwencja zapamiętywania właściwej wersji komponentów jest dziedziczona przez środowisko Ruby on Rails i dzięki tej właściwości możesz przenosić swoje aplikacje i zarządzać ich zależnościami bez obaw o konflikty edycji zależnych modułów.

Instalacja Ruby on Rails

Instalując RoR będziemy korzystali z RubyGems. Zarządzenie pakietami w Gems ma tę zaletę, że można wytypować wersję przeznaczoną do użytku. Ta właściwość przydaje się, gdy jakieś aplikacje zostały napisane z myślą o konkretnej wersji Rails. Jednak aby być na bieżąco zainstalujemy sugerowane wydanie RoR i nie będziemy specyfikowali konkretnego numeru edycji. Do poprawnej pracy środowisko Rails potrzebuje przynajmniej jednego działającego interfejsu łączącego z bazą danych. Ponieważ założyłem, że będzie to MySQL i –jak zakładam – w swoim systemie masz odpowiednie biblioteki oraz pliki nagłówkowe, to instalacja dodatkowych modułów nie powinna być problemem. Zaczynamy!

Zainstaluj biblioteki i pliki nagłówkowe, które będą potrzebne niektórym gemom, na przykład obsługującym łączność z bazą MySQL. Warto też wcześniej zainstalować biblioteki obsługujące bazę sqlite i sqlite3. Po co nam ona? Jest ona często używana w celach testowych, zachowuje się relacyjnie, a bazy zakłada w plikach.

W Debianie wykonaj:

  sudo apt-get install libmysqlclient15-dev sqlite3 \
                       sqlite libsqlite3-dev libsqlite0-dev

W Gentoo:

  sudo emerge --ask dev-db/sqlite
  sudo USE="minimal" emerge --ask dev-db/mysql

W PLD:

  sudo poldek -i mysql-devel sqlite-devel sqlite3-devel

W Mac OS-ie X (dla użytkowników narzędzia fink):

  sudo fink install  mysql-dev mysql-client sqlite sqlite3 sqlite-dev sqlite3-dev

Następnie zainstaluj gemy, które przydadzą się środowisku RoR i Tobie.

   sudo /usr/local/ruby/bin/gem install rake rdoc jdbc-mysql mysql \
     dbd-mysql activerecord-jdbcmysql-adapter \
     sqlite-ruby sqlite3-ruby termios rspec \
     tzinfo units mime-types RedCloth sake

W systemie Mac OS X i bazy MySQL instalowanej z użyciem fink gem ją obsługujący instaluje się poleceniem:

   sudo /usr/local/ruby/bin/gem install mysql -- \
    --with-mysql-dir=/sw/bin/mysql \
    --with-mysql-include=/sw/include/mysql \
    --with-mysql-lib=/sw/lib/mysql \
    --with-mysql-config=/sw/bin/mysql_config

A gem obsługujący SQLite (w Mac OS X) tak:

  sudo /usr/local/ruby/bin/gem install sqlite -- \
    --with-sqlite-include=/sw/include \
    --with-sqlite-lib=/sw/lib   

W przypadku samodzielnej instalacji MySQL-a (kompilowanego ze źródeł) wygląda to tak:

   sudo /usr/local/ruby/bin/gem install mysql -- \
    --with-mysql-dir=/usr/local/mysql
    --with-mysql-include=/usr/local/mysql/include/
    --with-mysql-lib=/usr/local/mysql/lib/
    --with-mysql-config=/usr/local/mysql/bin/mysql_config

I w końcu czas na Ruby on Rails.

   sudo /usr/local/ruby/bin/gem install rails

Udanej instalacji towarzyszy zwykle wyjście podobne do przedstawionego:

Successfully installed activesupport-2.2.2
Successfully installed activerecord-2.2.2
Successfully installed actionpack-2.2.2
Successfully installed actionmailer-2.2.2
Successfully installed activeresource-2.2.2
Successfully installed rails-2.2.2
6 gems installed

Gdyby podczas renderowania dokumentacji wystąpiły jakieś kłopoty i przez to gem nie chciałby się zainstalować, to ponów polecenie, ale na końcu dopisz: --no-ri --no-rdoc. Oto przykład takiej usterki:

Installing ri documentation for activeresource-2.2.2...
/usr/local/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:
in gem_original_require': no such file to load -- readline (LoadError)
from /usr/local/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31 :in
require’
from /usr/local/ruby/lib/ruby/gems/1.8/gems/rdoc-2.2.1/lib/rdoc/ri/display.rb:6
[…]

Ale po poniższym wywołaniu instalator już nie zgłasza błędów:

   sudo /usr/local/ruby/bin/gem install activeresource --no-ri

I raportuje:

Successfully installed activeresource-2.2.2
1 gem installed
Installing RDoc documentation for activeresource-2.2.2...

Instalacja serwera Apache

Uwaga: Jeśli nie chcesz używać serwera Apache, a w zamian ręcznie uruchamiać wbudowany, mały serwer WEBrick, to możesz pominąć tą sekcję.

Serwer Apache będzie witał klientów, rozmawiał z nimi protokołem HTTP, a dialog przekazywał do Rails, natomiast baza MySQL będzie zapleczem do przechowywania danych naszych aplikacji. Instalować je można z pakietów lub samodzielnie ze źródeł. Żeby nie przedłużać, tylko pokażę jak robię to w Debianie i w Gentoo.

Serwer Apache wraz z plikami potrzebnymi do kompilowania dodatkowych modułów instaluję z pakietu lub używając pakietów źródłowych.

W Debianie:

  sudo apt-get install apache2-mpm-itk libapr1-dev libaprutil1-dev \
                       apache2-prefork-dev

W Gentoo:

Do pliku /etc/make.conf dopisuję:

 APACHE2_MODULES="authn_alias authn_default authn_anon \
        authn_dbm dav_fs dav disk_cache ext_filter dav_lock deflate cache \
        headers env actions mime mime_magic authz_groupfile \
        authz_owner authz_user authz_host autoindex auth_basic \
        auth_digest authn_file alias dir proxy filter proxy_balancer \
        proxy_connect proxy_ftp proxy_http mem_cache \
        vhost_alias negotiation cgi info logio speling setenvif status \
        expires file_cache include rewrite log_config unique_id \
        userdir usertrack  authz_dbm  authz_default"

 APACHE2_MPMS="itk"

A potem robię:

   sudo emerge --ask apache-tools apache

Instalacja Phusion Passengera

Uwaga: Jeśli nie chcesz używać serwera Apache, a w zamian ręcznie uruchamiać wbudowany, mały serwer WEBrick, to możesz pominąć tą sekcję.

Instalacja modułu Apache’a służącego do współpracy z RoR jest przejrzyście opisana na stronie Passengera. W zasadzie to, co trzeba zrobić można przedstawić w kilku linijkach. Zauważ, że ustawiam zmienną środowiskową PATH, aby skrypt budujący moduł wiedział, gdzie szukać naszej instalacji interpretera Ruby i zainstalowanych gemów.

  PATH=/usr/local/ruby/bin:"${PATH}"
  export PATH

  sudo gem install  fastthread
  sudo gem install  rack
  sudo gem install  passenger --no-ri --no-rdoc
  sudo passenger-install-apache2-module

Pozostało tylko dodać klauzulę ładującą odpowiednie moduły do konfiguracji serwera Apache. W mojej instalacji tworzę po prostu plik /etc/apache2/mods-available/rails.load, a w nim:

   LoadModule passenger_module MODUŁ
   PassengerRoot /usr/local/ruby/lib/ruby/gems/1.8/gems/passenger-2.0.6
   PassengerRuby /usr/local/ruby/bin/ruby

Słowo MODUŁ trzeba zastąpić ścieżką:

/usr/local/ruby/lib/ruby/gems/1.8/gems/passenger-2.0.6/ext/apache2/mod_passenger.so

Potem tworzę symboliczne dowiązanie:

  cd /etc/apache2/mods-enabled
  ln -s ../mods-available/rails.load

…i restartuję Apache’a. Jeśli w Twojej instalacji nie istnieją takie katalogi, to po prostu dopisz powyższe klauzule konfiguracyjne tam gdzie trzeba (np. w /etc/apache2/httpd.conf).

Instalacja bazy MySQL

Zainstaluj bazę z pakietu lub ze źródeł. Zakładam, że potrafisz tworzyć bazy danych i nadawać uprawnienia użytkownikom bazodanowym. Jeśli nie potrafisz, to tutaj znajduje się podręcznik po polsku. Bazę możesz zainstalować na tej samej lub na innej maszynie. Osobiście, tam gdzie to możliwe, robię sobie wirtualne serwery i separuję serwer WWW, serwer aplikacji i serwer bazy danych.

Instalacja w Gentoo:

  sudo emerge --ask dev-db/mysql
  sudo emerge --config dev-db/mysql

Instalacja w Debianie:

  sudo apt-get install mysql-server mysql-client

Pakiet zawierający klienta bazy MySQL (mysql-client) możesz również zainstalować na maszynie, na której zainstalowane są Ruby on Rails, aby w razie czego mieć interfejs pozwalający na łączność z bazą. Jeśli baza będzie zainstalowana na tym samym systemie co RoR, to masz jedną instalację pakietu z głowy. :-)

Konfiguracja

Po instalacji pora na konfigurację. W zasadzie musimy upewnić się, że działa serwer Apache i baza MySQL i są one tak ustawione, żeby przykładowa aplikacja RoR miała z nimi łączność.

Zakładanie bazy

Aplikacja będzie korzystała z bazy danych, którą założymy. W tym celu użyjemy klienta MySQL wywoływanego na systemie, na którym działa baza:

  mysql -u root -p

W jego interfejsie wpiszemy polecenia zakładające nie tylko bazę (o nazwie rbaza), ale też użytkownika z dostępem do niej:

  CREATE DATABASE rbaza;
  GRANT SELECT,INSERT,UPDATE,DELETE,CREATE
        ON rbaza.*
        TO 'ruser'@'localhost' IDENTIFIED BY 'haslo';
  FLUSH PRIVILEGES;

W miejsce łańcucha haslo podaj hasło, które będzie przypisane do użytkownika ruser. Jeśli baza jest na innej maszynie niż RoR, to wyraz localhost zastąp nazwą hosta lub jego adresem IP. Jeśli wybierzesz nazwę, to upewnij się, że na systemie bazy jest ona dopisana do pliku /etc/hosts, aby nie polegać na zawodnym czasem systemie DNS.

Zakładanie wirtualnego hosta

Uwaga: Jeśli nie chcesz używać serwera Apache, a w zamian ręcznie uruchamiać wbudowany, mały serwer WEBrick, to możesz pominąć poniższe instrukcje.

Kolejny krok to skonfigurowanie serwera Apache w taki sposób, aby obsługiwał wirtualnego hosta. Host wirtualny to identyfikowany przez nazwę domenową lub adres IP, udostępniany przez serwer zasób związany z konkretną ścieżką systemu plików (np. katalogiem zawierającym dokumenty HTML) lub z mechanizmem komunikacji międzyprocesowej (np. gniazdo dziedziny Uniksa czy gniazdo sieciowe kierujące do innego procesu usługowego). W zależności od dystrybucji systemu i w zależności od tego, czy korzystasz z Apache’a kompilowanego samodzielnie, czy instalowanego z pakietu, konfiguracja wirtualnych hostów może znajdować się w różnych miejscach. W Debianie, aby zdefiniowań nowy host wirtualny rozpoznawany po nazwie DNS, należy utworzyć plik /etc/apache2/sites-available/rails o takiej zawartości:

NameVirtualHost *:80  # potrzebne tylko raz

<VirtualHost *:80>
        ServerName localhost:80
        ServerAdmin root@localhost

        DocumentRoot /var/www/sites/rails/public
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>

        CustomLog /var/log/apache2/rails-access.log combined
        ErrorLog /var/log/apache2/rails-error.log
        LogLevel warn

        ServerSignature On
</VirtualHost>

U mnie wygląda to tak, że trzeba jeszcze włączyć ten plik do konfiguracji wykonując:

  cd /etc/apache2/sites-enabled
  ln -s ../sites-available/rails

Jeśli w Twoim przypadku struktura katalogowa jest inna, to być może musisz stworzyć ten plik w innym miejscu, albo dopisać powyższy fragment do jakiegoś zbiorczego pliku konfiguracyjnego. Dopasuj parametry niektórych opcji, tak aby odzwierciedlały przyjętą przez Ciebie architekturę. Na przykład zamiast rails.local możesz podać jakąś inną nazwę, albo pozostawić przykładową. W tym drugim przypadku nie zapomnij dopisać jej do /etc/hosts i przypisać do adresu IP ustawionego na widocznym w lokalnej sieci interfejsie.

Uwaga: Jeśli korzystasz z dyrektywy silnika ITK o nazwie AssignUserID, to musisz wiedzieć, że nie współdziała ona z modułem Phusion Passenger. Jeśli z jakichś względów potrzebujesz, aby aplikacje RoR były uruchamiane z innymi uprawnieniami niż domyślne, to poczytaj rozdział zatytułowany User switching oryginalnej dokumentacji.

Poza tym, jeśli wystąpiłyby jakiekolwiek konflikty z innymi katalogami tego samego hosta wirtualnego, to możesz użyć odpowiedniej dyrektywy, aby selektywnie wyłączać ich obsługę przez moduł. Chodzi tu o sytuację, w której zapragniesz mieć aplikację Rails, a w katalogu obok na przykład kod PHP. Możesz wyłączać obsługę niektórych katalogów dodając:

<Location /blog>
  PassengerEnabled off
</Location>

Pamiętaj o utworzeniu katalogu /var/www/sites/rails/public, który będzie miejscem na umieszczanie aplikacji obsługiwanej przez RoR. Możesz go zmienić, ale pamiętaj wtedy o odpowiedniej zmianie w konfiguracji wirtualnego hosta. Osobiście stosuję takie podejście, że zakładam dodatkowego użytkownika, któremu w katalogu domowym tworzę dowiązanie symboliczne o nazwie www do katalogu /var/www/sites/rails. Trzeba potem pamiętać o zmianie właściciela i właściciela grupowego katalogu, aby należał on do nowo stworzonego użytkownika.

Zauważ, że podkatalog public nie musi jeszcze istnieć – założy go skrypt generujący aplikację RoR.

Tworzenie aplikacji RoR

O tworzeniu aplikacji Ruby on Rails w następnej części. ;-)

Podziel się

Trackbacki

Użyj następującego trackbacka na swojej stronie:

http://randomseed.pl/trackbacks?article_id=ruby-on-rails-iii-instalacja&day=27&month=12&year=2008

Komentarze

  1. RobertG powiedział about 1 month later:

    Czy możesz polecić porządny ebook/tutorial do aktualnej wersji railsów? Szukałem kilka miesięcy temu i nic wartościowego nie znalazłem :(

  2. http://bothunters.pl powiedział about 1 month later:

    Przejrzyste i bardzo bardzo szczegółowe. Dzięki !

    Borys Łącki

  3. lol powiedział 7 months later:
    A co z taką usterką: ERROR: Error installing mysql: ERROR: Failed to build gem native extension. /usr/bin/ruby1.8 extconf.rb extconf.rb:1:in `require': no such file to load -- mkmf (LoadError) from extconf.rb:1
  4. siefca powiedział 7 months later:

    Jeśli instalujesz Ruby’ego z paczki, to możliwe, że występuje potrzeba zainstalowania pakietu dla deweloperów, żeby budować gemy:

    sudo apt-get install ruby1.8-dev

    albo

    sudo apt-get install ruby1.9-dev
  5. proxy sites powiedział 11 months later:

    Going to play with it, right away. Will post updates. Cool bit.

    Ten komentarz oczekuje na akceptację. Nie ukaże się do czasu zaakceptowania przez autora..
  6. krzyzowki powiedział over 2 years later:

    I am often to blogging and i really appreciate your content. The article has really peaks my interest. I am going to bookmark your site and keep checking for new information.

    Ten komentarz oczekuje na akceptację. Nie ukaże się do czasu zaakceptowania przez autora..
  7. pozycjonowanie powiedział over 2 years later:

    wow very nice blog i will come again to read new topic thanks

    Ten komentarz oczekuje na akceptację. Nie ukaże się do czasu zaakceptowania przez autora..
  8. darmowe krzyzowki powiedział over 2 years later:

    This is the greatest topic I have read today

    Ten komentarz oczekuje na akceptację. Nie ukaże się do czasu zaakceptowania przez autora..
  9. darmowe pozycjonowanie powiedział over 2 years later:

    Thanks for this great post. Did you do it all on your own? This must’ve taken a lot of time

    Ten komentarz oczekuje na akceptację. Nie ukaże się do czasu zaakceptowania przez autora..

(leave url/email »)

   Pomoc języka formatowania Obejrzyj komentarz