En publicaciones anteriores, te hemos hablado en varias oportunidades de opciones cloud para el alojamiento de nuestras aplicaciones. En Garage Labs preferimos a Amazon Web Services (en adelante AWS), que es por lejos lo mejor que existe en el mercado.
Existen muchas razones por la que debes elegir a este proveedor para aprovisionar infraestructura para tus aplicaciones, que no las definiremos aquí, pero solo mencionaremos las siguientes:
- Costo, pagas solo por lo que usas.
- Escalabilidad, no necesitas aprovisionar grandes cantidades de infraestructura, ya que crece contigo.
- Performance, una gran cantidad de herramientas que te ayudan a optimizar el uso de recursos.
- Respaldo de un gigante de la informática.
Para esta publicación utilizaremos tan solo el servicio de Elastic Cloud Compute (EC2), para el levantamiento de instancias que hagan de servidor de aplicaciones. Por esta oportunidad también levantaremos el servicio de base de datos y almacenamiento de archivos en la misma instancia, pero dejemos en claro que AWS posee servicios auto-administrados de bases de datos (RDS) y de almacenamiento (S3), que podemos explicar su funcionamiento en siguientes publicaciones y además mostrar como “conversan” los distintos servicios.
¿Qué es Capistrano?
Es una herramienta de código abierto para ejecutar scripts en múltiples servidores; su uso principal es la implementación de aplicaciones web. Automatiza el proceso de hacer que una nueva versión de una aplicación esté disponible en uno o más servidores web, incluidas las tareas de soporte como el cambio en la base de datos, ejecución de tareas, entre otros. Ademas permite el despliegue en distintos proveedores simultáneamente.
Gracias a esta herramienta podemos poder empezar a pensar en lo que es ofrecer el servicio de entrega continua o mas adelante integración continua.
A lo nuestro
Bueno no te mareo más con definiciones y explicaciones, si quieres más información búscala por ti mismo, no es por lo que estas leyendo esto, ¿no?
En esta publicación vamos a crear una aplicación con Ruby On Rails básica, con conexión a una base de datos PostgreSQL, le instalaremos la gema de Capistrano y configuraremos para el despliegue en nuestra instancia de AWS que le instalaremos todo lo necesario mediante SSH.
- OJO: Puedes usar una cuenta gratuita de AWS, solo necesitas una tarjeta de crédito. No te hará cobros extras a no ser que te pongas a levantar servicios como loco.
Creando la aplicación
Partamos creando una nueva aplicación en rails, como cualquier otra, utilizando el comando:
rails new test-capistrano
Eso nos creará una nueva aplicación, vamos ahora a agregar las gemas necesarias en el archivo Gemfile. Las cuales, son las siguientes:
gem 'pg', '~> 0.18.4'
group :development, :test do
# Capistrano para despliegue de aplicación en servidor remoto
gem ‘capistrano’, ‘~> 3.0’
gem ‘capistrano-rvm’
gem ‘capistrano-bundler’, ‘1.1.1’
gem ‘capistrano-rails’, ‘1.1.3’
gem ‘capistrano-sidekiq’, github: ‘seuros/capistrano-sidekiq’ # No es necesaria
end
Obvio las versiones responden al momento en el que se desarrolló este post. La primera gema tiene que ver con PostgreSQL, que será nuestro motor de base de datos. Las primeras 4 gemas con las más importantes para poder utilizar Capistrano con RubyOnRails y RVM (no recomiendo Rbenv). La última gema no la utilizaremos, pero la pongo, para mostrar que es posible ejecutar varios tipos de script con Capistrano, en este caso sidekiq. No se olviden de eliminar la gema de sqlite.
Luego necesitamos crear un archivo de configuración para la base de datos, puede usar el siguiente como ejemplo:
Luego correr los típicos comandos:
bundle install
rake db:create
Y estarán instaladas nuestras gemas y creadas nuestras bases de datos. Puedes ejecutar el comando rails s en la consola para verificar todo y luego entrar a localhost:3000 para comprobar el trabajo bien hecho.
Agregando contenido a la web
Vamos a crear una pequeña aplicación rápidamente y sin interfaz decente alguna. Solo queremos mostrar la ejecución de script con Capistrano.
Generemos un scaffold de Posts, nada complejo, típico blog.
rails g scaffold post name:string body:text
Luego generemos los cambios en la base de datos, ejecutando las migraciones, que el scaffold creo por nosotros.
rake db:migrate
Listo! Aplicación rails, que crea posts en base de datos Postgres.
Finalmente debemos crear el archivo secrets.yml en la carpeta config/, donde debemos crear las variables del secret_key_base para nuestra aplicación. Asumiré que tienes conocimiento de este archivo y que sabes como crearlo y darle las variables (rails secret RAILS_ENV=development o test o production).
¿Cómo se configura Capistrano?
Pueden encontrar la documentación de la gema aquí. Yo les daré algunos tips para empezar rápidamente.
En pasos anteriores ya dejamos instalada la gema de Capistrano, ahora solo queda correr los instaladores y empezar a configurar. Ejecutamos el siguiente comando:
bundle exec cap install
Y tendremos una salida como la siguiente:
Agreguemos un par de lineas a los archivos creados:
Luego debemos meternos en config/deploy.rb para configurar todas las tareas de despliegue. Importante: debes tener un repositorio en github (o el de tu preferencia), con una llave SSH registrada y con la capacidad de hacer push a través de SSH. Asumiré que esto último sabes como manejarlo, de no ser así, nos plantearemos la necesidad de hacer otro tutorial de como realizar la tarea, pero es tan corta y fácil, que no sé si amerita uno. De todos modos te dejo uno de Github.
Bueno, ahora el deploy.rb:
Configurado todo esto, es el momento de empezar a usar Amazon. Luego volveremos a la aplicación a configurar lo último que necesitamos antes de salir a producción.
Creando y configurando instancias en AWS
Para poder usar los servicios de AWS sin gastar dinero, puedes moverte por la capa gratuita que ellos proveen. Puedes ver la especificación de servicios gratuitos aquí. Para usarlos solo debes crear una cuenta en el proveedor, asociar una tarjeta de crédito (obvio, te van a cobrar si te pasas del free tier, es una economía de escala multinacional, que más esperas). Si te mantienes dentro de los intervalos de lo que te regalan, puedes usar sus servicios gratis por un año.
El servicio de AWS que usaremos es EC2 (Elastic Compute Cloud), el servicio de instancias. Para ello seleccionamos el servicio en el menú.
Luego una vez dentro del servicio, lanzar una nueva instancia.
En el siguiente paso, se debe seleccionar un AMI, que son imágenes de instancias para no partir desde 0. Nosotros recomendamos la de Ubuntu, que es fácil de configurar y se encuentra dentro del free tier. a
Luego, es necesario elegir el tipo de instancia, ojo selecciona solo aquellas que se encuentre en el free tier, te recomendamos, t2.micro:
En el paso 3, deja todo como esta, de momento no nos importan esas configuraciones. En general tienen que ver con las redes y monitoreo.
En el paso 4, Almacenamiento, deja todo tal cual, los 8 gb de almacenamiento de General Purpose SSD.
En el paso 5, agrega algunos Tags si lo consideras necesario. Sirven para diferencias tus recursos. Muy útil si quieres diferencias las cuentas de tus clientes para hacer cobros.
En el paso 6, es muy importante abrir un puerto HTTP, para que la web pueda ser accedida. El SSH es necesario de igual forma, para que podamos hacer el deploy. Te recomiendo en el source, seleccionar tu propia IP, por temas de seguridad.
En el paso 7, puedes hacer una revisión de todos los pasos anteriores, y finalmente presionar “Launch”, para que la instancia se inicie.
Se pedirán generar un archivo .pem, descárgalo y guárdalo, es la única forma de acceder a la instancia. Si lo pierdes, quedará inaccesible.
Listo, ya tenemos nuestra instancia iniciada en Amazon. En el menu “Instances” puedes verla ya en funcionamiento.
Instalación de entorno de producción
Con el archivo .pem, conseguido a partir del proceso anterior, posiciónate en la carpeta contenedora mediante el comando “cd”. Si es la primera vez que se conecta a la instancia, es necesario entregar los permisos respectivos al archivo .pem para realizar la conexión, a través del siguiente comando:
chmod 400 mi-llave.pem
Con este archivo, y los permisos respectivos, ingresar el siguiente comando en un terminal, para ingresar por SSH a la instancia:
ssh -i “cliente.pem” ubuntu@ec2-xx-xxx-xxx-xx.us-east-2.compute.amazonaws.com
Donde en las “x” se debe escribir el número IP.
Instalando RVM y Ruby
Primero debes obtener versión más reciente de RVM, mediante el siguiente comando:
curl -L https://get.rvm.io | bash -s stable — ruby
En este paso puede ocurrir algún problema en la instalación de RVM causado por GPG. Para solucionarlo, instale gpg2 con el comando sudo apt install gnupg2 y luego agregue la nueva llave pública que se indica en el output del error con el comando gpg2 — recv-keys [nueva llave pública].
Debe cerrar sesión con SSH y volver a ingresar para hacer uso de RVM.
RVM permite administrar diversas versiones de ruby y conjuntos de gemas para el lenguaje.
Para el caso de estas versión se utilizará la versión 2.5.3 del lenguaje, por lo que se deben ingresar los siguientes comandos en el terminal:
rvm install ruby-2.5.3
rvm — default use ruby-2.5.3
Finalmente como gestor de dependencias, se utiliza el más conocido para Ruby, el bundler, mediante el siguiente comando:
gem install bundler — no-rdoc — no-ri
Finalmente instala Node.js, con el siguiente comando:
sudo apt-get install -y nodejs &&
sudo ln -sf /usr/bin/nodejs /usr/local/bin/node
Instalando Ruby On Rails
Para efectos de estar versión del tutorial se utilizará la versión 5.2.3 del framework.
gem install rails -v 5.2.3
Instalando Apache
Primero debes actualizar los repositorios. Con el siguiente comando:
sudo apt-get update
Luego simplemente instalar Apache con el siguiente comando (van algunos paquetes complementarios):
sudo apt-get install apache2 curl git build-essential zlibc zlib1g-dev zlib1g libcurl4-openssl-dev libssl-dev libapr1-dev libaprutil1-dev libreadline6 libreadline6-dev
Instalando PostgresSQL
Solo necesitas ingresar el siguiente comando:
sudo apt-get install postgresql postgresql-contrib
Ingresar con el usuario postgres, que se crea como súper usuario, para generar otro, que será el encargado de la conexión de la aplicación.
sudo -i -u postgres
Luego con la sesión iniciada, se debe crear el otro usuario, mediante el siguiente comando:
createuser — interactive
Esta funcionalidad, permite la creación del usuario dinámicamente, como muestra a continuación:
Output
Enter name of role to add: appuser
Shall the new role be a superuser? (y/n) y
Luego también es importante ingresar al cliente de postgres para crear la contraseña del nuevo usuario, de la siguiente forma (para aplicaciones serias, por favor no uses credenciales de este estilo):
psql
\password appuser
Enter pass: appuser
Repeat: appuser
Finalmente se deben instalar las librerías para comunicar la gema de rails con postgres, con el siguiente comando:
sudo apt-get install libpq-dev
Instalando Passenger y el módulo de Apache
Passenger será el encargado de desplegar la aplicación de RoR en el servidor apache, esta comunicación se logra gracias al modulo que instalaremos también. Primero se instalan algunos paquetes complementarios, para que Passenger funcione correctamente:
sudo apt-key adv — keyserver hkp://keyserver.ubuntu.com:80 — recv-keys 561F9B9CAC40B2F7
sudo apt-get install -y apt-transport-https ca-certificates
Posteriormente se agregan los enlaces a los repositorios donde se encuentran Passenger y su módulo:
sudo sh -c ‘echo deb https://oss-binaries.phusionpassenger.com/apt/passenger bionic main > /etc/apt/sources.list.d/passenger.list’
Y se instalan Passenger y el módulo para apache:
sudo apt-get install -y libapache2-mod-passenger
Luego se comunica a Apache 2 con el módulo de Passenger y reinicia el servidor:
sudo a2enmod passenger
sudo apache2ctl restart
Finalmente se valida la instalación mediante el siguiente comando (selecciona Apache y Passenger):
sudo /usr/bin/passenger-config validate-install
s importante considerar que es posible que la validación de Apache falle, de ser así el mismo programa de validación sugerirá la instalación de un componente, copiar el comando, instalar y eso solucionará el problema (sudo apt-get install apache2-dev).
Listo el entorno de producción, ahora para no volver a instalar todo en tus siguientes desarrollos, puedes generar un AMI en AWS (ojo se cobra). Botón derecho en la instancia -> Image -> Create Image.
Configurando los environments de Capistrano
En Capistrano tenemos la posibilidad de configurar varios ambientes de despliegue, por defecto staging y production. Esto en la práctica se utiliza para hacerles despliegues en distintos ambiente para realizar pruebas. Para este tutorial usaremos uno de los que vienen definidos por defecto staging.
El cual debería quedar se la siguiente forma:
Con todo esto configurado, queda solo el último paso, hacer el despliegue.
Desplegando la aplicación en AWS
Para poder realizar esta tarea, basta con ingresar el siguiente comando en la terminal, posicionada en la raíz del proyecto:
cap staging deploy
Donde “cap” es el comando que llama a Capistrano, “staging” es el entorno definido en la carpeta deploy, y el último es la tarea necesaria para realizar el despliegue.
Si realizaste todo bien. Deberías ver algo como esto:
Donde solo debes presionar “enter”, para iniciar el proceso.
A lo largo del despliegue veras un montón de comandos que el script correrá, solo debes esperar a que termine y que ninguno falle.
Si todo salió bien, deberías ver un mensaje como el siguiente en tu consola:
Quizás tengas algunos problemas haciendo el despliegue, al correr los script para crear y migrar la base de datos, hay algunos métodos para corregir eso en el despliegue, pero como solo es el primero, te conviene más entra a la maquina, en la ruta del proyecto y correrlos tu misme a mano. (rake db:create RAILS_ENV=production)
Pasos finales
Ahora ya tenemos la aplicación desplegada y lista en la maquina, ahora solo queda configurar apache y passenger para que identifiquen la página.
Primero debemos entrar a la carpeta de configuración de apache, agregar un nuevo archivo de configuración para el sitio (o editar alguno que ya exista). Te dejamos un ejemplo para que puedes usarlo como gustes.
Una vez configures el dominio y la ruta (no es necesario el dominio, si no tienes uno, puedes acceder por la ip). Debes agregar el sitio al registro de apache con el siguiente comando:
sudo a2ensite test-capistrano.conf
Obviamente reemplaza test-capistrano, por el nombre del archivo que tu hayas elegido.
Luego simplemente recarga los sitios del servidor con el siguiente comando:
sudo service apache2 reload
Luego si pones la ip o el dominio en un navegador, podrás ver tu sitio.
Es posible que tengas algunos problemas si usas la ip, y que cuando entres te siga mostrando el sitio por defecto de apache, y tendrás que deshabilitarlo con el comando sudo a2dissite 000-default.conf.
Es posible que cuando ingreses por primera vez, aparezca un error, de passenger
Eso es porque no se ha configurado correctamente el secret_key_base, eso se hace de la siguiente forma:
- Ingresa a la instancia mediante SSH
- Posiciónate mediante el comando cd en la carpeta del proyecto (Ej: /var/www/html/test_proyecto/current/, ojo debe ser current, ya que capistrano tiene esa estructura)
- Ingresar el comando: bundle exec rake secret RAILS_ENV=production
- Resulta algo como lo siguiente:
- Copiar la cadena de texto y pegarla en el secrets.yml (o trabajarla como variable de entorno).
- Debe ser el entorno de producción:
- Reinicia el servidor nuevamente
Finalmente puedes entrar al domino o tu ip, en la ruta /posts para verificar tu trabajo.
Finalmente
Si sigues los pasos que te entregamos tendrás un sitio web corriendo en AWS, y gran parte de la curva de aprendizaje ya la habrás superado. Hay muchos detalles que no abordamos aquí, pero que irás puliendo en medida que vayas avanzando en tus despliegues y conociendo un montón de servicios complementarios del proveedor que pueden potenciar en gran medida tus desarrollos; pero eso ya es materia de otro post. No olvides dejar tus comentarios si lo estimas o contactarnos en Garage Labs si necesitas ayuda.
Garage Labs
Publicaciones oficiales de la consultora tecnológica Garage Labs | Santiago de Chile