馃殌Gu铆a general para correr Ruby on Rails con Docker馃殌

Andr茅s

20 October 2023

4 mins

馃殌Gu铆a general para correr Ruby on Rails con Docker馃殌

Probablemente, ya conoces las ventajas de usar Docker, ya lo hemos escuchado o evidenciado en proyectos. Aqu铆 te mostrar茅 como llevar eso a tu aplicaci贸n Ruby on Rails. Para realizar lo que se propone necesitas una aplicaci贸n Rails, Docker instalado en tu computador y/o tu servidor y motivaci贸n para un par de pruebas y error.

Esto es una explicaci贸n general y no una gu铆a paso a paso. Puede que algunas definiciones necesiten m谩s trabajo dependiendo de tu proyecto.

Dockerfile

Necesitar谩s un archivo Dockerfile en la ra铆z de tu proyecto con el siguiente contenido:

FROM ruby:3.2.2

RUN apt-get update && apt-get install -y libsodium-dev

WORKDIR /app

COPY Gemfile Gemfile.lock ./

RUN gem install bundler && bundle install

COPY . .

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

Explicaci贸n paso a paso:

  1. El comando FROM se utiliza para especificar la imagen base sobre la cual correr谩 el proyecto. En mi caso me sirve la imagen ruby:3.2.2 porque mi proyecto utiliza esa versi贸n de Ruby.
  2. Si la imagen que eliges no viene con todos los paquetes que tu aplicaci贸n necesita, entonces tendr谩s que instalarlos. Eso es lo que pasa en la l铆nea:
RUN apt-get update && apt-get install -y libsodium-dev

Por ejemplo, si tu aplicaci贸n utiliza libvips para el procesamiento de im谩genes, entonces tendr谩s que agregar el comando correspondiente para instalarla aqu铆. Puedes fijarte si la imagen que eliges contiene el paquete que necesitas en la [p谩gina](https://hub.docker.com/layers/library/ruby/3.2.2/images/sha256-cd6e6798429527289a12f541f75f2e632164 9b5195bd88a0d97415bbc58cd45c?context=explore) de la imagen

  1. Definimos un directorio de trabajo
  2. Copiamos el Gemfile al directorio de trabajo.
  3. Instalamos las gemas de las que depende nuestro proyecto.
  4. Copiamos el resto del proyecto.
  5. Copiamos y definimos nuestro ENTRYPOINT

ENTRYPOINT

驴Por qu茅 un entrypoint? B谩sicamente, porque hay comandos que deben correr al momento de levantar un contenedor con nuestra imagen y no al momento de la construcci贸n de la imagen. Un claro ejemplo de esto es el comando db:migrate.

Entonces necesitaremos de otro archivo en la ra铆z de nuestro proyecto llamado entrypoint.sh con el siguiente contenido:

#!/bin/bash

if [ -f tmp/pids/server.pid ]; then
  rm tmp/pids/server.pid
fi

RAILS_ENV=$RAILS_ENV bundle exec rails db:migrate

RAILS_ENV=$RAILS_ENV bundle exec rails s -b 0.0.0.0

Explicaci贸n paso a paso:

  1. Definici贸n de bash script para que corra como tal al momento de la ejecuci贸n.
  2. Eliminamos cualquier server.pid previo.
  3. Ejecutamos cualquier migraci贸n pendiente de nuestra aplicaci贸n.
  4. Corremos nuestro servidor web.

Puede que seg煤n tus necesidades tengas que crear diferentes entrypoints. Imaginemos el caso de que est谩s usando whenever. Tu entrypoint deber谩 actualizar el crontab cada vez que se ejecute, pero tampoco quieres que todos tus contenedores corran los cronjobs al mismo tiempo. Entonces ah铆 es cuando necesitas de un contenedor que corra tu servicio web y otro con tus cronjobs. O sea, dos entrypoints diferentes para el mismo proyecto.

Para resolver ese caso puedes crear una carpeta en tu proyecto con el nombre entrypoints y dejar tus diferentes entrypoints ahi. Tu Dockerfile queda con un entrypoint por 鈥渄efecto鈥 y cuando necesites lo sobreescribes al momento de correr un contenedor con el flag --entrypoint.

ENVs

Dependiendo del entorno en que estamos ejecutando nuestro proyecto, es importante agregar algunas ENVs al contenedor:

  1. RAILS_MASTER_KEY a mi parecer es la forma m谩s f谩cil de permitirle a la app leer el archivo credentials.yml.enc.
  2. DATABASE_URL url completa a tu base de datos, ya sea mysql o postgresql.
  3. RAILS_SERVE_STATIC_FILES si tus archivos javascript y css ser谩n servidos por tu app y no un CDN.
  4. RAILS_LOG_TO_STDOUT as铆 tus logs podr谩n ser vistos por el servicio que uses y por ti.

Test en local

Si quieres probar tu imagen puedes construirla en local con el siguiente comando:

docker build -t rubyapp .

Luego puedes correr un contenedor a partir de tu imagen:

docker run -p 3000:3000 -e DATABASE_URL={YOUR_DATABASE_URL_HERE} rubyapp

Observaci贸n: Aqu铆 es donde necesitaras agregar las variables de entorno, al menos la base de datos.


Nuestro Dockerfile puede volverse m谩s complejo seg煤n nuestras necesidades, pero siempre que se comprenda su funcionamiento, no resultar谩 dif铆cil adaptarlo y realizar modificaciones. Espero que estas indicaciones sean de utilidad, y si consideras que falta alg煤n tema importante, no dudes en dejarme un comentario al respecto.

disfruta programando

隆Hola a todos! 馃憢 驴Disfrutaron leyendo el art铆culo? 隆Me encantar铆a conocer sus opiniones! 馃挰 No duden en dejar un comentario abajo, ya sea para compartir sus comentarios, preguntas o simplemente saludar. 隆No es necesario registrarse, solo compartan algo valioso! 馃槉
Hey there! 馃憢 Enjoyed reading the post? I'd love to hear your thoughts! 馃挰 Feel free to drop a comment below鈥攚hether it's feedback, questions, or just saying hi. No need to sign up, just share something valuable! 馃槉