Mostrando entradas con la etiqueta ruby. Mostrar todas las entradas
Mostrando entradas con la etiqueta ruby. Mostrar todas las entradas

domingo, 2 de agosto de 2015

Instalar rbenv, ruby-build y bundler en Ubuntu

# instalamos dependencias
sudo apt-get update
sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev
# inatalamos rbenv
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc

exec $SHELL
type rbenv #=> "rbenv is a function"
# instalamos ruby-build
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
# Listado de las versiones de ruby
$ rbenv install -l
# Instalamos ruby 2.2.2, lo designamos por defecto y lo comprobamos
rbenv install 2.2.2
rbenv global 2.2.2
ruby -v
# para evitar intalar la documentecion de la gemas
echo "gem: --no-ri --no-rdoc" > ~/.gemrc
# instalamos bundler
gem install bundler
# Repo rbenv https://github.com/sstephenson/rbenv
# Repo ruby-build https://github.com/sstephenson/ruby-build
# web bundler http://bundler.io/
# Recordatorio RVM, instalación y uso http://en-la-mina.blogspot.com/2012/01/recordatorio-rvm-instalacion-y-uso.html

jueves, 17 de abril de 2014

Raspberry Pi: Desplegando aplicación Rails,RVM,Thin en nginx con Capistrano


Configuración en el servidor:

Instalación de RVM multi-usuario [script]:

pi@raspberrypi ~ $ sudo su
root@raspberrypi:/home/pi# curl -L get.rvm.io | bash -s stable
#source /etc/profile.d/rvm.sh
root@raspberrypi:/home/pi# source /etc/profile
root@raspberrypi:/home/pi# rvm requirements;
root@raspberrypi:/home/pi# apt-get install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion pkg-config
root@raspberrypi:/home/pi# rvm install 2.0.0

Tenemos que instalar Nginx. Esta explicado en la anterior entrada: Cambiando Apache por Nginx

Vamos a crear el usuario que realizara los deploy de capistrano. El aprovechamos para crear con un home diferente /var/deploy y alojar ahí las aplicaciones. Luego bloqueamos la contraseña, solo podremos logarnos y deployar a través de ssh.

root@raspberrypi:/home/pi# adduser --home /var/deploy deploy
root@raspberrypi:/home/pi# passwd -l deploy

Nos vamos ponernos como usuario deploy y lo configuramos para poder autenticarnos por ssh como el usuario deploy (explicado en entrada anterior):

root@raspberrypi:/home/pi# su - deploy
deploy@raspberrypi ~ $ pwd #comprobamos donde estamos y si es igual al HOME esperado
/var/deploy
deploy@raspberrypi ~ $ mkdir .ssh
deploy@raspberrypi ~ $ vim .ssh/authorized_keys #introducimos la llave publica a autorizar
Vamos a crear el gemset de nuestra aplicación y como instalaríamos thin:
deploy@raspberrypi ~ $ rvm use 2.0.0@showip --create
deploy@raspberrypi ~ $ rvm gemset create showip
deploy@raspberrypi ~ $ # gem install thin


Configuración en nuestra aplicación (entorno de desarrollo):

En el Gemfile añadimos capistrano y thin [ejemplo thin, ejemplo unicorn]:
# Use Capistrano for deployment
group :development do
  gem 'capistrano'
  gem "rvm-capistrano"
end

# Use Thin for production
gem 'thin', group: :production

Si no tenemos instalado ningún motor de Javascript en el servidor, tenemos que descomentar también la linea de therubyracer. Otra opción, instalar en el servidor nodejs.

Ejecutamos un bundle y comando para crear ficheros de capistrano:

$ bundle install
$ capify .
[add] writing './Capfile'
[add] writing './config/deploy.rb'
[done] capified!
Configuramos el fichero de /config/deploy.rb, (lo creamos si es necesario). En mi caso queda así:
require "rvm/capistrano"
#require "capistrano/ext/multistage"
require "bundler/capistrano"

#set :stages, %w(staging production) #Si queremos mas de un entorno

set :application, "showip"
set :repository,  "git@github.com:verdor/showip.git"

default_run_options[:pty] = true
ssh_options[:forward_agent] = true

# la versión de ruby tiene que estar instalada y el gemset existir
# antes del cap deploy:setup
set :rvm_ruby_string, 'ruby-2.0.0-p451@showip'
set :rvm_type, :system

set :scm, :git
set :git_shallow_clone, 1
server "192.168.1.10", :app, :web, :db, primary: true
#server "showip.tk", :app, :web, :db, primary: true

set :user, "deploy"
set :keep_releases, 5
set :use_sudo, false

#set :port, 22 #sustituye con el puerto que usas
# Capistrano's default location "/u/apps/#{application}"
set :deploy_to, "/var/#{user}/apps/#{application}"
set :deploy_via, :remote_cache

set :branch, "master"

after  "deploy:finalize_update" , "symlinks"
after  "deploy",                  "deploy:cleanup"

namespace :deploy do
  desc "Despues de ejecutar el setup subimos ficheros de configuracion"
  task :setup_config, roles: :app do
    #run "mkdir #{shared_path}/config"
    #run "#{try_sudo} mkdir #{shared_path}/config"
    top.upload("config/nginx.conf", "#{shared_path}/nginx.conf", via: :scp)
    top.upload("config/thin_config.yml", "#{shared_path}/thin_config.yml", via: :scp)
    top.upload("config/database.yml", "#{shared_path}/database.yml", via: :scp)
    #top.upload(".rvmrc", "#{shared_path}/.rvmrc", via: :scp)
    top.upload(".versions.conf", "#{shared_path}/.versions.conf", via: :scp)
    #sudo "mv #{shared_path}/config/nginx.conf /etc/nginx/sites-available/showip"
    #sudo "ln -nfs /etc/nginx/sites-available/showip /etc/nginx/sites-enabled/showip"
  end

  after "deploy:setup", "deploy:setup_config"
end

task :symlinks, roles: [:app] do
  run <<-CMD
    ln -s #{shared_path}/cache #{release_path}/public/;
    ln -s #{shared_path}/database.yml #{release_path}/config/;
    ln -s #{shared_path}/thin_config.yml #{release_path}/config/;
    ln -s #{shared_path}/.versions.conf #{release_path}/;
  CMD
end

namespace :deploy do
  desc "Start the Thin processes"
  task :start do
    run  <<-CMD
      cd #{current_path}; bundle exec thin start -C config/thin_config.yml
    CMD
  end

  desc "Stop the Thin processes"
  task :stop do
    run <<-CMD
      cd #{current_path}; bundle exec thin stop -C config/thin_config.yml
    CMD
  end

  desc "Restart the Thin processes"
  task :restart do
    run <<-CMD
      cd #{current_path}; bundle exec thin restart -C config/thin_config.yml
    CMD
  end
end
Un a vez hecho esto, queremos ver el listado de tareas capistrano:
verdor@enlamina ~$ cap -T
Creamos el fichero de configuración del servidor en nginx para nuestra aplicación:
upstream showip {
        server 127.0.0.1:3000;
}
server {
        listen       80;
        server_name  showip.pi showip.jeronima.tk showip.tk;

        root /var/deploy/apps/showip/current/public/;
        access_log /var/log/nginx/showip-access.log;
        error_log /var/log/nginx/showip-error.log;
        rewrite_log on;

        location ~ ^/assets/ {
                root /var/deploy/apps/showip/current/public;
                gzip_static on;
                expires 1y;
                add_header Cache-Control public;
                add_header ETag "";
                break;
        }

        location / {
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                client_max_body_size 10m;
                client_body_buffer_size 128k;

                proxy_connect_timeout 90;
                proxy_send_timeout 90;
                proxy_read_timeout 90;

                proxy_buffer_size 4k;
                proxy_buffers 4 32k;
                proxy_busy_buffers_size 64k;
                proxy_temp_file_write_size 64k;

                proxy_redirect off;
                if (!-f $request_filename) {
                        proxy_pass http://showip;
                        break;
                }
        }

        if (-f $document_root/system/maintenance.html) {
                return 503;
        }
        error_page 503 @maintenance;
        location @maintenance {
                rewrite  ^(.*)$  /system/maintenance.html last;
                break;
        }

        error_page 500 502 503 504 /50x.html;
}
Escribimos nuestro fichero de configuracion del thin, pero al final no lo usamos y lo generamos con thin en el propio servidor, probar ejecutando thin -h:

---
chdir: /var/deploy/apps/showip/current
environment: production
address: 0.0.0.0
port: 3000
timeout: 30
log: /var/deploy/apps/showip/current/log/thin.log
pid: /var/deploy/apps/showip/current/tmp/pids/thin.pid
max_conns: 1024
max_persistent_conns: 100
require: []
wait: 30
threadpool_size: 20
servers: 1
user: deploy
group: deploy
daemonize: true
Ahora tenemos que preparar el servidor con capistrano:

verdor@enlamina ~$ cap deploy:update
verdor@enlamina ~$ cap deploy:start

* Ojo, la aplicación no tiene base de datos, ni asset.



Más configuración en el servidor. WRAPPERS. Que wrappers.

Queremos que nuestra aplicación se inicie como un servicio más (init.d):

pi@raspberrypi ~ $ sudo su
root@raspberrypi:/home/pi# source /etc/profile #cargamos rvm
root@raspberrypi:/home/pi# rvm use ruby-2.0.0-p451@showip
root@raspberrypi:/home/pi# thin install
Installing thin service at /etc/init.d/thin ...
mkdir -p /etc/init.d
writing /etc/init.d/thin
chmod +x /etc/init.d/thin
mkdir -p /etc/thin

To configure thin to start at system boot:
on RedHat like systems:
  sudo /sbin/chkconfig --level 345 thin on
on Debian-like systems (Ubuntu):
  sudo /usr/sbin/update-rc.d -f thin defaults
on Gentoo:
  sudo rc-update add thin default

Then put your config files in /etc/thin

Genera el el fichero /etc/init.d/thin, mostramos como se crea, pero luego lo renombraremos y editaremos:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          thin
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      S 0 1 6
# Short-Description: thin initscript
# Description:       thin
### END INIT INFO

# Original author: Forrest Robertson

# Do NOT "set -e"

DAEMON=/usr/local/rvm/gems/ruby-2.0.0-p451@showip/bin/thin
SCRIPT_NAME=/etc/init.d/thin
CONFIG_PATH=/etc/thin

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

case "$1" in
  start)
        $DAEMON start --all $CONFIG_PATH
        ;;
  stop)
        $DAEMON stop --all $CONFIG_PATH
        ;;
  restart)
        $DAEMON restart --all $CONFIG_PATH
        ;;
  *)
        echo "Usage: $SCRIPT_NAME {start|stop|restart}" >&2
        exit 3
        ;;
esac

:
Si vamos a tener más de una aplicación que use thin, renombramos el fichero /etc/init.d/thin, en nuestro caso por /etc/init.d/showip y modificamos...

SCRIPT_NAME=/etc/init.d/showip
CONFIG_PATH=/etc/showip #var/deploy/showip
Lo renombramos y ponemos en el arranque:

root@raspberrypi:~# mv /etc/init.d/thin /etc/init.d/showip
root@raspberrypi:~# sudo /usr/sbin/update-rc.d -f showip defaults
Generamos la configuracion del thin para nuestra aplicacion showip

root@raspberrypi:~# thin config -C /etc/thin/showip.yml -c /var/deploy/apps/showip/current --servers 1 -p 3000
Wrote configuration to /etc/thin/showip.yml
Editamos el fichero del config /etc/thin/showip.yml para ver si le damos algun retoque:

---
chdir: /var/deploy/apps/showip/current
environment: production
address: 0.0.0.0
port: 3000
timeout: 30
log: log/thin.log
pid: /var/deploy/apps/showip/current/tmp/pids/thin.pid
max_conns: 1024
max_persistent_conns: 100
require: []
wait: 30
threadpool_size: 20
servers: 1
user: deploy
group: deploy
daemonize: true
Generamos el wrapper de RVM ya que la ruta /usr/local/rvm/gems/ruby-2.0.0-p451@showip/bin/thin no nos acaba de funcionar, despues editaremos de forma definitiva /etc/init.d/showip

root@raspberrypi:~# rvm wrapper ruby-2.0.0-p451@showip showip thin
Regenerating ruby-2.0.0-p451@showip wrappers.........
Comprobamos que se ha generado (es un enlace blando):

root@raspberrypi:~# ls /usr/local/rvm/bin/ | grep showip
showip_thin
Podemos probarlo y si hay algun fallo en el fichero de configuracion, nos lo dira:

root@raspberrypi:~# /usr/local/rvm/bin/showip_thin start -C /etc/thin/showip.yml
/usr/local/rvm/rubies/ruby-2.0.0-p451/lib/ruby/2.0.0/psych.rb:205:in `parse': (/etc/thin/showip.yml): could not find expected ':' while scanning a simple key at line 15 column 1 (Psych::SyntaxError)

#o funcionara

Starting server on 0.0.0.0:3000 ... 

root@raspberrypi:~# /usr/local/rvm/bin/showip_thin stop  -C /etc/thin/showip.yml 
Stopping server on 0.0.0.0:3000 ... 
Sending QUIT signal to process 3001 ... 

Exiting!

Ya generado el wrapper editamos /etc/init.d/showip dejandolo como queda:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          thin
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      S 0 1 6
# Short-Description: thin initscript
# Description:       thin
### END INIT INFO

# Original author: Forrest Robertson

# Do NOT "set -e"

DAEMON=/usr/local/rvm/bin/showip_thin
SCRIPT_NAME=/etc/init.d/showip
CONFIG_PATH=/etc/thin/showip.yml
#chown=/bin/chown
#mkdir=/bin/mkdir

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

case "$1" in
  start)
        $DAEMON start -C $CONFIG_PATH
        ;;
  stop)
        $DAEMON stop -C $CONFIG_PATH
        ;;
  restart)
        $DAEMON restart -C $CONFIG_PATH
        ;;
  *)
        echo "Usage: $SCRIPT_NAME {start|stop|restart}" >&2
        exit 3
        ;;
esac

:
Los fichero creados los ponemos como propiedad del usuario deploy:

chown deploy:deploy /etc/init.d/showip
Hacemos una pruaba antes de reiniciar y ver que arranca la aplicación:

pi@raspberrypi ~ $ sudo service showip start
Starting server on 0.0.0.0:3000 ... 
Ya podemos ir desarrollando, subir al repositorio y hacer deploy con las ultimas versiones del código.

verdor@enlamina$ cap deploy
Tendríamos que dar algunos retoques si tuviéramos mas de un entrono (entorno de pruebas) y la aplicación necesitase de base de datos, etc... Enlaces:

miércoles, 27 de noviembre de 2013

Validación XML

1ª Opción
dtd = XML::Dtd.new(IO.read(dtd_path, encoding: "UTF-8"))
document = io ? XML::Document.io(xml[:tempfile], encoding: XML::Encoding::ISO_8859_1) : document = XML::Document.file(xml, encoding: XML::Encoding::ISO_8859_1)
document.validate(dtd)


2ª Opción
xsd = Nokogiri::XML::Schema(File.read(PO_SCHEMA_FILE))
doc = Nokogiri::XML(File.read(PO_XML_FILE))
xsd.validate(doc).each do |error|
  puts error.message
end

http://www.xmlsoft.org/xmldtd.html
http://www.xmlvalidation.com/

sábado, 21 de enero de 2012

Recordatorio RVM, instalación y uso

  • ¿que es RVM?
    Ruby Version Manager permite gestionar varios entornos de desarrollo Ruby por versiones y dentro de cada versión de Ruby, distintos entornos mediante diferentes conjuntos de conjuntos de gemas. Para cada Ruby hay un gemset Global al que acceden todos los demás gemset

  • Instalación de RVM:
    bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
    

    Añadimos la siguiente línea al fichero de configuración ~/.bashrc, teniendo en cuenta que no haya ningún “return” antes:
    echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bash_profile
    
    Abrimos otro shell y comprobamos que se haya instalado correctamente
    type rvm | head -1 #la salida sera rvm is a function
    
  • Instalar una versión de ruby con RVM
    
    rvm install ruby-1.9.3-p0 # ultima versión estable
    rvm --default use ruby-1.9.3-p0 #lo dejamos por defecto
    ruby -v # compruebo con que versión estoy trabajando
    
  • Pregunto por la versión de rubygem:
    gem -v #si es menor de 1.8.11 la actualizamos
    gem update –system #actualizacion (no os hará falta)
    
  • Crear un gemset (entorno de trabajo para rails 3.2.0) , actualizo gema rake si es necesario
    rvm ruby-1.9.3-p0@rails320 --create --default # creo entorno rails320 por defecto
    
    rvm gemset list #comprobamos que se ha creado
    
    gem list #pedimos que nos muestre la información actual sobre las gemas que tenemos
    
    gem update rake # si la versión de rake es menor que 0.9.2.2 actualizamos
    
    rake -version rvm install ruby-1.9.3-p0 # ultima versión estable
    
  • Instalamos rails 3.2.0 (http://rubygems.org/gems/rails):

    gem install rails -v 3.2.0.rc2 # le indicamos la ultima versión apunto de salir, en breve estable

    # gem install rails #toma la última versión estable
    rails -v # Consulta la versión de la gema rails

  • listado de otros comandos:
    • rvm info # información de configuración y sistema
    • rvm list # lista de rubies instalados
    • rvm list known # lista de rubies que se pueden instalar
    • rvm gemset list # lista de gemset
    • rvm gemset list_all # lista de gemsets en cada ruby
    • rvm gemset create rails312 # crea el gemset rails312
    • rvm ruby-1.9.3-p0@rails312 # nos movemos al nuevo gemset
    • rvm gemset use rails312 # moverse de gemset dentro de la misma versión de ruby
    • gem install rails -v 3.1.2 # instalamos en este gemset la versión de rails 3.1.2
    • #rvm gemset delete rails312 #borramos el gemset rails312
    • #rvm uninstall ree,1.8.7 #borramos ruby con passenger y ruby 1.8.7
  • Puedes crear ficheros de configuración el tus proyectos en un fichero .rvmrc y así cuando cambias de directorio cargas el entorno correcto, versión de ruby y conjunto de gemas: http://beginrescueend.com/workflow/rvmrc/
    
        # ../myapp/.rvmrc
        rvm_gemset_create_on_use_flag=1
        rvm use 1.9.3-p0
        rvm gemset use rails320myapp

  • También puedes configurar el prompt para que te indique la configuración con la que estas trabajando: http://beginrescueend.com/workflow/prompt/

Fuente: RVM
código