tag:blogger.com,1999:blog-4149644160926437982024-03-13T13:06:45.217+01:00Simple is beautifulO Ruby on Rails, Ubuntu, MySql, Solr, Lucene i inne ciekawoskiAnonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.comBlogger13125tag:blogger.com,1999:blog-414964416092643798.post-24039849923160938382012-05-30T08:00:00.003+02:002012-06-28T11:35:50.326+02:00elasticsearch i tire - instalacja oraz uruchomienie testowej aplikacji<br />
<br />
<h3>
Java 6</h3>
<br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">$ wget https://github.com/flexiondotorg/oab-java6/raw/0.2.1/oab-java6.sh -O oab-java6.sh<br />$ chmod +x oab-java6.sh<br />$ sudo ./oab-java6.sh</span><br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">$ sudo sudo apt-get install sun-java6-jre</span><br />
<h3>
Elasticsearch</h3>
<br />
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">$ curl -k -L -o elasticsearch-0.19.4.tar.gz https://github.com/downloads/elasticsearch/elasticsearch/elasticsearch-0.19.4.tar.gz<br />$ tar -zxvf elasticsearch-0.19.4.tar.gz<br />$ ./elasticsearch-0.19.4/bin/elasticsearch -f</span><br />
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<h3>
<span style="font-family: inherit; font-size: small;">Tire and searchapp</span></h3>
<div>
<pre style="background-color: #f8f8f8; border-bottom-color: rgb(204, 204, 204); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(204, 204, 204); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #333333; font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow-x: auto; overflow-y: auto; padding-bottom: 6px; padding-left: 10px; padding-right: 10px; padding-top: 6px;"><code style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: none; border-color: initial; border-image: initial; border-left-style: none; border-right-style: none; border-style: initial; border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: none; border-width: initial; font-family: 'Bitstream Vera Sans Mono', Courier, monospace; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">rails new searchapp -m https://raw.github.com/karmi/tire/master/examples/rails-application-template.rb</code></pre>
<div>
#Gemfile</div>
<div>
gem 'kaminari'</div>
<div>
<br /></div>
<div>
#app/models/article.rb</div>
<div>
class Article < ActiveRecord::Base</div>
<div>
attr_accessible :title, :content, :published_on</div>
<div>
include Tire::Model::Search</div>
<div>
include Tire::Model::Callbacks</div>
<div>
end</div>
<div>
<br /></div>
<div>
#app/controllers/articles_controller.rb</div>
<div>
<div>
def search</div>
<div>
@articles = Article.search params[:q], :page => (params[:page] || 1), :per_page => 1</div>
<div>
<br /></div>
<div>
render :action => "index"</div>
<div>
end</div>
</div>
<div>
<br /></div>
<div>
#app/views/articles/index.html.erb</div>
</div>
<div>
<%= paginate @articles %></div>
<div>
<br /></div>
<div>
<a href="http://localhost:9200/articles/_mapping">http://localhost:9200/articles/_mapping</a></div>
<div>
<br /></div>
<div>
<br /></div>Anonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com0tag:blogger.com,1999:blog-414964416092643798.post-57847301168150836282012-03-30T21:33:00.002+02:002012-03-30T21:46:51.825+02:00oh my zsh, Ubuntu i rvmOstatnio trafiłem na powłokę zsh i projekt <a href="https://github.com/robbyrussell/oh-my-zsh" target="_blank">Oh My ZSH</a><br />
W domyślym theme Oh My ZSH m. in. dodaje do prompt konsoli informację o nazwie branch'a jeśli znajdujemy się w katalogu z repozytorium git'a.<br />
Jeśli używamy rvm - aby naszy ruby i inne gemy były widziane przez powłokę należy dodać następującą linię do pliku ~/.zshrc<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: inherit;">Polecam ten <a href="http://railscasts.com/episodes/308-oh-my-zs" target="_blank">screencast</a> aby przekonać się czym jest zsh i jakie ma możliwości. </span>Anonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com0tag:blogger.com,1999:blog-414964416092643798.post-60266597257794947242012-03-18T21:08:00.002+01:002012-03-18T21:08:53.338+01:00Ustawianie wspólnego repozytorium gitTu opis jak to zrobić:<br />
<a href="http://mapopa.blogspot.com/2009/10/git-insufficient-permission-for-adding.html">Shared group repository</a><br />
<br />
<blockquote>ssh to server<br />
cd repository.git<br />
<br />
sudo chmod -R g+ws *<br />
sudo chgrp -R mygroup *<br />
<br />
git repo-config core.sharedRepository true<br />
</blockquote>Anonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com0tag:blogger.com,1999:blog-414964416092643798.post-5048477374586820232012-01-25T17:21:00.001+01:002012-01-25T17:22:12.552+01:00logrotate - rotacja logów na ubuntulogrotate służy do rotowania określonej liczby plików log.<br />
<br />
logrotate powinien być domyślnie zainstalowany w każdym systemie Ubuntu.<br />
<br />
Dla każdej aplikacji, której logami chcemy zarządzać, dodajemy plik konfiguracyjny:<br />
#/etc/logrotate.d/our_app<br />
<br />
Zawartość pliku:<br />
/home/apps/our_app/current/log/production.log* {<br />
daily<br />
rotate 7<br />
compress<br />
missingok<br />
}<br />
<br />
daily - codziennie<br />
rotate 7 - zostaw ostatnie siedem plików<br />
compress - spakuj gzip<br />
missingok - nie krzycz, gdy nie ma żadnych logów<br />
<br />
logrotate wykonuje ten skrypt każdego dnia, datę ostatniego wykonania, można sprawdzić w pliku:<br />
cat /var/lib/logrotate/status<br />
<br />
Za pomocą następującej komendy można ręcznie uruchomić określoną konfigurację logrotate:<br />
sudo logrotate -f /etc/logrotate.d/our_appAnonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com0tag:blogger.com,1999:blog-414964416092643798.post-60494304934050512002012-01-20T12:02:00.002+01:002012-01-20T12:02:59.609+01:00Capistrano - czyszczenie katalogu releases<p>
Po raz kolejny szukam w Google składni polecenia capistrano aby wyczyścić stare 'releases', aby więcej tego nie szukać oto składnia:
</p>
<p><b>cap deploy:cleanup -s keep_releases=2</b></p>
<p><b>keep_releases=2</b> oznacza, że pozostaną nam dwa ostanie 'releases'.</p>Anonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com1tag:blogger.com,1999:blog-414964416092643798.post-67829131263017159132012-01-03T16:13:00.000+01:002012-04-17T11:35:23.678+02:00ssh bez hasłaPiszę to głównie po to aby nie musieć szukać ponownie tych informacji za miesiąc lub dwa, gdy będę musiał konfigurować rsync lub coś podobnego...<br />
<br />
Mamy dwa serwery:<br />
A - serwer produkcyjny<br />
B - serwer backup<br />
<br />
Zakładam, że na serwerze B posiadamy już użytkownika (np. backup) i folder .ssh w jego katalogu domowym. Zakładam także, że posiadamy już plik .ssh/authorized_keys (lub .ssh/authorized_keys2)<br />
Jeśli nie, to:<br />
<span style="font-family: 'Courier New', Courier, monospace;">touch ~/.ssh/authorized_keys</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">chmod 700 ~/.ssh</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">chmod 600 ~/.ssh/authorized_keys</span><br />
<br />
Na serwerze A, z którego będziemy robili upload za pomocą rsync generujemy klucz prywatny i publiczny, np: <br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">mkdir ~/.ssh</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">chmod 700 ~/.ssh</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">ssh-keygen -t rsa</span><br />
<br />
Kopiujemy klucz publiczny z maszyny A na B:<br />
<span style="font-family: 'Courier New', Courier, monospace;">scp </span><span style="font-family: 'Courier New', Courier, monospace;">~/.ssh/</span><span style="font-family: 'Courier New', Courier, monospace;">id_rsa.pub server_b_username@server_b_domain:~/id_rsa.pub</span><br />
<br />
Następnie logujemy się poprzez ssh na serwer B.<br />
<span style="font-family: 'Courier New', Courier, monospace;">cd .ssh</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">cat ~/id_rsa.pub >> ~/.ssh/authorized_keys</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">rm ~/id_rsa.pub</span><br />
<br />
Następnie wylogowujemy się z serwera B, logujemy się na serwer A i z niego powinniśmy być w stanie zalogować się na serwer B bez podawania hasła.Anonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com2tag:blogger.com,1999:blog-414964416092643798.post-64256901411260963192012-01-03T14:10:00.001+01:002012-01-03T16:22:42.288+01:00Instalacja gem'ów bez dokumentacji na UbuntuNależy utworzyć plik ~/.gemrc i dodać do niego następującą linię:<br />
<br />
gem: --no-ri --no-rdoc<br />
<br />
Wylogować się, zalogować ponownie i gem install [gem_name] nie powinien już instalować dokumentacji dla wybranego gem'a.Anonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com0tag:blogger.com,1999:blog-414964416092643798.post-29863098137781378912011-06-18T11:59:00.000+02:002011-06-18T11:59:55.855+02:00Zabezpieczenie jettyW mojej aplikacji Ruby on Rails używam gema <a href="http://outoftime.github.com/sunspot/">Sunspot</a>, który to używa <a href="https://github.com/mwmitchell/rsolr">RSolr</a> do komunikacji z serwerem <a href="http://lucene.apache.org/solr/">Solr</a>. <a href="http://lucene.apache.org/solr/">Solr</a> to serwer bazujący na indeksie <a href="http://lucene.apache.org/">Lucene</a>, który świetnie nadaje się do wyszukiwania pełnotekstowego.<br />
Domyślna instalacja Sunspot posiada kopię Solr'a, którą można uruchomić na <a href="http://jetty.codehaus.org/jetty/">jetty</a>. <a href="http://jetty.codehaus.org/jetty/">Jetty</a> domyślnie uruchamia się na porcie 8983 i można podglądnąć sobie panel administracyjny Solr'a wchodząc na adres: http://localhost:8983/solr/admin/<br />
<br />
Wszystko fajnie gdy pracuje się na localhost, jednak na serwerze produkcyjnym nie jest mile widziane aby każdy miał dostęp do wspomnianego panelu.<br />
<br />
Najpierw próbowałem zabezpieczyć port 8983 dla ruchu z poza mojego serwera, chciałem użyć do tego <a href="https://wiki.ubuntu.com/UncomplicatedFirewall">ufw</a> niestety moje zdolności administratorskie nie są na tyle dobre aby to poprawnie skonfigurować.<br />
<br />
Następnie zastanawiałem się czy jest możliwość konfiguracji <a href="http://jetty.codehaus.org/jetty/">jetty</a>, aby odpowiadała tylko dla zapytań z konkretnego hosta. Okazało się, że można to skonfigurować, oto instrukcja:<br />
<br />
1. w pliku konfiguracyjnym jetty jetty.xml - w moim przypadku ścieżka to: <br />
<script src="https://gist.github.com/1032143.js"> </script><br />
odnaleźć fragment:<br />
<script src="https://gist.github.com/1032148.js"> </script><br />
2. dodać następującą linię<br />
<script src="https://gist.github.com/1032151.js"> </script><br />
przed linią<br />
<script src="https://gist.github.com/1032152.js"> </script><br />
3. zrestartować serwer jetty i nasz panel solr powinien już być zabezpieczony.Anonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com1tag:blogger.com,1999:blog-414964416092643798.post-83258175323167482742011-06-17T21:22:00.002+02:002011-06-17T21:25:42.577+02:00whenever - zarządzaj crontab za pomocą RubyZgodnie z obietnicą opiszę jak skonfigurować crontab za pomocą gem'a <a href="https://github.com/javan/whenever">whenever</a>.<br />
<br />
W poprzednim <a href="http://blog.dedico.pl/2011/03/amazon-s3-i-backup.html">poście</a> mowa była jak utworzyć backup bazy MySql za pomocą gem'a <a href="https://github.com/meskyanichi/backup/">backup</a> i wysłać go do <a href="http://aws.amazon.com/s3/">Amazon S3</a>.<br />
<br />
Przydałoby się zautomatyzować ten proces aby wykonywał się przynajmniej raz dziennie.<br />
<br />
Oto jak można to zrobić za pomocą gem'a <a href="https://github.com/javan/whenever">whenever</a>.<br />
<br />
Pominę proces instalacji, gdyż jest to bardzo dobrze opisane na stronie <a href="https://github.com/javan/whenever">projektu</a>. <br />
<br />
Po komendzie <b><i>wheneverize .</i></b> został utworzony plik <b>config/schedule.rb</b>, w tym pliku należy wpisać własne zadania, które chcemy wykonać na naszym serwerze.<br />
<br />
Moim celem było utworzenie taska, który będzie wykonywał się codziennie i który będzie wywoływał komendę:<br />
<p><script src="https://gist.github.com/943959.js?file=perform"></script><br />
</p>Zgodnie z dokumentacją napisałem coś takiego:<br />
<p><script src="https://gist.github.com/1032068.js"> </script><br />
</p>Jeśli używamy domyślnego pliku konfiguracyjnego dla gem backup, to możemy w komendzie pominąć paramter -c oraz ścieżkę do pliku, można jednak wskazać konkretny plik, gdzie mamy zdefiniowany nasz <b>Backup::Model test_backup</b>.<br />
<br />
Po wrzuceniu tego na serwer okazało się, że cron nie rozumie polecenia backup. Trzeba było odpowiednio ustawić zmienną PATH, poniżej jeszcze raz plik schedule.rb wraz z dodatkowymi ustawieniami:<br />
<p><script src="https://gist.github.com/1032075.js"> </script><br />
</p><br />
Cron po każdym uruchomieniu taska wyśle podsumowanie na adres email, który został ustawiony w zmiennej :MAILTO. <br />
<br />
To wszystko. Cron działa, backup się wykonuje. Bardzo podoba mi się, to, że taski cron są zdefiniowane wraz z projektem Rails. Jeśli używa się <a href="https://github.com/halorgium/capistrano">capistrano</a> do deployment'u to warto dodać do pliku deploy.rb task, który będzie aktualizował crontab po każdym wypuszczeniu nowej wersji aplikacji:<br />
<p><script src="https://gist.github.com/1032097.js"> </script><br />
</p>Anonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com0tag:blogger.com,1999:blog-414964416092643798.post-25526765326038516062011-03-12T00:59:00.010+01:002011-06-17T21:23:39.488+02:00Amazon S3 i backupDzięki <a href="http://ruby5.envylabs.com/episodes/160-episode-157-march-11-2011">Ruby5</a> ponownie znalazłem fajne narzędzie, tym razem do robienia backup'ów.<br />
<br />
Gem <a href="https://github.com/meskyanichi/backup">backup</a> ma za zadanie robić backup'y (bazy danych, plików) i wysyłać je tam gdzie sobie tego zażyczymy (ftp, Amazon S3, itd).<br />
<br />
Spodobała mi się opcja wysyłania backup'u bazy MySql na Amazon S3. <br />
Nigdy wcześniej nie korzystałem z Amazon S3, można tam założyć konto, które będzie darmowe do momentu gdy miesięcznie nie przekroczy się następujących parametrów:<br />
<ul><li>5 GB of Amazon S3 storage</li>
<li>20 000 Get Requests</li>
<li>2 000 Put Requests</li>
</ul>Sądzę, że na początek to w zupełności wystarczy.<br />
Więcej info odnośnie darmowego serwisu Amazon: <a href="http://aws.amazon.com/free/">AWS free</a><br />
<br />
OK, mamy konto S3, należałoby utworzyć jakiś bucket na S3 - należy zalogować się do <br />
<a href="https://console.aws.amazon.com/s3/">https://console.aws.amazon.com</a> - nazwę naszego bucket'a ustawiamy na 'test'.<br />
<br />
Potrzebujemy jeszcze access_key_id oraz secret_access_key, są do pobrania z:<br />
<a href="https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&action=access-key">https://aws-portal.amazon.com</a><br />
<br />
Teraz czas na gema backup, instalacja:<br />
<div><p><script src="https://gist.github.com/943962.js"> </script><br />
</p></div><br />
Generujemy domyślny plik konfiguracyjny:<br />
<div><p><script src="https://gist.github.com/943963.js?file=generate"></script><br />
</p></div><br />
Należy dostosować plik konfiguracyjny (domyślnie w ~/Backup/config.rb) do naszych potrzeb: nazwa bazy, użytkownika i hasło oraz nazwa regionu Amazon, ja wybrałem Europę - stąd wartość dla s3.region = 'eu-west-1'<br />
<br />
<div><p><script src="https://gist.github.com/943956.js"> </script><br />
</p></div><br />
Teraz możemy wykonać backup bazy:<br />
<div><p><script src="https://gist.github.com/943959.js?file=perform"></script><br />
</p></div><br />
...i mamy zrobiony backup!<br />
<br />
W kolejnym <a href="http://blog.dedico.pl/2011/06/whenever-zarzadzaj-crontab-za-pomoca.html">poście</a> postaram się opisać automatyzację tego rozwiązania za pomocą gema <a href="https://github.com/javan/whenever">whenever</a>.Anonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com0tag:blogger.com,1999:blog-414964416092643798.post-60701110296361795302011-03-07T21:05:00.004+01:002011-03-13T09:37:09.231+01:00Upgrade do Rails 3.0.5 paperclip i ... gdzie są moje zdjęcia?!?!Tak jak zalecano zrobiłem upgrade na produkcji do Rails 3.0.5. Po wgraniu nowej wersji oraz po komendzie:<br />
bundle update<br />
gem'y rails zostały zaktualizowane.<br />
Aplikacja (<a title="Wyszukiwarka noclegów" href="http://holidio.pl">holidio</a>) śmiga, jednak zauważyłem, że niestety nie wyświetlają się zdjęcia, które zostały wgrane za pomocą paperclip... <br />
Hmm, nie zastanawiając się zbyt długo zrobiłem szybki rollback (dobrze, że korzystam z capistrano):<br />
cap deploy:rollback<br />
To przywróciło aplikację do poprzedniej wersji a mi dało trochę czasu na zastanowienie się co poszło nie tak...<br />
<br />
Przypomniało mi się, że słuchając jednego z ostatnich podcastów <a href="http://ruby5.envylabs.com/episodes/157-episode-154-march-1-2011#story-1">Ruby5</a> chłopaki wspominali, że w Rails 3.0.5 poprawiono "pluralizację" oraz, że m.in. od teraz np. "media" w liczbie mnogiej dalej pozostaną "media", a nie jak to było wcześniej "medias"...<br />
Ale co to ma wspólnego z moją aplikacją?<br />
Ano ma, <a href="https://github.com/thoughtbot/paperclip">paperclip</a> domyślnie używa katalogu "data" dla załączników. Ja potrzebowałem wielu załączników (zdjęć) do mojego modelu, więc załączniki te zostały zapisane w folderze "datas" (zła odmiana w liczbie mnogiej).<br />
Po upgrade do Rails 3.0.5 aplikacja szukała zdjęć w katalogu "data"... a takiego folderu niestety nie miałem na serwerze... Aby to naprawić wystarczyło zmienić nazwę folderu z "datas" na "data" i sprawa załatwiona.<br />
Gdybym potrzebował jednak utrzymać starą nazwę folderu, można przekazać <a href="https://github.com/thoughtbot/paperclip">paperclip</a> parametr :path i dowolnie ustawić jego wartość.Anonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com0tag:blogger.com,1999:blog-414964416092643798.post-88006791572794389002011-03-05T15:20:00.002+01:002011-03-13T09:36:30.608+01:00Couldn't parse YAML at line - po update RubyGems do wersji 1.6.1Wygląda na to, że połączenie Ruby 1.9.2 oraz najnowszej wersji RubyGems 1.6.1 domyślnie używa 'psych' jako parsera plików YAML...<br />
<br />
Mi nie udało się zainstalować gem'a 'psych', więc trzeba było ustawić inny domyślny parser dla aplikacji.<br />
<br />
W pliku boot.rb dodałem następujące linie:<br />
<pre>require 'yaml'
YAML::ENGINE.yamler = 'syck'
</pre>Anonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com1tag:blogger.com,1999:blog-414964416092643798.post-32372698634869751912011-02-21T21:06:00.000+01:002011-02-21T21:06:21.458+01:00Can't find gem rake ([">= 0"])Dotyczy prawdopodobnie tylko Ruby 1.9.2 na Windows. U mnie problem zaczął się po próbie instalacji gem'a radiant (cms), który, wygląda na to, że niestety jeszcze nie działa pod Ruby 1.9.2.<br />
<br />
Wystarczyło usunąć plik "rake.gemspec" z folderu:<br />
C:\Ruby192\lib\ruby\gems\1.9.1\specifications<br />
To załatwiło sprawę.Anonymoushttp://www.blogger.com/profile/00338728908650020002noreply@blogger.com0