<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>articulos on luis angel ortega</title><link>https://luisangel.me/es/categories/articulos/</link><description>Recent Articulos on luis angel ortega</description><generator>Hugo</generator><language>es-MX</language><managingEditor>hey@luisangel.me (Luis Angel Ortega)</managingEditor><webMaster>hey@luisangel.me (Luis Angel Ortega)</webMaster><copyright>2025 Luis Angel Ortega Holguin All rights reserved</copyright><lastBuildDate>Thu, 26 Jun 2025 17:00:00 +0000</lastBuildDate><atom:link href="https://luisangel.me/es/categories/articulos/index.xml" rel="self" type="application/rss+xml"/><item><title>¿Para quién estamos digitalizando la educación? Una llamada urgente a la accesibilidad</title><link>https://luisangel.me/es/post/2025/06/26/digitalizando-la-educacion/</link><pubDate>Thu, 26 Jun 2025 17:00:00 +0000</pubDate><author>hey@luisangel.me (Luis Angel Ortega)</author><guid>https://luisangel.me/es/post/2025/06/26/digitalizando-la-educacion/</guid><description>&lt;p>Desde hace más de dos décadas, hablar de transformación digital en la educación se ha vuelto casi obligatorio. Se invierte en plataformas, se promueven nuevas metodologías y se celebran los avances tecnológicos en las aulas. Pero hay una pregunta que rara vez se formula con claridad: &lt;strong>¿para quién estamos digitalizando?&lt;/strong>&lt;/p>
&lt;p>El entusiasmo por la innovación ha dejado fuera un elemento esencial: la accesibilidad. No se trata solamente de si una persona tiene internet, sino de si puede usar, entender y beneficiarse de las herramientas educativas disponibles desde su contexto. Y en México, ese contexto suele ser un celular de gama media, una conexión móvil intermitente y la ausencia de una computadora en casa.&lt;/p>
&lt;p>Según datos del INEGI (2024), &lt;strong>más del 97% de las personas usuarias de internet en el país se conecta desde su celular&lt;/strong>, mientras que &lt;strong>menos del 44% de los hogares tiene una computadora&lt;/strong>. Además, la velocidad promedio de conexión móvil —25 Mbps— es apenas suficiente para navegación básica, no para plataformas pesadas llenas de animaciones, videos incrustados y carga visual innecesaria.&lt;/p>
&lt;p>Pese a esta realidad, seguimos impulsando plataformas que no están pensadas para esa mayoría. Herramientas como Genially, Canva o incluso Moodle con temas pesados se convierten en un obstáculo para muchos estudiantes. No por falta de interés, sino porque simplemente &lt;strong>no cargan&lt;/strong> o saturan el equipo. El mensaje es claro: si no tienes el hardware o la conexión correcta, estás fuera.&lt;/p>
&lt;p>No se trata de rechazar la tecnología. Se trata de exigir que se piense desde el usuario real y no desde el escritorio del diseñador o del tomador de decisiones. Una plataforma educativa que no funcione sin conexión, que no se adapte a pantallas pequeñas o que requiera equipos costosos &lt;strong>no está pensada para incluir, sino para excluir&lt;/strong>.&lt;/p>
&lt;p>Docentes, directivos y desarrolladores deben comprender que la transformación digital no es sinónimo de sofisticación ni de estética. Es una oportunidad para hacer las cosas mejor, para cerrar brechas, no para abrir nuevas. Apostar por sitios ligeros, diseño responsivo, estándares abiertos y software libre no es solo una decisión técnica: &lt;strong>es una postura ética y pedagógica&lt;/strong>.&lt;/p>
&lt;p>En un país con tanta diversidad social y tecnológica, no basta con ofrecer acceso. Hay que pensar en el uso real, cotidiano, situado. Mientras no tomemos en serio la accesibilidad digital, cualquier intento de inclusión será solo una promesa vacía. Y la brecha, lejos de cerrarse, seguirá creciendo… cargando lento.&lt;/p>
&lt;hr>
&lt;h3 id="referencias">Referencias&lt;/h3>
&lt;ul>
&lt;li>
&lt;p>Covarrubias Hernández, L. Y. (2021). &lt;em>Educación a distancia: transformación de los aprendizajes&lt;/em>. &lt;em>Telos: Revista de Estudios Interdisciplinarios en Ciencias Sociales&lt;/em>. Recuperado de la base de datos Gale: Informe Académico &lt;a href="https://doi.org/10.36390/telos231.12">https://doi.org/10.36390/telos231.12&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Fernández-Enguita, M. (2023). &lt;em>La quinta ola: la transformación digital del aprendizaje, de la educación y de la escuela&lt;/em>. Ediciones Morata, S. L. Recuperado de la base de datos eLibro Cátedra &lt;a href="https://elibro.net/es/lc/bibliotecauveg/titulos/232678">https://elibro.net/es/lc/bibliotecauveg/titulos/232678&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Instituto Nacional de Estadística y Geografía. (2025, mayo 6). &lt;em>Encuesta Nacional sobre Disponibilidad y Uso de Tecnologías de la Información en los Hogares (ENDUTIH) 2024: Principales resultados&lt;/em>. &lt;a href="https://www.inegi.org.mx/programas/endutih/2024/">https://www.inegi.org.mx/programas/endutih/2024/&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Speedtest by Ookla. (2024). &lt;em>Speedtest Global Index – Mexico&lt;/em>. &lt;a href="https://www.speedtest.net/global-index/mexico">https://www.speedtest.net/global-index/mexico&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The Competitive Intelligence Unit. (2024). &lt;em>Mercado de smartphones en México, 1T-2024&lt;/em>. &lt;a href="https://www.theciu.com/publicaciones-analisis/2024/03/smartphones-en-mexico-1T-2024">https://www.theciu.com/publicaciones-analisis/2024/03/smartphones-en-mexico-1T-2024&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Públicado originalmente en el blog de &lt;a href="https://eltelar.xyz/blog/para-quien-estamos-digitalizando-la-educacion/">El telar&lt;/a>&lt;/p>
&lt;/blockquote></description></item><item><title>Dropdowns y Toggles con puro CSS</title><link>https://luisangel.me/es/post/2022/11/05/dropdowns-y-toggles-con-css/</link><pubDate>Sat, 05 Nov 2022 11:53:11 -0500</pubDate><author>hey@luisangel.me (Luis Angel Ortega)</author><guid>https://luisangel.me/es/post/2022/11/05/dropdowns-y-toggles-con-css/</guid><description>&lt;p>Podríamos imaginar las tecnologías de la plataforma en la cual trabajo, &lt;a href="https://www.joinbuildit.com/">Build It&lt;/a>, como un platillo; donde Ruby on Rails es nuestro platillo principal pero está acompañada de una buena porción al lado de JavaScript a través de &lt;a href="https://stimulus.hotwired.dev/">Stimulus JS&lt;/a>, y mientras esta trae la funcionalidad y ese sentimiento mágico de una aplicación de una sola página (SPA, por sus siglas en inglés) hay cosas que queremos mantener simple en lugar de usar una bomba para matar una hormiga, como un profesor de la universidad solía decir. Por ello decidimos tomar nota de la página de &lt;a href="https://apple.com/mx">Apple&lt;/a> a la hora de manejar menús desplegables o dropdown y hacerlo por medio de puro CSS y HTML; sin requerir una línea de JavaScript.&lt;/p>
&lt;h2 id="los-pilares">Los pilares&lt;/h2>
&lt;p>Nuestros dos pilares en la vista serán los elementos &lt;code>&amp;lt;input&amp;gt;&lt;/code> de tipo checkbox y las etiquetas &lt;code>&amp;lt;label&amp;gt;&lt;/code>. Formaremos nuestro esqueleto básico de la siguiente manera:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#ca9ee6">input&lt;/span> &lt;span style="color:#8caaee">id&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>&lt;span style="color:#a6d189">&amp;#34;toggle&amp;#34;&lt;/span> &lt;span style="color:#8caaee">type&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>&lt;span style="color:#a6d189">&amp;#34;checkbox&amp;#34;&lt;/span>&amp;gt;&amp;lt;/&lt;span style="color:#ca9ee6">input&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#ca9ee6">label&lt;/span> &lt;span style="color:#8caaee">for&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>&lt;span style="color:#a6d189">&amp;#34;toggle&amp;#34;&lt;/span>&amp;gt;&amp;lt;/&lt;span style="color:#ca9ee6">label&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Estaremos usando la propiedad checked de los inputs tipo checkbox para poder controlar el contenido que mostramos y cuando lo mostramos. Para esto nos estaremos apoyando del elemento &lt;code>&amp;lt;label&amp;gt;&lt;/code> ya que al relacionarlo a través de su propiedad &lt;code>for&lt;/code> también será afectado por el cambio de clases cuando la propiedad checked de nuestro checkbox se encuentre presente.&lt;/p>
&lt;p>Todo nuestro código realmente se encontrará dentro de &lt;code>&amp;lt;label&amp;gt;&lt;/code> en dos secciones: container y toggle como se muestra a continuación.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-html" data-lang="html">&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#ca9ee6">input&lt;/span> &lt;span style="color:#8caaee">id&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>&lt;span style="color:#a6d189">&amp;#34;toggle&amp;#34;&lt;/span> &lt;span style="color:#8caaee">type&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>&lt;span style="color:#a6d189">&amp;#34;checkbox&amp;#34;&lt;/span>&amp;gt;&amp;lt;/&lt;span style="color:#ca9ee6">input&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;&lt;span style="color:#ca9ee6">label&lt;/span> &lt;span style="color:#8caaee">for&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>&lt;span style="color:#a6d189">&amp;#34;toggle&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#ca9ee6">div&lt;/span> &lt;span style="color:#8caaee">class&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>&lt;span style="color:#a6d189">&amp;#34;toggle&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#737994;font-style:italic">&amp;lt;!-- El elemento con el cual el usuario va a interactuar --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;/&lt;span style="color:#ca9ee6">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#ca9ee6">div&lt;/span> &lt;span style="color:#8caaee">class&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>&lt;span style="color:#a6d189">&amp;#34;container&amp;#34;&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#737994;font-style:italic">&amp;lt;!-- Lo que queremos mostrar--&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;/&lt;span style="color:#ca9ee6">div&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;/&lt;span style="color:#ca9ee6">label&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="la-magia">La magia&lt;/h2>
&lt;p>Ahora que ya tenemos nuestro esqueleto con HTML listo, es hora de agregar el CSS que le dará el toque mágico a nuestro componente:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-css" data-lang="css">&lt;span style="display:flex;">&lt;span>#&lt;span style="color:#ef9f76">toggle&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">display&lt;/span>: &lt;span style="color:#ef9f76">none&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>.&lt;span style="color:#e5c890">container&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">display&lt;/span>: &lt;span style="color:#ef9f76">none&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>#&lt;span style="color:#ef9f76">toggle&lt;/span>:&lt;span style="color:#8caaee;font-weight:bold">checked&lt;/span> &lt;span style="color:#99d1db;font-weight:bold">+&lt;/span> &lt;span style="color:#ca9ee6">label&lt;/span> .&lt;span style="color:#e5c890">container&lt;/span> { 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">display&lt;/span>: &lt;span style="color:#ef9f76">inherit&lt;/span>; 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Nuestro input con el id de toggle nunca se mostrará para que no tengamos la checkbox presente en nuestra página, lo que mostraremos y con lo que interactúa el usuario es lo que esté dentro de nuestra div con clase de toggle. Una vez que le den click a nuestro toggle el input tendrá el valor de checked y con &lt;code>#toggle:checked+label&lt;/code> afectamos el estilo de nuestro &lt;code>&amp;lt;label&amp;gt;&lt;/code> para obtener un resultado como el siguiente&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/dropdowns-toggle-css-1.gif" alt="Demo 1">&lt;/p>
&lt;p>Y con un poco más de estilo (cortesía de Thulio Philipe) podemos tener resultados como este&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/dropdowns-toggle-css-2.gif" alt="Demo 2">&lt;/p>
&lt;p>O como los ejemplos que tenemos dentro de Build It&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/dropdowns-toggle-css-3.gif" alt="Demo 3">&lt;/p>
&lt;p>Un pequeño popover que siempre está presente, dando información vital al usuario&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/dropdowns-toggle-css-4.gif" alt="Demo 4">&lt;/p>
&lt;p>O un menú de filtros que puede ser mostrado con facilidad.&lt;/p>
&lt;p>Como podemos ver, el CSS moderno nos permite hacer páginas interactivas sin necesidad de hacer un script para ello; dándonos una nueva solución a un problema con infinidad de maneras de resolverlo, por lo que habrá que considerar las necesidades del proyecto y que es lo que más conviene.&lt;/p>
&lt;p>Finalmente les dejo &lt;a href="https://github.com/LinkSake/toggle-dropdown-css">un repositorio&lt;/a> con un par de ejemplos vistos en este artículo para referencia futura y los invito a ver &lt;a href="https://www.joinbuildit.com/early_access/client">la plataforma&lt;/a> y en especial &lt;a href="https://www.joinbuildit.com/u/luis-ortega-160">mi perfil&lt;/a>, donde podremos conectar para proyectos futuros.&lt;/p></description></item><item><title>Docker + Rails: Una solución para tus dolores de cabeza</title><link>https://luisangel.me/es/post/2021/09/02/docker-y-rails/</link><pubDate>Thu, 02 Sep 2021 15:15:49 -0500</pubDate><author>hey@luisangel.me (Luis Angel Ortega)</author><guid>https://luisangel.me/es/post/2021/09/02/docker-y-rails/</guid><description>&lt;p>¿Has llegado a pasar una semana solamente tratando de correr el proyecto al que te acabas de unir? ¿O tu aplicación no corre en producción como corría en local?&lt;br>
Hay una multitud de factores que pueden contribuir esto, por ello &lt;a href="https://www.docker.com/">Docker&lt;/a> nos ofrece una solución con la cual podemos tener un mayor control sobre estas variables a través de las computadoras que sean necesarias.&lt;/p>
&lt;p>Dicho esto, en este articulo veremos como falicitarnos la vida al tener toda nuestra aplicación de Ruby on Rails corriendo sobre Docker; incluidas las bases de datos que sean necesarias.&lt;/p>
&lt;h2 id="prerequisitos">Prerequisitos&lt;/h2>
&lt;p>Para poder seguir esta guía necesitaras tener &lt;a href="https://docs.docker.com/get-docker/">Docker instalado&lt;/a> así como un proyecto el cual quieras &lt;em>dockerizar&lt;/em>, si solamente quieres prácticar puedes usar &lt;a href="https://github.com/LinkSake/docker-rails">este proyecto de ejemplo&lt;/a> el cual necesita una conexión a &lt;a href="https://es.wikipedia.org/wiki/PostgreSQL">Postgres&lt;/a> y a &lt;a href="https://es.wikipedia.org/wiki/Redis">Redis&lt;/a> para funcionar.&lt;/p>
&lt;p>¿Eres impaciente? ¡Puedes clonar &lt;a href="https://github.com/LinkSake/docker-rails/tree/docker">esta rama&lt;/a> del proyecto donde ya se encuentran los archivos necesarios para correr el projecto dentro de Docker!&lt;/p>
&lt;h2 id="primero-viene-el-dockerfile">Primero viene el Dockerfile&lt;/h2>
&lt;p>Lo primero que haremos será hacer una &lt;a href="https://docs.docker.com/get-started/overview/#docker-objects">imagen&lt;/a> personalizada para nuestro proyecto, así que crearemos un archivo en la raíz del mismo llamado &lt;code>Dockerfile&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>touch Dockerfile
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>La primer linea de nuestro archivo definirá la imagen de la cual nos basaremos, en este caso será la &lt;a href="https://hub.docker.com/_/ruby">imagen oficial de Ruby&lt;/a>, pero usaremos la versión de &lt;a href="https://es.wikipedia.org/wiki/Alpine_Linux">Alpine&lt;/a> para tener una imagen más ligera como resultado.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Dockerfile" data-lang="Dockerfile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">FROM&lt;/span>&lt;span style="color:#a6d189"> ruby:3.0.1-alpine&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>⚠️ Asegurate que la version de Ruby (ruby:X.X.X-alpine) sea la misma que en tu proyecto, o tendrás errores a la hora de tratar de construir la imagen. Puedes encontrar la versión que usa tu proyecto en tu Gemfile.&lt;/p>
&lt;/blockquote>
&lt;p>Después sigue la parte más dificil de este Dockerfile, instalar la dependendencias necesarias para que funcione el proyecto; las que se muestran aquí son las que funcionan para nuestro &lt;a href="https://github.com/LinkSake/docker-rails">proyecto de ejemplo&lt;/a>, que incluyen las necesarias para realizar una conexión con Postgres, pero tendrás que descubrir cuales son necesarias para tu proyecto.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Dockerfile" data-lang="Dockerfile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">FROM&lt;/span>&lt;span style="color:#a6d189"> ruby:3.0.1-alpine&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">RUN&lt;/span> apk add --update --no-cache --virtual run-dependencies &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>build-base &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>postgresql-client &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>postgresql-dev &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>yarn &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>git &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>tzdata &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>libpq &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">&amp;amp;&amp;amp;&lt;/span> rm -rf /var/cache/apk/*&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Puedes esperar a construir la imagen (&lt;code>docker build .&lt;/code>) para revisar el error que imprima Docker, con eso podrás ir averiguando que depenencias hacen falta 😉&lt;/p>
&lt;/blockquote>
&lt;p>La última linea (&lt;code>rm -rf /var/cache/apk/*&lt;/code>) borra los paquetes de las dependencias que acabamos de instalar, esto ahorrará espacio en la imagen.&lt;/p>
&lt;p>Lo siguiente que debemos de realizar es crear un directorio dentro del contenedor donde podamos copiar el código de nuestra aplicación para su ejecución, eso lo haremos con el siguente comando dentro de nuestro Dockerfile.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Dockerfile" data-lang="Dockerfile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">FROM&lt;/span>&lt;span style="color:#a6d189"> ruby:3.0.1-alpine&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">RUN&lt;/span> apk add --update --no-cache --virtual run-dependencies &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>build-base &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>postgresql-client &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>postgresql-dev &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>yarn &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>git &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>tzdata &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>libpq &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">&amp;amp;&amp;amp;&lt;/span> rm -rf /var/cache/apk/*&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">WORKDIR&lt;/span>&lt;span style="color:#a6d189"> /docker-rails&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>¡Recuerda cambiar el &lt;code>docker-rails&lt;/code> por el nombre de tu proyecto!&lt;/p>
&lt;/blockquote>
&lt;p>Así como le dimos un hogar a tu proyecto dentro del contenedor que crearemos, las gemas del mismo necesitan una carpeta también. Por ello, le informaremos a &lt;a href="https://bundler.io/es/">bundler&lt;/a> donde colocarlas a través de una variable de ambiente.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Dockerfile" data-lang="Dockerfile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">FROM&lt;/span>&lt;span style="color:#a6d189"> ruby:3.0.1-alpine&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">RUN&lt;/span> apk add --update --no-cache --virtual run-dependencies &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>build-base &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>postgresql-client &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>postgresql-dev &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>yarn &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>git &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>tzdata &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>libpq &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">&amp;amp;&amp;amp;&lt;/span> rm -rf /var/cache/apk/*&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">WORKDIR&lt;/span>&lt;span style="color:#a6d189"> /docker-rails&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">ENV&lt;/span> BUNDLE_PATH /gems&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Y aunque ya instalamos las dependencias necesarias para correr Rails dentro del contenedor, tu proyecto necesitará algunas gemas y algunos paquetes de JavaScript para funcionar de manera correcta, vamos a encargarnos de eso de la siguiente manera.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Dockerfile" data-lang="Dockerfile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">FROM&lt;/span>&lt;span style="color:#a6d189"> ruby:3.0.1-alpine&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">RUN&lt;/span> apk add --update --no-cache --virtual run-dependencies &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>build-base &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>postgresql-client &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>postgresql-dev &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>yarn &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>git &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>tzdata &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>libpq &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">&amp;amp;&amp;amp;&lt;/span> rm -rf /var/cache/apk/*&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">WORKDIR&lt;/span>&lt;span style="color:#a6d189"> /docker-rails&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">ENV&lt;/span> BUNDLE_PATH /gems&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">COPY&lt;/span> package.json yarn.lock /docker-rails/&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">RUN&lt;/span> yarn install&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">COPY&lt;/span> Gemfile Gemfile.lock /docker-rails/&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">RUN&lt;/span> bundle install&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Ahora que ya tenemos todo lo necesario para que funcione tu proyecto, vamos a copiar el código al contenedor dentro de la que carpeta que creamos con el comando &lt;code>WORKDIR&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Dockerfile" data-lang="Dockerfile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">FROM&lt;/span>&lt;span style="color:#a6d189"> ruby:3.0.1-alpine&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">RUN&lt;/span> apk add --update --no-cache --virtual run-dependencies &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>build-base &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>postgresql-client &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>postgresql-dev &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>yarn &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>git &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>tzdata &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>libpq &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">&amp;amp;&amp;amp;&lt;/span> rm -rf /var/cache/apk/*&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">WORKDIR&lt;/span>&lt;span style="color:#a6d189"> /docker-rails&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">ENV&lt;/span> BUNDLE_PATH /gems&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">COPY&lt;/span> package.json yarn.lock /docker-rails/&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">RUN&lt;/span> yarn install&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">COPY&lt;/span> Gemfile Gemfile.lock /docker-rails/&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">RUN&lt;/span> bundle install&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">COPY&lt;/span> . /docker-rails/&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>¿Por qué copiamos primero los manifiestos (package.json, Gemfile, etc.) y después el resto del proyecto? Esto nos evita tener que reinstalar las dependencias (dado a que se quedan en caché) después de cambiar el código base y reconstruir la imagen; de esta manera solo cuando cambien los manifiestos se volverá a correr sus comandos de instalación.&lt;/p>
&lt;/blockquote>
&lt;p>Finalmente le diremos a Docker que comando correr cuando iniciemos nuestro contenedor (&lt;code>rails&lt;/code>), así como los argumentos de este (&lt;code>s -b 0.0.0.0&lt;/code>) y que puerto exponer para que nosotros podamos accesar a nuestra aplicación.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Dockerfile" data-lang="Dockerfile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">FROM&lt;/span>&lt;span style="color:#a6d189"> ruby:3.0.1-alpine&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">RUN&lt;/span> apk add --update --no-cache --virtual run-dependencies &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>build-base &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>postgresql-client &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>postgresql-dev &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>yarn &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>git &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>tzdata &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>libpq &lt;span style="color:#8caaee">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8caaee">&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">&amp;amp;&amp;amp;&lt;/span> rm -rf /var/cache/apk/*&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">WORKDIR&lt;/span>&lt;span style="color:#a6d189"> /docker-rails&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">ENV&lt;/span> BUNDLE_PATH /gems&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">COPY&lt;/span> package.json yarn.lock /docker-rails/&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">RUN&lt;/span> yarn install&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">COPY&lt;/span> Gemfile Gemfile.lock /docker-rails/&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">RUN&lt;/span> bundle install&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">COPY&lt;/span> . /docker-rails/&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">ENTRYPOINT&lt;/span> [&lt;span style="color:#a6d189">&amp;#34;bin/rails&amp;#34;&lt;/span>]&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">CMD&lt;/span> [&lt;span style="color:#a6d189">&amp;#34;s&amp;#34;&lt;/span>, &lt;span style="color:#a6d189">&amp;#34;-b&amp;#34;&lt;/span>, &lt;span style="color:#a6d189">&amp;#34;0.0.0.0&amp;#34;&lt;/span>]&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e78284">&lt;/span>&lt;span style="color:#ca9ee6">EXPOSE&lt;/span>&lt;span style="color:#a6d189"> 3000&lt;/span>&lt;span style="color:#e78284">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>El puerto default sobre el que Rails corre es el 3000, pero si has designado otro puerto dentro de tu aplicación asegurarte de exponerlo de manera correcta.&lt;/p>
&lt;/blockquote>
&lt;p>Y con esto tenemos listo nuestro Dockerfile, aunque estamos lejos de tener nuestra aplicación lista. Si construyeramos nuestra imagen con &lt;code>docker build .&lt;/code> y trataramos de correrla con &lt;code>docker start docker-rails&lt;/code> nos encontraríamos con un error, ya que Rails no encuentra las bases de datos que necesita para iniciar de manera correcta; pero pronto nos encargaremos de ello.&lt;/p>
&lt;h2 id="luego-el-docker-composeyml">Luego el docker-compose.yml&lt;/h2>
&lt;p>Para poder coordinar todos los servicios que necesitamos para el correcto funcionamiento de nuestra aplicación (en este caso 2 bases de datos: Posgres y Redis) usaremos &lt;a href="https://docs.docker.com/compose/">docker-compose&lt;/a>, esta útilidad de Docker nos ayudará a crear multimples contenedores de diferentes imagenes, &lt;a href="https://docs.docker.com/compose/networking/">conectarlos&lt;/a>, darles &lt;a href="https://docs.docker.com/compose/environment-variables/">variables de ambiente&lt;/a> e incluso &lt;a href="https://docs.docker.com/storage/volumes/">volumenes&lt;/a>.&lt;/p>
&lt;p>Empezaremos creando un archivo llamado &lt;code>docker-compose.yml&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>touch docker-compose.yml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Y en su primera linea especificaremos que &lt;a href="https://docs.docker.com/compose/compose-file/#compose-and-docker-compatibility-matrix">versión&lt;/a> de la herramienta queremos usar, en este caso usaremos la más reciente a la redacción de este articulo.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">version&lt;/span>: &lt;span style="color:#a6d189">&amp;#39;3.8&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Después indicaremos los servicios que queremos que corra docker-compose, esto lo haremos dentro de la etiqueta &lt;code>services&lt;/code>. A cada servicio le daremos un nombre el cual será importante cuando estemos configurando nuestra imagen así que asegurate de nombrarlo de una manera que haga sentido para ti. Vamos como primer ejemplo servicio de Posgres, al cual llamaremos &lt;em>db&lt;/em>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">version&lt;/span>: &lt;span style="color:#a6d189">&amp;#39;3.8&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">services&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">db&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">image&lt;/span>: postgres:latest
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">container_name&lt;/span>: docker-rails-db
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">environment&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_DB=docker-rails-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_PASSWORD=password
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ef9f76">5432&lt;/span>:&lt;span style="color:#ef9f76">5432&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">volumes&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#a6d189">&amp;#39;dbdata:/var/lib/postgresql/data&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Los archivos YAML son sensibles a la identación, así que asegurate de tener todo en orden y andidado de forma correcta.&lt;/p>
&lt;/blockquote>
&lt;p>La etiqueta &lt;code>db&lt;/code> es el nombre que le dimos al servicio y dentro de la cual especificaremos toda la configuración del mismo.&lt;/p>
&lt;p>Lo primero con lo que nos encontramos es &lt;code>image&lt;/code> que tal como su nombre lo indica es el nombre de la imagen que queremos usar para ese servicio, en este caso es la imagen oficial de Posgres en su última versión (puedes especificar una versión remplazando el &lt;code>latest&lt;/code> por alguna otra versión válida).&lt;/p>
&lt;p>Después nos encontramos con &lt;code>container_name&lt;/code>, que también es autodescriptivo y el cual vendra útil a la hora de checar nuestros contendores con &lt;code>docker ps&lt;/code>.&lt;/p>
&lt;p>&lt;code>enviroment&lt;/code> se refiere a las variables de ambiente, y si nos referimos a la documentación de la imagen de &lt;a href="https://hub.docker.com/_/postgres">Docker de Posgres&lt;/a> podemos ver que la única variable obligatoria es &lt;code>POSTGRES_PASSWORD&lt;/code> pero nosotros también definiremos &lt;code>POSTGRES_DB&lt;/code> para darle un nombre personalizado a la base de datos que crea la imagen por defecto.&lt;/p>
&lt;blockquote>
&lt;p>⚠️ ¡Asegurate de elegir una contraseña segura para la base de datos!&lt;/p>
&lt;/blockquote>
&lt;p>&lt;code>ports&lt;/code> son los puertos que necesitaremos pasar de dentro del contenedor a nuestra maquina, los indicados en el archivo son los que por defecto usa Posgres.&lt;/p>
&lt;p>Finalmente los &lt;code>volumes&lt;/code> son la infomación persistente que necesitaremos para no correr las migraciones cada vez que encendamos el contenedor, esto porque Docker borra todos los datos una vez que damos de baja la información, si quieres aprender más sobre este tema te recomiendo &lt;a href="https://docs.docker.com/storage/volumes/">esta&lt;/a> sección de la documentación.&lt;/p>
&lt;p>Ahora, el siguiente servicio es el de Redis pero no ahondaremos mucho en el pues cuenta solo con un par de etiquetas las cuales ya hemos revisado, para más información puedes visitar &lt;a href="https://hub.docker.com/_/redis">la imagen oficial.&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">version&lt;/span>: &lt;span style="color:#a6d189">&amp;#39;3.8&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">services&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">db&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">image&lt;/span>: postgres:latest
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">container_name&lt;/span>: docker-rails-db
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">environment&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_DB=docker-rails-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_PASSWORD=password
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ef9f76">5432&lt;/span>:&lt;span style="color:#ef9f76">5432&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">volumes&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#a6d189">&amp;#39;dbdata:/var/lib/postgresql/data&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">redis&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">image&lt;/span>: redis:latest
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">container_name&lt;/span>: docker-rails-redis
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ef9f76">6379&lt;/span>:&lt;span style="color:#ef9f76">6379&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Nuestro último servicio lo llamaremos &lt;code>web&lt;/code> y será la imagen que hemos construido con nuestro &lt;code>Dockerfile&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">version&lt;/span>: &lt;span style="color:#a6d189">&amp;#39;3.8&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">services&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">db&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">image&lt;/span>: postgres:latest
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">container_name&lt;/span>: docker-rails-db
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">environment&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_DB=docker-rails-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_PASSWORD=password
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ef9f76">5432&lt;/span>:&lt;span style="color:#ef9f76">5432&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">volumes&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#a6d189">&amp;#39;dbdata:/var/lib/postgresql/data&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">redis&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">image&lt;/span>: redis:latest
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">container_name&lt;/span>: docker-rails-redis
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ef9f76">6379&lt;/span>:&lt;span style="color:#ef9f76">6379&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">web&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">build&lt;/span>: .
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">image&lt;/span>: docker-rails
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">container_name&lt;/span>: docker-rails-web
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ef9f76">3000&lt;/span>:&lt;span style="color:#ef9f76">3000&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">depends_on&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - db
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - redis
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">environment&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_HOST=db
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_USER=postgres
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_PASSWORD=password
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - REDIS_URL=redis://redis:6379
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>La primer etiqueta nueva con la que nos topamos es &lt;code>build&lt;/code>, la cual indica el directorio donde se encuentra nuestro Dockerfile; dado a que nuestro Dockerfile está en la raíz solamente pondremos &lt;code>.&lt;/code>; si tu Dockerfile no está en la raíz o tiene otro nombre es recomendable que leas &lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#build">esta&lt;/a> sección de la documentación para asegurarte que Compose lo encuentre.&lt;/p>
&lt;p>La etiqueta &lt;code>image&lt;/code> en este caso servirá para nombrar la imagen que construirá Compose, ya que al estar presente &lt;code>build&lt;/code> no irá al repositorio a buscar una imagen preconstruida.&lt;/p>
&lt;p>Por último, la etiqueta &lt;code>depends_on&lt;/code> informará a Compose que no se debe de tratar de iniciar el contenedor hasta que estén creados los servicios &lt;code>db&lt;/code> y &lt;code>redis&lt;/code>, así como los conectará de manera interna para que nosotros podamos accesar a ellos mediante un URL (como se puede observar en la variable de ambiente de Redis) o por sus respectivas credenciales (como es el caso de Postgres), si quieres aprender como Docker maneja eso puedes leer sobre &lt;a href="https://docs.docker.com/compose/networking/">Docker Network&lt;/a>.&lt;/p>
&lt;p>Ahora que ya terminamos con los servicios, lo unico que debemos es listar los volumenes que usaremos y a los cuales &lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#volumes">nombramos&lt;/a> de la siguiente manera.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">version&lt;/span>: &lt;span style="color:#a6d189">&amp;#39;3.8&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">services&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">db&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">image&lt;/span>: postgres:latest
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">container_name&lt;/span>: docker-rails-db
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">environment&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_DB=docker-rails-dev
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_PASSWORD=password
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ef9f76">5432&lt;/span>:&lt;span style="color:#ef9f76">5432&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">volumes&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#a6d189">&amp;#39;dbdata:/var/lib/postgresql/data&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">redis&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">image&lt;/span>: redis:latest
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">container_name&lt;/span>: docker-rails-redis
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ef9f76">6379&lt;/span>:&lt;span style="color:#ef9f76">6379&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">web&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">build&lt;/span>: .
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">image&lt;/span>: docker-rails
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">container_name&lt;/span>: docker-rails-web
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ef9f76">3000&lt;/span>:&lt;span style="color:#ef9f76">3000&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">depends_on&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - db
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - redis
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">environment&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_HOST=db
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_USER=postgres
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - POSTGRES_PASSWORD=password
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - REDIS_URL=redis://redis:6379
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">volumes&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - .:/app
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">volumes&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">dbdata&lt;/span>:
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>¡Y listo! Nuestro &lt;code>docker-compose.yml&lt;/code> está listo, ahora solo falta un paso para empezar a crear nuestra aplicación contenida en Docker.&lt;/p>
&lt;h2 id="ojos-que-no-ven-dockerignore-que-no-siente">Ojos que no ven, .dockerignore que no siente&lt;/h2>
&lt;p>Muchas veces no queremos que ciertos archivos estén en nuestra imagen de Docker pues estos no son necesarios para su contrucción (o se generan en la misma) y solo terminan haciendo el proyecto más grande de lo que necesita ser, como puede ser el caso de los &lt;code>node_modules&lt;/code> y la carpeta &lt;code>.git&lt;/code>.&lt;br>
Para ahorrarnos este espacio crearemos un archivo llamado &lt;code>.dockerignore&lt;/code> en la raíz de nuestro proyecto y añadiremos estas dos carpetas:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#99d1db">echo&lt;/span> &lt;span style="color:#a6d189">&amp;#34;.git \n node_modules&amp;#34;&lt;/span> &amp;gt;&amp;gt; .dockerignore
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Para más información sobre lo que puede contenener un archivo &lt;code>.dockerignore&lt;/code> puedes consultar la &lt;a href="https://docs.docker.com/engine/reference/builder/#dockerignore-file">documentación oficial de Docker&lt;/a>&lt;/p>
&lt;h2 id="unas-bases-de-datos-para-llevar">Unas bases de datos para llevar&lt;/h2>
&lt;p>Antes de correr el proyecto será necesario crear la base de datos que Rails espera, y crearla es tan sencillo que se puede hacer en un solo comando.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>docker-compose run web db:create
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Este comando le dice a Docker que use la imagen (que construirá) para correr un comando, en este caso &lt;code>db:create&lt;/code>. Docker, con lo especificado en el &lt;code>docker-compose.yml&lt;/code> sabe que como &lt;em>web&lt;/em> depende de &lt;em>db&lt;/em> tendrá que correr primero la instancia de Postgres, por lo que la base de datos se creará en este contenedor.&lt;/p>
&lt;blockquote>
&lt;p>¿Por qué solamente &lt;code>db:create&lt;/code> y no &lt;code>rails db:create&lt;/code> o &lt;code>rake db:create&lt;/code>? En nuestro &lt;code>Dockerfile&lt;/code> dimos como punto de entrada el comando &lt;code>rails&lt;/code>, por ello solo es necesario pasar los parametros. Si quisieramos efectuar otro comando dentro del contenedor esto tendría que ser a través de &lt;a href="https://docs.docker.com/engine/reference/commandline/exec/">docker exec&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;h2 id="nuestra-aplicación-en-un-contenedor">Nuestra aplicación en un contenedor&lt;/h2>
&lt;p>Con la base de datos creada, solo queda un comando que corra los contenedores en &lt;a href="https://docs.docker.com/compose/reference/up/">modo separado&lt;/a> y podremos ver el fruto de nuestro trabajo.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>docker-compose up -d
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>¡Y listo! Ya podrás accesar a traves de tu navegador a &lt;a href="http://localhost:3000/">localhost:3000&lt;/a> y ver la página de bienvenida de Rails.&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/docker-rails-1.png" alt="Welcome to Rails!">&lt;/p>
&lt;h2 id="conclusión">Conclusión&lt;/h2>
&lt;p>Puede que todo este proceso sea algo intimidante al principio, en especial si no sabes Docker, pero su resultado es un ambiente de desarrollo mucho más sencillo para todos los involucrados en el proyecto, pues ahora solo con tener Docker instalado podrán iniciar a programar; sin mencionar los beneficios que esta tecnología puede traer a tu ambiente de producción cuando se combina con Kubernetes o Docker Swarm.&lt;/p>
&lt;p>Espero que te haya sido útil, cualquier cosa puedes &lt;a href="https://luisangel.me/es/about">contactarme&lt;/a> y responderé lo más pronto posible.&lt;/p>
&lt;h2 id="referencias">Referencias&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://docs.docker.com/samples/rails/">Docker Docs&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://gorails.com/episodes/docker-basics-for-gorails">Go Rails&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>¿Home office o no home office? Esa es la cuestión</title><link>https://luisangel.me/es/post/2021/04/20/el-dilema-del-home-office/</link><pubDate>Tue, 20 Apr 2021 15:07:57 -0500</pubDate><author>hey@luisangel.me (Luis Angel Ortega)</author><guid>https://luisangel.me/es/post/2021/04/20/el-dilema-del-home-office/</guid><description>&lt;p>Durante este fin de semana que pasó me encontré a mitad de una plática familiar, en ella salió el tema del &lt;em>home office&lt;/em> a lo que mi padre comentó que no era una práctica buena. &amp;ldquo;No es sano&amp;rdquo;, repitió múltiples veces mientras movía la cabeza de derecha a izquierda en manera de negación.&lt;/p>
&lt;p>Mi primo y yo no estábamos de acuerdo con él, pues los dos (que como dato, ambos trabajamos en el ámbito de TI) hemos percibido beneficios enormes al trabajar desde nuestra casa. Tratamos de explicarle, pero él seguía negándolo con la cabeza y finalmente dejamos así la conversación.&lt;/p>
&lt;p>Pero desde entonces no he podido dejar de pensar en ello ¿Realmente es sano el &lt;em>home office&lt;/em>? ¿Realmente tiene los beneficios que yo promulgo? Después de un par de días de reflexión me encontré que este tema, como todo en la vida, es complicado.&lt;/p>
&lt;p>Ya hemos pasado la marca del 1er año de &lt;a href="https://es.wikipedia.org/wiki/Pandemia_de_COVID-19">pandemia&lt;/a>, y desde mi experiencia y mi privilegio, el &lt;em>home office&lt;/em> ha traído a mi vida un montón de beneficios (aunque aquí solo liste 3).&lt;/p>
&lt;hr>
&lt;h3 id="lo-bueno">Lo bueno&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Oportunidades laborales&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>Esta situación me ha permitido tener un empleo a distancia, cosa que si bien antes se podía, no estoy seguro que a mi como desarrollador &lt;em>junior&lt;/em> me dieran la oportunidad de manera tan sencilla.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Más tiempo para mi&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>Creo que esta es la más obvia, pues sin tener que transportarse (o siquiera bañarme en las mañanas) para ir a una oficina he podido dormir más, pasar más tiempo con mi familia y darme tiempo para mi. He podido aventarme a más actividades, que aunque son dentro de mi casa o con un número limitado de gente, que antes no había podido probar; no sabía cuánto tiempo de mi vida se iba solamente en transporte a otros lugares.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Mayor paz mental&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>Este era el punto al que quería llegar, pues creo que no a todos les ha pasado así, pero para mi (después del golpe inicial del confinamiento) mi salud mental ha mejorado considerablemente. Verán, yo tengo un &lt;a href="https://es.wikipedia.org/wiki/Trastorno_de_ansiedad_generalizada">trastorno de ansiedad generalizada&lt;/a> y hay días que la paso muy muy mal. Esos días, cuando llegué a trabajar en una oficina, los pasaba terrible. El día laboral se me hacía eterno, estoy seguro de que envejecía 4 años por cada día que era así; no me podía concentrar durante esas horas y me sentía horrible al respecto, sentía que no valía la pena mi trabajo y no estaba seguro de lo que hacía ahí. Era un momento en el que ni mi mente ni. mi cuerpo podían escapar de ahí, lo más que podía hacer era ver un par de vídeos de Youtube, hablar con colegas o salir a caminar; pero eso era todo, tus colegas solo pueden hablar un tanto contigo antes de que tengan que volver a sus labores y después de cierto número de caminatas tu jefe te empieza a ver raro (los vídeos de Youtube son infinitos, para bien o para mal).&lt;/p>
&lt;p>Pero en el &lt;em>home office&lt;/em> tengo el privilegio de trabajar desde mi cuarto, donde tengo todas las herramientas que necesito para lidiar con esos malos días, los cuales solo ya no son terribles ¡Pero han bajado en cantidad y frecuencia! Si bien tomó un par de meses en que llegara a una estabilidad en mi rutina y a tener la disciplina de trabajar desde casa, ahora si empiezo a tener un día particularmente terrible, tomaré un rápido baño, saldré al patio y jugaré con mi mascota; y eso funcionará como un &lt;em>reset&lt;/em> a mi cuerpo, donde ya no perdí todo el día tratando de escapar de mi propia mente, en su lugar solamente 20 minutos en recobrar la compostura. En días menos terribles, pero igual difíciles, con parar cada descanso de &lt;a href="https://es.wikipedia.org/wiki/T%C3%A9cnica_Pomodoro">pomodoro&lt;/a> y caminar por la casa o jugar una partida de algo como recompensa por haber terminado una tarea servirá como suficiente incentivo para tener buen ánimo todo el día.&lt;/p>
&lt;hr>
&lt;h3 id="lo-malo">Lo malo&lt;/h3>
&lt;p>Esto no quiere decir que todo haya sido color de rosa, como mencioné, fue un trabajo de un par de meses llegar a este punto. Además yo sé que estoy hablando desde un privilegio enorme, porque no solo tuve la fortuna de tener el equipo para trabajar cómodamente desde casa; pero tuve un lugar donde hacerlo y un entorno tranquilo, cosa que muchas personas no han tenido.&lt;/p>
&lt;p>Aún así, con todo mi privilegio, han un punto grande y un tema importante durante toda la pandemia: la socialización.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Socialización&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>Como &amp;ldquo;adulto&amp;rdquo; que soy, ya estoy empezando a notar algo que había escuchado de gente mayor que yo: cuando eres adulto cuesta hacer amigos. Y es que en mi primer empleo en TI lo mejor que me pude llevar fueron las amistades que hice, pues son gente que hasta la fecha frecuento y con quien hablo a diario; pasaron de ser colegas a ser amigos cercanos. Hablando con ellos me gusta comentarles que realmente esa oficina no era una oficina, pero que realmente estábamos en un &lt;em>reality show&lt;/em> al estilo &lt;a href="https://es.wikipedia.org/wiki/The_Office">&lt;em>The Office&lt;/em>&lt;/a> donde grababan todo lo que pasaba.&lt;/p>
&lt;p>Si bien, en los empleos/prácticas que tuve en durante la pandemia pude conocer a gente increíble, personas que considero mentores, no puedo evitar pensar que tendría una mejor relación con ellos si los pudiera haber visto en persona más seguido. Tampoco puedo negar que es mucho más sencillo conseguir ayuda de alguien si este está sentado enseguida de ti, aunque solamente sirva de &lt;a href="https://es.wikipedia.org/wiki/M%C3%A9todo_de_depuraci%C3%B3n_del_patito_de_goma">patito&lt;/a>.&lt;/p>
&lt;p>En pocas palabras, extraño mucho la calidéz humana que traía trabajar en una oficina y sería mentira si no dijera que me preocupa que pierda la habilidad de hacer amigos si este modelo me esperara por el resto de mi vida.&lt;/p>
&lt;p>Sin embargo, este es solo uno de los problemas que trae el trabajar desde casa; no he tocado cosas tan importantes como que los negocios se ahorran dinero si nosotros no estamos físicamente en una oficina mientras que nosotros gastamos más por el hecho de pagar los insumos que usamos al laborar sin tener un aumento de sueldo que refleje ese ahorro de parte del patrón. Este no era el punto que quería tocar en este escrito, pero no hay que quitar el dedo de ese tema.&lt;/p>
&lt;hr>
&lt;h2 id="lo-que-propongo">Lo que propongo&lt;/h2>
&lt;p>¿Entonces cuál es la solución? ¿Qué sería lo ideal? Desde mi punto de vista, joven e ingenuo, y tomando en cuenta que esta es una solución para mis problemas en específico; yo creo que la solución sería un modelo híbrido, 2 días de oficina presencial y 3 de trabajo en casa. Podría funcionar de manera inversa también, pero en lo personal prefiero la primera opción.&lt;/p>
&lt;p>Esto permitiría tener una dinámica ágil para situaciones como lo serían juntas, planeaciones o algún otro tipo de evento que se beneficie de estar físicamente en una habitación, dejando 3 días de espacio para que el empleado trabaje de una manera cómoda y a su estilo desde su casa. Además, si la oficina ya va a estar abierta algunos días ¿por qué no permitir a los empleados que quieran ir a laborar ahí? Esto podría beneficiar, por ejemplo, a quien no pueda contar con internet bueno en su casa o a quien tenga hijos en casa y no le permitan tener un lugar adecuado para concentrarse.&lt;/p>
&lt;p>En este último ejemplo también funciona al revés, permitiría (si es que las cosas vuelven a algo que se parezca al &lt;em>pasado&lt;/em>) que los padres que trabajan puedan ver más tiempo a sus hijos después de que lleguen de la escuela, incluso permitiendo que todos coman al mismo tiempo, en la misma mesa.&lt;/p>
&lt;hr>
&lt;p>Al final, como muchas de las cosas bellas de la vida, creo que todo se debería dejar al libre albedrío de las personas; que ellos puedan escoger el modelo que mejor les funcione, pues creo que nosotros como humanos somos mucho más que un pedazo de carne capaz de producir dinero para una empresa y el &lt;em>home office&lt;/em> puede ser un apoyo en nuestra búsqueda de sentido y de felicidad.&lt;/p>
&lt;p>Si les interesa más sobre el tema de la vida post-covid, les recomiendo este &lt;a href="https://www.youtube.com/watch?v=6iILrpgbAMY">vídeo&lt;/a> de Ophelia Pastrana.&lt;/p></description></item></channel></rss>