Deploy Ruby on Rails con Dokku

Soy un fanático de Heroku, hace años atrás un amigo me contó sobre la plataforma y me enamoré al tiro. Me encantó que con un simple git push heroku master podía desplegar una aplicación nueva.

Aún me encanta Heroku y trato de usarlo en la mayoría de mis proyectos, pero ahora que mi empresa ha ido creciendo de a poco y está trabajand0 con clientes un poco más grande no siempre puedo trabajar con Heroku.

Ahi entra Dokku al rescate, me permitió mantener todas las cosas que me encantaban de Heroku pero ahora en un VPS. A continuación voy a mostrar como en Gitz hacemos despliegue de aplicaciones Ruby on Rails utilizando Dokku y Ubuntu.

Para poder hacer todo lo que aparece en el tutorial, es necesario acceso SSH al servidor. Para instrucciones sobre como hacer esto revisa este artículo de Digital Ocean: https://www.digitalocean.com/community/tutorials/how-to-connect-to-your-droplet-with-ssh.

Instalación de Dokku

Para instalar Dokku en el servidor primero necesitamos ingresar al servidor mediante SSH.

$ ssh <user>@<mi.servidor.com>

Luego instalamos la última versión de Dokku (en este caso la 0.7.2) con estos comandos:

$ wget https://raw.githubusercontent.com/dokku/dokku/v0.7.2/bootstrap.sh
$ sudo DOKKU_TAG=v0.7.2 bash bootstrap.sh

Configuración SSH

Ahora es necesario asegurarse que el usuario dokku puede conectarse mediante SSH, ya que este es el usuario que se utilizará para subir el código a través de git. Para esto agrega el usuario dokku al archivo authorized_keys:

$ cat /root/.ssh/authorized_keys | sshcommand acl-add dokku dokku

Crear la Aplicación

Ahora es necesario crear la aplicación para poder subir esta al servidor.

$ dokku apps:create <nombre-app>

Esto creará un contenedor con el nombre <nombre-app>.

Crear Base de Datos

Para configurar una base de datos PostgreSQL es necesario instalar un plugin.

$ sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres

Luego se crea la base de datos.

$ dokku postgres:create <nombre-app>-postgres

Con la base de datos creadas se debe linkear esta con la aplicación:

$ dokku postgres:link <nombre-app>-postgres <nombre-app>

Ahora deberás agregar el URL de Postgres al archivo database.yml:

development:
adapter: postgresql
database: <nombre-app>_dev
host: localhost
test:
adapter: postgresql
database: <nombre-app>_test
host: localhost
<% if ENV['POSGRESQL_URL'] %>
production:
adapter: postgresql
url: <%= ENV['POSTGRESQL_URL'] %> # Variable de ambiente de Dokku
encoding: unicode
pool: 5
<% end
%>

Subir la Aplicación

Ahora en tu máquina local debes agregar un git remote hacia dokku.

$ git remote add dokku dokku@IP.O.DOMINIO.SERVIDOR:<nombre-app>

Ahora deberás configurar los pre-flight checks de Dokku. Para hacer esto debes crear un archivo CHECKS en la ruta del proyecto:

$ touch CHECKS

Luego debes abrir el archivo creado y pegar lo siguiente:

WAIT=8 # Espera 8 segundos para cada intento
ATTEMPTS=6 # Intenta 6 veces y si no funciona, deploy fracasó y se utilizará el contenedor antiguo.
/check_deploy.txt deploy_successful

Importante: Debes dejar una última línea vacía en el archivo, sino Dokku podría no visualizar el cambio.

Ahora debes crear un archivo check_deploy.txt en la carpeta public:

$ cd public
$ touch check_deploy.txt
$ echo "deploy_successful" >> check_deploy.txt

Por último para finalizar el deploy debes hacer commit y subir el código con este comando:

$ git push dokku master

Configurar Nginx

Esto es opcional pero recomendado. Para poder agregar configuraciones específicas de Nginx a la app es necesario crear una carpeta llamada nginx.conf.d y dentro de esa carpeta agregar archivos de configuración. Es recomendado aumentar el tamaño máximo de un archivo que se puede subir a la aplicación, para esto:

$ mkdir /home/dokku/<nombre-app>/nginx.conf.d/
$ chown dokku:dokku /home/dokkku/<nombre-app>/nginx.conf.d/
$ echo 'client_max_body_size 50M;' > /home/dokku/<nombre-app>/nginx.conf.d/upload.conf
$ service nginx reload

Instalar Dokku Logging

Este último paso es importante ya que Dokku solamente corre procesos web por defecto en el Procfile. Debes instalar esto en el servidor (accede mediante SSH) y ejecutar este comando:

$ dokku plugin:install https://github.com/sehrope/dokku-logging-supervisord.git dokku-logging-supervisord

Todos los deploys en el futuro utilizaron este plugin para iniciar todos los procesos y logear todo el output en /var/log/dokku/$APP/.

Configurar Scaling

Para configurar el scaling de la App es necesario agregar un archivo DOKKU_SCALE al proyecto. Este archivo debería tener el número de procesos a ejecutar por tipo de procesos. Nota: Los nombres de los procesos deberían ser los mismos que aparecen en el Procfile de la aplicación.

web=1
worker=1

Con todo lo anterior deberías quedar con tu propio Heroku. También para que puedas ejecutar comandos dokku simplemente desde tu maquina local en el servidor recomiendo instalar dokku-cli.

Si encuentran algún error o cualquier mejora por favor dejen sus comentarios. Gracias.