Como subir una app rails a heroku

Configurar App

si tenemos un sitio en rails (también da soporte python, nodejs, java, clousure…) que queremos subirlo a internet para probarlo Heroku es una gran alternativa. Para poder usar Heroku debemos crearnos una cuenta y instalarlos sus Toolbelt. Un buen punto de partida para hacer todo esto es su QuickStart.

Para deployar en heroku deberemos hacer unos pequeños cambios en nuestro Gemfile. Heroku usa Postgres como base de datos, por lo que deberemos añadir las gemas en entorno de producción. Tambien deberemos poner la gem sqlite3 solo en los grupos development y test.

group :development, :test do
  gem 'sqlite3'
end
group :production do
  gem "pg"
  gem "rails_12factor"
end

Y ejecutar bundle install --without production para actualizar las dependencias. Una vez actualizados debemos realizar un commit para tener la última versión en git.

# => Si todavia no se tiene el proyecto en git, sera necesario añadirlo con 
# => git init
# => git commit -a -m "version inicial"
$ git commit -a -m "Añadidas dependecias para heroku y actualizado Gemfile.lock"

Subir la app

El siguiente paso es crear una nueva app en Heroku. Para ello ejecutamos heroku create

$ heroku create
Creating radiant-island-4647... done, stack is cedar-14
https://radiant-island-4647.herokuapp.com/ | https://git.heroku.com/radiant-island-4647.git
Git remote heroku added

Nos creará un nombre aleatorio, que asignará como repositorio remoto y como subdominio en el cual estará alojado nuestra aplicación.

Si queremos definir el nombre de nuestro subdominio, podemos entrar al entorno de administración de Heroku, crear la app con el nombre que mas nos guste y configurar en nuestra app el repositorio remoto

cd my-project/
$ git init
$ heroku git:remote -a my-project

Una vez configurado, lo único que nos falta es hacer un push de la última versión de nuestra app. Para ello ejecutaremos git push heroku master. Al realizar el push, Heroku adaptará nuestro proyecto (BBDD y logs) para su correcto funcionamiento

$ git push heroku master
Counting objects: 90, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (82/82), done.
Writing objects: 100% (90/90), 21.44 KiB | 0 bytes/s, done.
Total 90 (delta 4), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Ruby app detected
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.0.0
remote: -----> Installing dependencies using 1.7.12
remote:        Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
remote:        Fetching gem metadata from https://rubygems.org/...........
remote:        Installing rake 10.4.2
[...] Instala todas las gemas [...]
remote:        Installing turbolinks 2.5.3
remote:        Your bundle is complete!
remote:        Gems in the groups development and test were not installed.
remote:        It was installed into ./vendor/bundle
remote:        Post-install message from rdoc:
remote:        Depending on your version of ruby, you may need to install ruby rdoc/ri data:
remote:        <= 1.8.6 : unsupported
remote:        = 1.8.7 : gem install rdoc-data; rdoc-data --install
remote:        = 1.9.1 : gem install rdoc-data; rdoc-data --install
remote:        >= 1.9.2 : nothing to do! Yay!
remote:        Bundle completed (34.42s)
remote:        Cleaning up the bundler cache.
remote: -----> Preparing app for Rails asset pipeline
remote:        Running: rake assets:precompile
remote:        I, [2015-03-25T23:07:25.573293 #1159]  INFO -- : Writing /tmp/build_b8e3435b0d8e41346147ce1d18e9b308/public/assets/application-47fe71a3b34a93e1929c175b1755d405.js
remote:        I, [2015-03-25T23:07:25.661104 #1159]  INFO -- : Writing /tmp/build_b8e3435b0d8e41346147ce1d18e9b308/public/assets/application-3942007d31710307dd44000cb1f768c9.css
remote:        Asset precompilation completed (6.79s)
remote:        Cleaning assets
remote:        Running: rake assets:clean
remote:
remote: ###### WARNING:
remote:        You have not declared a Ruby version in your Gemfile.
remote:        To set your Ruby version add this line to your Gemfile:
remote:        ruby '2.0.0'
remote:        # See https://devcenter.heroku.com/articles/ruby-versions for more information.
remote:
remote: ###### WARNING:
remote:        No Procfile detected, using the default web server (webrick)
remote:        https://devcenter.heroku.com/articles/ruby-default-web-server
remote:
remote: -----> Discovering process types
remote:        Procfile declares types -> (none)
remote:        Default types for Ruby  -> console, rake, web, worker
remote:
remote: -----> Compressing... done, 29.8MB
remote: -----> Launching... done, v6
remote:        https://radiant-island-4647.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/radiant-island-4647.git
 * [new branch]      master -> master

Ya solo falta crear las tablas de BBDD ejecutando heroku run rake db:migrate y estaremos dispuesto para visualizar nuestra app con heroku open

En produccion, si no se define en el router.rb, la raiz del dominio no devuelve nada, al contrario que el entorno de desarrollo

Opcional

Posiblemente la primera vez que subamos una app a Heroku nos saldran algunos de los siguientes warnings:

  • Definir version ruby: Esto se soluciona añadiendo al Gemfile la versión de ruby que utiliza nuestro código:
ruby '2.2.1'
  • No existe Procfile: Este archivo permite configurar los procesos que utilizan las apps, y como se arrancan. En el caso básico, será un proceso web, que arranca el servidor. Heroku recomienda utilizar como servidor Puma en vez de webrick. Para configurarlo tendremos que poner en el Procfile:
web: bundle exec puma -C config/puma.rb

Añadir a Gemfile:

gem 'puma'

Y crear el archivo ./config/puma.rb con:

workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 5)
threads threads_count, threads_count

preload_app!

rackup      DefaultRackup
port        ENV['PORT']     || 3000
environment ENV['RACK_ENV'] || 'development'

on_worker_boot do
  # Worker specific setup for Rails 4.1+
  # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
  ActiveRecord::Base.establish_connection
end

Ahora solo tenemos que actualizar el código en heroku para tener la nueva versión:

$ git commit -a -m "Corrigiendo warnings de heroku"
$ git push heroku master

Nociones básicas de rails

Generar app

Crear una app en un directorio

$ # => rails new <app_name>
$ rails new Blog

Opciones

  • –skip-bundle: Desactiva la ejecucion del bundle install despues de descargar las dependencias
  • -d postgresql: Selecciona la BBDD (defecto sqlite3)
  • –skip-active-record: Si no queremos que nos cree la configuración de ActiveRecord (p.e. si no usamos BB.DD no relacionales como mongodb)
  • –skip-test-unit: Para no generar el codigo de test

Si tenemos varias versiones de rails instaladas y queremos utilizar una versión que no sea la ultima (la por defecto) hay que indicar la versión entre underlines

$ rails _4.1.8_ new Blog

Crear en el directorio actual

$ rails new . 

Ahora para arrancarlo solo tenemos que ejecutar

# => rails s|server
$ rails server 
=> Booting WEBrick
=> Rails 4.2.1 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2015-03-24 23:27:58] INFO  WEBrick 1.3.1
[2015-03-24 23:27:58] INFO  ruby 2.2.1 (2015-02-26) [x86_64-darwin14]
[2015-03-24 23:27:58] INFO  WEBrick::HTTPServer#start: pid=1589 port=3000

Generar codigo

Si queremos generar codigo, podemos usar la opción generate (g) de rails

# => rails g scaffold <modelo> <campo1>:(string|integer|boolean|references) campo2 ... campoN [opciones]
$ rails g scaffold Post title description year:integer
     invoke  active_record
      create    db/migrate/20150324224320_create_posts.rb
      create    app/models/post.rb
      invoke    test_unit
      create      test/models/post_test.rb
      create      test/fixtures/posts.yml
      invoke  resource_route
       route    resources :posts
      invoke  scaffold_controller
      create    app/controllers/posts_controller.rb
      invoke    erb
      create      app/views/posts
      create      app/views/posts/index.html.erb
      create      app/views/posts/edit.html.erb
      create      app/views/posts/show.html.erb
      create      app/views/posts/new.html.erb
      create      app/views/posts/_form.html.erb
      invoke    test_unit
      create      test/controllers/posts_controller_test.rb
      invoke    helper
      create      app/helpers/posts_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/posts/index.json.jbuilder
      create      app/views/posts/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/posts.coffee
      invoke    scss
      create      app/assets/stylesheets/posts.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.scss

Opciones

  • -t=spec: Define la libreria que queremos usar para generar los tests
  • –skip-assets: Si no queremos generar los asset para esta entidad

Si queremos recrear las BB.DD.

$ rake db:create

Para ejecutar los scripts de migracion que recrean los models

$ rake db:migrate

Si queremos inicializar la app con datos, podemos introducirlos en el seed.rb y se ejecutaran con:

$ rake db:seed

el db:setup ejecuta en schema.rb y el seed.rb, pero si se cambia los archivos de migrate no se actualiza el schema.rb automaticamente (no se cuando)

Para borrar lo generado con un scaffold p.e.

$ rails d scaffold Post

Corregir el error de certificados al instalar gems en Windows

Si al intentar instalar una gem en windows nos da un error del estilo:

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

hay que actualizar los certificados siguiendo esta guia

Resumen

  • Descargar e instalar manualmente el update_rubygems correspondiente a nuestra versión de rubygems.
C:\>gem install --local C:\rubygems-update-2.2.3.gem
  • Actualizar rubygems.
C:\>update_rubygems --no-ri --no-rdoc
  • Localizar la ubicacion de gem.
C:\>gem which rubygems
C:/Ruby21/lib/ruby/2.1.0/rubygems.rb
# => la carpeta sera C:/Ruby21/lib/ruby/2.1.0/ssl_certs
  • Descargar y copiar el nuevo certificado en la carpeta indicada en el pto anterior.

probando redis desde docker

Una de las grandes virtudes de docker, es que permite probar tecnologias sin necesidad de “guarrear” nuestra máquina. Para arrancar redis desde docker, simplemente hay que ejecutar: docker run -d -p 6379:6379 redis:2.8.17 redis-cli -h $(boot2docker ip): conectar a un redis en docker (si se ha mapeado el puerto del redis a fuera)

En redis las databases se identifican por numeros. Se seleccciona con “SELECT 1”. Por defecto tiene 16 bd (0-15)

Tutorial REDIS SET server:name “fido” GET server:name => fido SET connections 10 INCR connections => 11 INCR connections => 12 DEL connections INCR connections => 1

EXPIRE server:name 120: fija tiempo de vida variable (integer) 1 redis 192.168.59.103:6379> TTL server:name: muestra tiempo restante

TTL resource:lock (integer) -1 Si no esta definido devuelve -1

RPUSH friends “Alice” (integer) 1 redis 192.168.59.103:6379> RPUSH friends “Bob” LPUSH friends “Sam”

RPUSH puts the new value at the end of the list.

 RPUSH friends "Alice"
 RPUSH friends "Bob"

LPUSH puts the new value at the start of the list.

 LPUSH friends "Sam"

LRANGE friends 0 -1 => 1) “Sam”, 2) “Alice”, 3) “Bob” LRANGE friends 0 1 => 1) “Sam”, 2) “Alice” LRANGE friends 1 2 => 1) “Alice”, 2) “Bob”

LLEN friends => 3

LPOP removes the first element from the list and returns it.

LPOP friends => "Sam"

RPOP removes the last element from the list and returns it.

RPOP friends => "Bob"

SADD adds the given value to the set.


    SADD superpowers "flight"
    SADD superpowers "x-ray vision"
    SADD superpowers "reflexes"

SREM removes the given value from the set.


    SREM superpowers "reflexes"

SISMEMBER tests if the given value is in the set. It returns 1 if the value is there and 0 if it is not.

SISMEMBER superpowers "flight" => 1
SISMEMBER superpowers "reflexes" => 0

SMEMBERS returns a list of all the members of this set.

SMEMBERS superpowers => 1) "flight", 2) "x-ray vision"

SUNION combines two or more sets and returns the list of all elements.

SADD birdpowers "pecking"
SADD birdpowers "flight"
SUNION superpowers birdpowers => 1) "pecking", 2) "x-ray vision", 3) "flight"

Sets are a very handy data type, but as they are unsorted they don’t work well for a number of problems. This is why Redis 1.2 introduced Sorted Sets.

A sorted set is similar to a regular set, but now each value has an associated score. This score is used to sort the elements in the set.

ZADD hackers 1940 "Alan Kay"
ZADD hackers 1906 "Grace Hopper"
ZADD hackers 1953 "Richard Stallman"
ZADD hackers 1965 "Yukihiro Matsumoto"
ZADD hackers 1916 "Claude Shannon"
ZADD hackers 1969 "Linus Torvalds"
ZADD hackers 1957 "Sophie Wilson"
ZADD hackers 1912 "Alan Turing"


HSET user:1000 name "John Smith"
HSET user:1000 email "john.smith@example.com"
HSET user:1000 password "s3cret"

To get back the saved data use HGETALL:

HGETALL user:1000

You can also set multiple fields at once:

HMSET user:1001 name "Mary Jones" password "hidden" email "mjones@example.com"

If you only need a single field value that is possible as well:

HGET user:1001 name => "Mary Jones"

Calcular el espacio de los directorios

  • Una manera sencilla de calcular el espacio de los directorios es usando el comando du
$ du -cksh *
1.7G	Documents
1.6G	Downloads
1.4G	Google Drive
2.2G	Library
 27M	Music
421M	Pictures
 26G	VirtualBox VMs
7.0G	apps
1.1G	biblioteca
208M	eclipse
 91M	sources
# [...]
 44G	total