<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Luis Angel Ortega</title>
    <description>The latest articles on DEV Community by Luis Angel Ortega (@linksake).</description>
    <link>https://dev.to/linksake</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F323678%2F593ca43b-a079-4962-908e-a0908c5f9d31.jpg</url>
      <title>DEV Community: Luis Angel Ortega</title>
      <link>https://dev.to/linksake</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/linksake"/>
    <language>en</language>
    <item>
      <title>Dropdowns y Toggles con puro CSS</title>
      <dc:creator>Luis Angel Ortega</dc:creator>
      <pubDate>Mon, 07 Nov 2022 16:30:56 +0000</pubDate>
      <link>https://dev.to/linksake/dropdowns-y-toggles-con-puro-css-5em7</link>
      <guid>https://dev.to/linksake/dropdowns-y-toggles-con-puro-css-5em7</guid>
      <description>&lt;p&gt;Podríamos imaginar las tecnologías de la plataforma en la cual trabajo, &lt;a href="https://www.joinbuildit.com/"&gt;Build It&lt;/a&gt;, 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/"&gt;Stimulus JS&lt;/a&gt;, 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"&gt;Apple&lt;/a&gt; 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&gt;

&lt;h2&gt;
  
  
  Los pilares
&lt;/h2&gt;

&lt;p&gt;Nuestros dos pilares en la vista serán los elementos &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; de tipo checkbox y las etiquetas &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;. Formaremos nuestro esqueleto básico de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input id="toggle" type="checkbox"&amp;gt;&amp;lt;/input&amp;gt;
&amp;lt;label for="toggle"&amp;gt;&amp;lt;/label&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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&gt;&amp;lt;label&amp;gt;&lt;/code&gt; ya que al relacionarlo a través de su propiedad &lt;code&gt;for&lt;/code&gt; también será afectado por el cambio de clases cuando la propiedad checked de nuestro checkbox se encuentre presente. &lt;/p&gt;

&lt;p&gt;Todo nuestro código realmente se encontrará dentro de &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; en dos secciones: container y toggle como se muestra a continuación.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input id="toggle" type="checkbox"&amp;gt;&amp;lt;/input&amp;gt;
&amp;lt;label for="toggle"&amp;gt;
  &amp;lt;div class="toggle"&amp;gt;
    &amp;lt;!-- El elemento con el cual el usuario va a interactuar --&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class="container"&amp;gt;
    &amp;lt;!-- Lo que queremos mostrar--&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/label&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  La magia
&lt;/h2&gt;

&lt;p&gt;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;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#toggle {
  display: none;
}

.container {
  display: none;
}

#toggle:checked + label .container { 
  display: inherit; 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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&gt;#toggle:checked+label&lt;/code&gt; afectamos el estilo de nuestro  para obtener un resultado como el siguiente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bAotnHE3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m369xjqlslttoxf46beb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bAotnHE3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m369xjqlslttoxf46beb.gif" alt="Demo 1" width="138" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Y con un poco más de estilo (cortesía de Thulio Philipe) podemos tener resultados como este&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--16lwmytF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxauc4zl7958lcauxon1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--16lwmytF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxauc4zl7958lcauxon1.gif" alt="Demo 2" width="182" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O como los ejemplos que tenemos dentro de Build It&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gSc6Y6dw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bwke1yv9j4t1kkgopwnc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gSc6Y6dw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bwke1yv9j4t1kkgopwnc.gif" alt="Demo 3" width="600" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Un pequeño popover que siempre está presente, dando información vital al usuario&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8uoeLKLL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eglvsda9dq6v3wr3lqeo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8uoeLKLL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eglvsda9dq6v3wr3lqeo.gif" alt="Demo 4" width="880" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O un menú de filtros que puede ser mostrado con facilidad.&lt;/p&gt;

&lt;p&gt;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&gt;

&lt;p&gt;Finalmente les dejo &lt;a href="https://github.com/LinkSake/toggle-dropdown-css"&gt;un repositorio&lt;/a&gt; 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"&gt;la plataforma&lt;/a&gt; y en especial &lt;a href="https://www.joinbuildit.com/u/luis-ortega-160"&gt;mi perfil&lt;/a&gt;, donde podremos conectar para proyectos futuros.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>español</category>
    </item>
    <item>
      <title>Why should we teach with Open Source Software?</title>
      <dc:creator>Luis Angel Ortega</dc:creator>
      <pubDate>Thu, 25 Nov 2021 17:42:29 +0000</pubDate>
      <link>https://dev.to/linksake/why-should-we-teach-with-open-source-software-1075</link>
      <guid>https://dev.to/linksake/why-should-we-teach-with-open-source-software-1075</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Full article originally available at &lt;a href="https://aviyel.com/post/1429/why-should-we-teach-with-open-source-software"&gt;Aviyel&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your 20s are a time in your life when some of your friends are still in college while others are already in the workforce. This can give you a broad perspective in transitioning from student life to a professional one, and this acquired vision helped me realize that we should be teaching primarily with open source software (OSS).&lt;/p&gt;

&lt;p&gt;To build a career in tech these days, students have to start early as technology is rapidly evolving through innovation. This has become a challenge for the education sector to equip students with basic computer literacy. This situation has arisen because currently, every facet of human life is touched upon by computer technology.&lt;/p&gt;

&lt;p&gt;To equip students with primary computer literacy, schools and colleges have a mandatory policy of giving lectures in basic computer programs at a very early age. These programs include – learning to operate computers or laptops, a basic understanding of &lt;a href="https://www.office.com/"&gt;MS Office&lt;/a&gt;, which includes MS Word, MS Powerpoint, MS Excel etc. Many of these fields have received tremendous responses from the job market, such as graphic designing, online marketing, video editing, etc.&lt;/p&gt;

&lt;p&gt;These skillsets have become an essential part of every curriculum across the world. And since setting up a computer lab for 40 students costs a bomb to educational institutions, these institutions are forced to buy proprietary software, which adds to the recurring bill. This forces some educational institutions to use an illicit version of this software. We should not allow such pedagogy to enter our children’s curriculum.&lt;/p&gt;

&lt;p&gt;An alternate method has to be used to cut down software invoices, i.e., using open-source software for all kinds of learning purposes. First of all, there are almost alternate sources to every type of proprietary software in the market. These open-source software have been built by open-source communities across the globe and provided for free of cost. Not only this, you can even patch your updates and share them with the whole world. This significantly reduces the software invoice for all kinds of learning purposes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;If you’re lucky, your college will give you the tools that the employers want you to learn. This can be from Maya or AutoCAD to the Adobe Suite. The schools teach this tool because they are the standard in the industry; they want you to get familiar with them. Still, not everyone has the same opportunities. These licences are expensive, and if the student needs them at their personal computer, there’s a chance that they either need to buy them or get an illegal copy of them in the most common scenario (especially during the pandemic).&lt;/p&gt;

&lt;p&gt;Piracy is an everyday occurrence in most developing countries simply because it’s cheaper than buying a licence. Even if downloading cracked software can come with serious security risks, people use it to avoid buying software. But piracy should not be the only option. There’s a whole world of OSS that can solve this; why use Maya to learn 3D modelling if you can use &lt;a href="https://www.blender.org/"&gt;Blender&lt;/a&gt;, why bother with the high prices of the Adobe Suite if you can find alternatives like &lt;a href="https://www.gimp.org/"&gt;GIMP&lt;/a&gt;, &lt;a href="https://www.audacityteam.org/download/"&gt;Audacity&lt;/a&gt; and &lt;a href="https://www.openshot.org/"&gt;OpenShot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Skills can be translated from software to software, even if it takes effort to do it; this way, you’re giving them equal access to every one of your students since they’re not only open and accessible but multiplatform. Stop dealing with compatibility problems since everyone has a different cracked version of Maya.&lt;/p&gt;

&lt;p&gt;After school, students could do freelance work without worrying about the limitations of student licences, which help you learn the software but not make money with it. Does a friend need Point-of-Sale Software? Just fire them an instance of &lt;a href="http://floreant.org/"&gt;FloreantPOS&lt;/a&gt; without worrying about licensing.&lt;/p&gt;

&lt;p&gt;The idea is lovely, but most people stop when they encounter the problem of finding said OSS. Proprietary software can be easily found via the app stores, but you’ll often need to know what you’re looking for with OSS, but this is changing. Projects like &lt;a href="https://aviyel.com/post/33/manifesto-aviyel"&gt;Aviyel&lt;/a&gt; function like a hub for the community; you’ll find the software you need, tutorials for it, news and a community to support you if you ever get stuck.&lt;/p&gt;

&lt;p&gt;Working with open-source software sets your skill set at a premium level in the job market as you tend to know more about the functionalities of products and output generated from those products. Employers love the guys who work using open-source projects. Since open-source is free to use for all, even large MNC’s benefit from these tools. There would have been no Facebook, IBM, Amazon without open-source.&lt;/p&gt;

&lt;p&gt;The love for open-source is growing day-in-day-out among big MNC’s due to monetary reasons. They only have to hire a skillful employee and provide them with a laptop, and voila, they can build one of the most intuitive things this world has ever seen. Thus, if educational institutions take the route of educating their pupils from open-source resources issue of unemployability would not arise in the software job market.&lt;/p&gt;

&lt;p&gt;This is because proprietary software has much more finishing than open-source. This leads to a gap of skill between the users. A user of Blender might know a few extra bits about designing than a user bred on Adobe products. This happens because an open-source user has to understand features in-depth, whereas proprietary tools have an excellent finish in the product, making it easier to use. However, open-source is free of cost, whereas proprietary tools might cost a bomb.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parting note
&lt;/h2&gt;

&lt;p&gt;If we want to change the abusive corporate practices of proprietary software companies, we need to do as Michael Jackson once said and “start the change with the man in the mirror”. Change is necessary if we want to give everyone the same opportunities for learning the skills of today and tomorrow. Thankfully with Aviyel, you’ll never walk alone.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>teaching</category>
    </item>
    <item>
      <title>Thinking outside the box: An online resume with Docz</title>
      <dc:creator>Luis Angel Ortega</dc:creator>
      <pubDate>Thu, 21 Oct 2021 16:45:34 +0000</pubDate>
      <link>https://dev.to/linksake/thinking-outside-the-box-an-online-resume-with-docz-1ila</link>
      <guid>https://dev.to/linksake/thinking-outside-the-box-an-online-resume-with-docz-1ila</guid>
      <description>&lt;p&gt;One of the best traits of humankind is its curiosity. It is so human that in honor of it we named a Mars rover "Curiosity" in 2003. &lt;/p&gt;

&lt;p&gt;Talking about curiosity in the developer world, open source projects top the list, since by nature they invite us to experiment, modify and share what else we can do with them. This is why I propose to think a little outside the box with &lt;a href="https://www.docz.site/" rel="noopener noreferrer"&gt;Docz&lt;/a&gt; - a software documentation tool that is completely &lt;a href="https://aviyel.com/post/1146/how-to-start-contributing-to-open-source" rel="noopener noreferrer"&gt;open source&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Index
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is Docz?&lt;/li&gt;
&lt;li&gt;Creating our Docz project&lt;/li&gt;
&lt;li&gt;Adding our information&lt;/li&gt;
&lt;li&gt;Adding a custom component&lt;/li&gt;
&lt;li&gt;Deploy to GitHub Pages&lt;/li&gt;
&lt;li&gt;Parting note&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Docz? &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Docz is a &lt;a href="https://www.gatsbyjs.com/" rel="noopener noreferrer"&gt;Gatsby-based&lt;/a&gt; project that simplifies the process of documenting other projects without worrying about configuration, speed and support.&lt;/p&gt;

&lt;p&gt;It provides a library that allows you to write MDX pages instead of HTML or JSX files, handles the routing and provides plugins for all the other needs that you may have. All of this results on projects anyone can contribute to!&lt;/p&gt;

&lt;p&gt;Is this simplicity and friendliness that makes Docz a great option for more than just docs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating our Docz project &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Before we can jump into Docz, there are some prerequisites that you will need have in order to create the project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm#overview" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://yarnpkg.com/getting-started/install" rel="noopener noreferrer"&gt;Yarn&lt;/a&gt; or &lt;a href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm#overview" rel="noopener noreferrer"&gt;npm&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you have the prerequisites, let’s start by creating a new React app with &lt;code&gt;create-react-app&lt;/code&gt; (CRA)&lt;/p&gt;

&lt;p&gt;Go to your terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-react-app my-resume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don’t have CRA installed, npm will ask you if it’s okay to install &lt;code&gt;create-react-app&lt;/code&gt; type &lt;code&gt;y&lt;/code&gt; to continue and let CRA create the new project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We are using the command &lt;code&gt;npx&lt;/code&gt; instead of &lt;code&gt;npm&lt;/code&gt; since we want to execute a package, not install it to a project. You can read more about it &lt;a href="https://stackoverflow.com/questions/50605219/difference-between-npx-and-npm" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now lets move to the directory of our project and install Docz.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;my-resume
yarn add docz &lt;span class="c"&gt;# or npm install docz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then let’s remove everything that CRA created for us inside the &lt;code&gt;src&lt;/code&gt; folder, since we don’t need it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm &lt;/span&gt;src/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, it is a good idea to add to the .gitignore the .docz folder since we only needed for development.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .gitignore

# Docz generated files
.docz/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s go and create a file named &lt;code&gt;index.mdx&lt;/code&gt; and a &lt;em&gt;hello world&lt;/em&gt; header in the following way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- src/index.mdx --&amp;gt;

---
name: Hello World
route: /
---

# Hello world from Docz!

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it’s time to run our development server to see what we have just created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn docz dev &lt;span class="c"&gt;# or npm run docz dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you get an error &lt;a href="https://github.com/gatsbyjs/gatsby/issues/19922" rel="noopener noreferrer"&gt;ERROR #98123&lt;/a&gt; while trying to run the development server, just delete your &lt;code&gt;yarn.lock&lt;/code&gt; or &lt;code&gt;package-json.lock&lt;/code&gt; and the &lt;code&gt;node_modules&lt;/code&gt; folder and install the dependencies again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Et voila!&lt;/em&gt; We have successfully created our Docz project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F98pqzm87ku49wfk6rt3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F98pqzm87ku49wfk6rt3n.png" alt="Hello from Docz"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Now is a good time to commit your files!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Your time to shine &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Before we start adding more pages, let’s create a configuration file named &lt;code&gt;doczrc.js&lt;/code&gt; on the root of our project. This will help us to set some meta tags easily, but it manages &lt;a href="https://www.docz.site/docs/project-configuration" rel="noopener noreferrer"&gt;all the configuration&lt;/a&gt; of our project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// doczrc.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Luis Angel Ortega&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, I'm Luis Angel and this is my resume made with Docz!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;ignore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;README.md&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The title key will set the suffix for our &lt;a href="https://www.w3schools.com/tags/tag_title.asp" rel="noopener noreferrer"&gt;title tag&lt;/a&gt; and it will change the text on the top left corner of our project, since it’s an online resume I recommend using your name in this field.&lt;/p&gt;

&lt;p&gt;Then, the description key that we added will modify the &lt;a href="https://moz.com/learn/seo/meta-description" rel="noopener noreferrer"&gt;meta description tag&lt;/a&gt; on our webpage to display it when it’s looked up or shared online.&lt;/p&gt;

&lt;p&gt;The last key will tell Docz to ignore some files and don’t display them on the webpage, as is in this case with the README file.&lt;/p&gt;

&lt;p&gt;Now let’s add more pages! I’ll add a contact page with my socials and resume one in the following way&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- src/contact.mdx --&amp;gt;

---
name: Contact
route: /contact
---

# Contact me! 🗣

---

Let's talk! You can find me on these platforms:

- ✉️ [Email](mailto:hey@luisangelme)
- 🤝 [LinkedIn](https://www.linkedin.com/in/luisangel-ortega)
- 🐙 [GitHub](https://github.com/LinkSake)
- 🐦 [Twitter](https://twitter.com/LinkSake)
- 🌐 [Website](https://luisangel.me)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- src/resume.mdx --&amp;gt;

---
name: Resume
route: /resume
---

# Resume 💼

---

## Work Experience

&amp;lt;details&amp;gt;
  &amp;lt;summary&amp;gt;Software Developer. &amp;lt;a href='growthconstant.co' target='_blank'&amp;gt;Growth Constant&amp;lt;/a&amp;gt;, (Mar. 2021 - Currently)&amp;lt;/summary&amp;gt;
  &amp;lt;div style={{marginLeft: '1em'}}&amp;gt;
    &amp;lt;li&amp;gt; Full stack developer (Ruby on Rails) and copywriter for the first project of the start-up: &amp;lt;a href='virtualdash.co' target='_blank'&amp;gt;Virtual Dash &amp;lt;/a&amp;gt;.&amp;lt;/li&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/details&amp;gt;

&amp;lt;details&amp;gt;
  &amp;lt;summary&amp;gt;Backend Developer Intern. &amp;lt;a href='facturasamurai.com' target='_blank'&amp;gt;Factura Samurai&amp;lt;/a&amp;gt;, (Aug. - Dec. 2020)&amp;lt;/summary&amp;gt;
  &amp;lt;div style={{marginLeft: '1em'}}&amp;gt;
    &amp;lt;li&amp;gt; Implemented the user authentication on the Elixir API. &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt; Learn and developed serverless services (Cloudflare Workers) with TypeScript. &amp;lt;/li&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/details&amp;gt;

&amp;lt;details&amp;gt;
  &amp;lt;summary&amp;gt;Full Stack Web Developer. &amp;lt;a href='biobot.farm' target='_blank'&amp;gt;biobot.farm&amp;lt;/a&amp;gt;, (Aug. 2019 - Jun. 2020)&amp;lt;/summary&amp;gt;
  &amp;lt;div style={{marginLeft: '1em'}}&amp;gt;
    &amp;lt;li&amp;gt; Successfully launched a new service (web application) that was developed form scratch while learning React. &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt; Documented the web application and taught a colleague to mantener said application. &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt; Improved speed, functionality and readability of a Python API and micro-services. &amp;lt;/li&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/details&amp;gt;

## Education

&amp;lt;details&amp;gt;
  &amp;lt;summary&amp;gt;Bachelor's Degree in Information Technologies and Telecomunications. &amp;lt;a href='ulsachihuahua.edu.mx/site' target='_blank'&amp;gt;Universidad La Salle Chihuahua&amp;lt;/a&amp;gt;, (Aug. 2016 - Dic. 2020)&amp;lt;/summary&amp;gt;
  &amp;lt;div style={{marginLeft: '1em'}}&amp;gt;
    &amp;lt;li&amp;gt; Degree on engineering on information and telecommunication with specialization on mobile development. &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt; Academic exchange semester at La Salle Ramon Llull University (Barcelona, Spain) from January to June 2019 with the Computer Engineering degree. &amp;lt;/li&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/details&amp;gt;

## Skills

&amp;lt;details&amp;gt;
  &amp;lt;summary&amp;gt; Languages &amp;lt;/summary&amp;gt;
  &amp;lt;div style={{marginLeft: '1em'}}&amp;gt;
    &amp;lt;li&amp;gt;Spanish: Native&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;English: Advanced (TOFEL ITP: 627)&amp;lt;/li&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/details&amp;gt;
&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt; Tech &amp;lt;/summary&amp;gt;
  &amp;lt;div style={{marginLeft: '1em'}}&amp;gt;
    &amp;lt;li&amp;gt; &amp;lt;b&amp;gt; Professional level &amp;lt;/b&amp;gt; &amp;lt;/li&amp;gt;
    &amp;lt;div div style={{marginLeft: '1em'}}&amp;gt;
      &amp;lt;li&amp;gt;JavaScript (Node, React, Next)&amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;Ruby (Rails)&amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;SQL (MySQL, PostgreSQL)&amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;Version manager (Git)&amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;HTML &amp;amp; CSS&amp;lt;/li&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div style={{marginLeft: '1em'}}&amp;gt;
    &amp;lt;li&amp;gt; &amp;lt;b&amp;gt; Novice Level &amp;lt;/b&amp;gt; &amp;lt;/li&amp;gt;
    &amp;lt;div style={{marginLeft: '1em'}}&amp;gt;
      &amp;lt;li&amp;gt;Python (Bottle)&amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;Docker&amp;lt;/li&amp;gt;
      &amp;lt;li&amp;gt;UNIX&amp;lt;/li&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/details&amp;gt;

## Achivements

- Essential part of the winning team of the following hackathons:
  - Ideacon (2018)
  - Reset (2018)
- Essential part of the 2nd place team of the Blockchain Mobility Hackathon 2019 in Barcelona, Spain.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, using MDX means that we can use &lt;a href="https://www.markdownguide.org/" rel="noopener noreferrer"&gt;Markdown syntax&lt;/a&gt; and &lt;a href="https://es.reactjs.org/docs/introducing-jsx.html" rel="noopener noreferrer"&gt;JSX&lt;/a&gt; in the same document, giving a lot of flexibility and customization to our Docz projects.&lt;/p&gt;

&lt;p&gt;At the end they will look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd84njghystqarrvla88u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd84njghystqarrvla88u.png" alt="Contact page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3xxbfkz047n2dodvcoh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3xxbfkz047n2dodvcoh.png" alt="Resume page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Spice it! Adding a custom component &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Now let’s focus on our &lt;code&gt;index.mdx&lt;/code&gt; file. Let’s change it’s title to "About me"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- src/index.mdx --&amp;gt;
---
name: About me
route: /
---

# Hello world from Docz!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then, create a &lt;code&gt;components&lt;/code&gt; folder inside of the &lt;code&gt;src&lt;/code&gt; directory. There create a &lt;code&gt;welcome.jsx&lt;/code&gt; component, this will replace our Markdown heading to make the root page more interesting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/welcome.jsx&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Welcome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;textContainer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;imgContainer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;paddingTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1em&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;40%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;50%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContainer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imgContainer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Welcome&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I just made a quick component that takes a title, some text and displays it all centered and the image as a circle, but you can make your creativity go wild on this one!&lt;/p&gt;

&lt;p&gt;Next, let’s change index.mdx to import our component and use it to give a warm welcome to all the visitors on our webpage, here is how it looks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgeyjq72lwzq24ytmvaaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgeyjq72lwzq24ytmvaaz.png" alt="Welcome page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  It's alive! Time to deploy &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;ow that we have our Docz project it’s time to build it and deploy it to GitHub Pages (since we already have the repository there).&lt;/p&gt;

&lt;p&gt;First we need to configure some things, go to your doczrc.js file and add a dest key with the value “/docs” and a base key the name of your repo as it’s value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// doczrc.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Luis Angel Ortega&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, I'm Luis Angel and this is my resume made with Docz!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;ignore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;README.md&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/docs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;docz-resume&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first key is telling Docz to build the project into the docs directory, we’re doing this since GitHub Pages expects the static files to be on the root or docs directories.&lt;/p&gt;

&lt;p&gt;The base key is changing the base folder to match the name of the repo in order to make the public files and links to work in GitHub Pages.&lt;/p&gt;

&lt;p&gt;Once we have everything correctly configured, we need to build the project with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn docz build &lt;span class="c"&gt;# or npm run docz build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When it is done, you will see a docs folder on your project. Commit and push everything to your repo. After that, let’s go to the settings tab on your project and in the left menu go to the Pages section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa893b8h7j51j5sb0cfp0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa893b8h7j51j5sb0cfp0.png" alt="Repo page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94bpp70s2trtdq9il4re.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94bpp70s2trtdq9il4re.png" alt="Settings page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then select your main branch (or the branch on which you are working on) and select the docs folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11oppjrv3fhhm3llqjaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11oppjrv3fhhm3llqjaz.png" alt="Pages page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that is it! In a few minutes your website should be live on the link that GitHub has given you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahnre6f474fogmr51r8h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahnre6f474fogmr51r8h.png" alt="Done!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfscyh1gaqonjwn23urz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfscyh1gaqonjwn23urz.png" alt="Handsome you"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The future awaits &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;In this article we only scratched the surface of what Docz is capable of, so be sure to check their &lt;a href="https://www.docz.site/docs/getting-started" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;p&gt;I encourage you to read about them to make your resume stand out from the crowd and always remember to support the creators of this amazing project and contribute if you can.&lt;/p&gt;

&lt;p&gt;Find the repo of the project &lt;a href="https://github.com/LinkSake/docz-resume" rel="noopener noreferrer"&gt;here&lt;/a&gt;. For end result, check out &lt;a href="https://linksake.github.io/docz-resume/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>docz</category>
      <category>documentation</category>
      <category>resume</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Docker + Rails: Una solución para tus dolores de cabeza</title>
      <dc:creator>Luis Angel Ortega</dc:creator>
      <pubDate>Mon, 06 Sep 2021 23:24:35 +0000</pubDate>
      <link>https://dev.to/linksake/docker-rails-una-solucion-para-tus-dolores-de-cabeza-jh8</link>
      <guid>https://dev.to/linksake/docker-rails-una-solucion-para-tus-dolores-de-cabeza-jh8</guid>
      <description>&lt;p&gt;¿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&gt;&lt;br&gt;
Hay una multitud de factores que pueden contribuir esto, por ello &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; 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&gt;

&lt;p&gt;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&gt;
&lt;h2&gt;
  
  
  Prerequisitos
&lt;/h2&gt;

&lt;p&gt;Para poder seguir esta guía necesitaras tener &lt;a href="https://docs.docker.com/get-docker/" rel="noopener noreferrer"&gt;Docker instalado&lt;/a&gt; así como un proyecto el cual quieras &lt;em&gt;dockerizar&lt;/em&gt;, si solamente quieres prácticar puedes usar &lt;a href="https://github.com/LinkSake/docker-rails" rel="noopener noreferrer"&gt;este proyecto de ejemplo&lt;/a&gt; el cual necesita una conexión a &lt;a href="https://es.wikipedia.org/wiki/PostgreSQL" rel="noopener noreferrer"&gt;Postgres&lt;/a&gt; y a &lt;a href="https://es.wikipedia.org/wiki/Redis" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; para funcionar.&lt;/p&gt;

&lt;p&gt;¿Eres impaciente? ¡Puedes clonar &lt;a href="https://github.com/LinkSake/docker-rails/tree/docker" rel="noopener noreferrer"&gt;esta rama&lt;/a&gt; del proyecto donde ya se encuentran los archivos necesarios para correr el projecto dentro de Docker!&lt;/p&gt;
&lt;h2&gt;
  
  
  Primero viene el Dockerfile
&lt;/h2&gt;

&lt;p&gt;Lo primero que haremos será hacer una &lt;a href="https://docs.docker.com/get-started/overview/#docker-objects" rel="noopener noreferrer"&gt;imagen&lt;/a&gt; personalizada para nuestro proyecto, así que crearemos un archivo en la raíz del mismo llamado &lt;code&gt;Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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" rel="noopener noreferrer"&gt;imagen oficial de Ruby&lt;/a&gt;, pero usaremos la versión de &lt;a href="https://es.wikipedia.org/wiki/Alpine_Linux" rel="noopener noreferrer"&gt;Alpine&lt;/a&gt; para tener una imagen más ligera como resultado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ruby:3.0.1-alpine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ 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&gt;
&lt;/blockquote&gt;

&lt;p&gt;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" rel="noopener noreferrer"&gt;proyecto de ejemplo&lt;/a&gt;, que incluyen las necesarias para realizar una conexión con Postgres, pero tendrás que descubrir cuales son necesarias para tu proyecto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ruby:3.0.1-alpine&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--update&lt;/span&gt; &lt;span class="nt"&gt;--no-cache&lt;/span&gt; &lt;span class="nt"&gt;--virtual&lt;/span&gt; run-dependencies &lt;span class="se"&gt;\
&lt;/span&gt;build-base &lt;span class="se"&gt;\
&lt;/span&gt;postgresql-client &lt;span class="se"&gt;\
&lt;/span&gt;postgresql-dev &lt;span class="se"&gt;\
&lt;/span&gt;yarn &lt;span class="se"&gt;\
&lt;/span&gt;git &lt;span class="se"&gt;\
&lt;/span&gt;tzdata &lt;span class="se"&gt;\
&lt;/span&gt;libpq &lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/cache/apk/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Puedes esperar a construir la imagen (&lt;code&gt;docker build .&lt;/code&gt;) para revisar el error que imprima Docker, con eso podrás ir averiguando que depenencias hacen falta 😉  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La última linea (&lt;code&gt;rm -rf /var/cache/apk/*&lt;/code&gt;) borra los paquetes de las dependencias que acabamos de instalar, esto ahorrará espacio en la imagen.  &lt;/p&gt;

&lt;p&gt;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;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ruby:3.0.1-alpine&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--update&lt;/span&gt; &lt;span class="nt"&gt;--no-cache&lt;/span&gt;  &lt;span class="nt"&gt;--virtual&lt;/span&gt; run-dependencies &lt;span class="se"&gt;\
&lt;/span&gt;build-base &lt;span class="se"&gt;\
&lt;/span&gt;postgresql-client &lt;span class="se"&gt;\
&lt;/span&gt;postgresql-dev &lt;span class="se"&gt;\
&lt;/span&gt;yarn &lt;span class="se"&gt;\
&lt;/span&gt;git &lt;span class="se"&gt;\
&lt;/span&gt;tzdata &lt;span class="se"&gt;\
&lt;/span&gt;libpq &lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/cache/apk/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /docker-rails&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;¡Recuerda cambiar el &lt;code&gt;docker-rails&lt;/code&gt; por el nombre de tu proyecto!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;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/" rel="noopener noreferrer"&gt;bundler&lt;/a&gt; donde colocarlas a través de una variable de ambiente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ruby:3.0.1-alpine&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--update&lt;/span&gt; &lt;span class="nt"&gt;--no-cache&lt;/span&gt;  &lt;span class="nt"&gt;--virtual&lt;/span&gt; run-dependencies &lt;span class="se"&gt;\
&lt;/span&gt;build-base &lt;span class="se"&gt;\
&lt;/span&gt;postgresql-client &lt;span class="se"&gt;\
&lt;/span&gt;postgresql-dev &lt;span class="se"&gt;\
&lt;/span&gt;yarn &lt;span class="se"&gt;\
&lt;/span&gt;git &lt;span class="se"&gt;\
&lt;/span&gt;tzdata &lt;span class="se"&gt;\
&lt;/span&gt;libpq &lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/cache/apk/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /docker-rails&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; BUNDLE_PATH /gems&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ruby:3.0.1-alpine&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--update&lt;/span&gt; &lt;span class="nt"&gt;--no-cache&lt;/span&gt;  &lt;span class="nt"&gt;--virtual&lt;/span&gt; run-dependencies &lt;span class="se"&gt;\
&lt;/span&gt;build-base &lt;span class="se"&gt;\
&lt;/span&gt;postgresql-client &lt;span class="se"&gt;\
&lt;/span&gt;postgresql-dev &lt;span class="se"&gt;\
&lt;/span&gt;yarn &lt;span class="se"&gt;\
&lt;/span&gt;git &lt;span class="se"&gt;\
&lt;/span&gt;tzdata &lt;span class="se"&gt;\
&lt;/span&gt;libpq &lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/cache/apk/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /docker-rails&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; BUNDLE_PATH /gems&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json yarn.lock /docker-rails/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; Gemfile Gemfile.lock /docker-rails/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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&gt;WORKDIR&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ruby:3.0.1-alpine&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--update&lt;/span&gt; &lt;span class="nt"&gt;--no-cache&lt;/span&gt;  &lt;span class="nt"&gt;--virtual&lt;/span&gt; run-dependencies &lt;span class="se"&gt;\
&lt;/span&gt;build-base &lt;span class="se"&gt;\
&lt;/span&gt;postgresql-client &lt;span class="se"&gt;\
&lt;/span&gt;postgresql-dev &lt;span class="se"&gt;\
&lt;/span&gt;yarn &lt;span class="se"&gt;\
&lt;/span&gt;git &lt;span class="se"&gt;\
&lt;/span&gt;tzdata &lt;span class="se"&gt;\
&lt;/span&gt;libpq &lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/cache/apk/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /docker-rails&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; BUNDLE_PATH /gems&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json yarn.lock /docker-rails/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; Gemfile Gemfile.lock /docker-rails/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /docker-rails/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;¿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&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finalmente le diremos a Docker que comando correr cuando iniciemos nuestro contenedor (&lt;code&gt;rails&lt;/code&gt;), así como los argumentos de este (&lt;code&gt;s -b 0.0.0.0&lt;/code&gt;) y que puerto exponer para que nosotros podamos accesar a nuestra aplicación.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ruby:3.0.1-alpine&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--update&lt;/span&gt; &lt;span class="nt"&gt;--no-cache&lt;/span&gt;  &lt;span class="nt"&gt;--virtual&lt;/span&gt; run-dependencies &lt;span class="se"&gt;\
&lt;/span&gt;build-base &lt;span class="se"&gt;\
&lt;/span&gt;postgresql-client &lt;span class="se"&gt;\
&lt;/span&gt;postgresql-dev &lt;span class="se"&gt;\
&lt;/span&gt;yarn &lt;span class="se"&gt;\
&lt;/span&gt;git &lt;span class="se"&gt;\
&lt;/span&gt;tzdata &lt;span class="se"&gt;\
&lt;/span&gt;libpq &lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/cache/apk/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /docker-rails&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; BUNDLE_PATH /gems&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json yarn.lock /docker-rails/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; Gemfile Gemfile.lock /docker-rails/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /docker-rails/&lt;/span&gt;

&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["bin/rails"]&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["s", "-b", "0.0.0.0"]&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;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&gt;
&lt;/blockquote&gt;

&lt;p&gt;Y con esto tenemos listo nuestro Dockerfile, aunque estamos lejos de tener nuestra aplicación lista. Si construyeramos nuestra imagen con &lt;code&gt;docker build .&lt;/code&gt; y trataramos de correrla con &lt;code&gt;docker start docker-rails&lt;/code&gt; 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&gt;

&lt;h2&gt;
  
  
  Luego el docker-compose.yml
&lt;/h2&gt;

&lt;p&gt;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/" rel="noopener noreferrer"&gt;docker-compose&lt;/a&gt;, esta útilidad de Docker nos ayudará a crear multimples contenedores de diferentes imagenes, &lt;a href="https://docs.docker.com/compose/networking/" rel="noopener noreferrer"&gt;conectarlos&lt;/a&gt;, darles &lt;a href="https://docs.docker.com/compose/environment-variables/" rel="noopener noreferrer"&gt;variables de ambiente&lt;/a&gt; e incluso &lt;a href="https://docs.docker.com/storage/volumes/" rel="noopener noreferrer"&gt;volumenes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Empezaremos creando un archivo llamado &lt;code&gt;docker-compose.yml&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y en su primera linea especificaremos que &lt;a href="https://docs.docker.com/compose/compose-file/#compose-and-docker-compatibility-matrix" rel="noopener noreferrer"&gt;versión&lt;/a&gt; de la herramienta queremos usar, en este caso usaremos la más reciente a la redacción de este articulo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después indicaremos los servicios que queremos que corra docker-compose, esto lo haremos dentro de la etiqueta &lt;code&gt;services&lt;/code&gt;. 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&gt;db&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-rails-db&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_DB=docker-rails-dev&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD=password&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;5432:5432&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dbdata:/var/lib/postgresql/data'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Los archivos YAML son sensibles a la identación, así que asegurate de tener todo en orden y andidado de forma correcta.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La etiqueta &lt;code&gt;db&lt;/code&gt; es el nombre que le dimos al servicio y dentro de la cual especificaremos toda la configuración del mismo.&lt;/p&gt;

&lt;p&gt;Lo primero con lo que nos encontramos es &lt;code&gt;image&lt;/code&gt; 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&gt;latest&lt;/code&gt; por alguna otra versión válida).&lt;/p&gt;

&lt;p&gt;Después nos encontramos con &lt;code&gt;container_name&lt;/code&gt;, que también es autodescriptivo y el cual vendra útil a la hora de checar nuestros contendores con &lt;code&gt;docker ps&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;enviroment&lt;/code&gt; 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" rel="noopener noreferrer"&gt;Docker de Posgres&lt;/a&gt; podemos ver que la única variable obligatoria es &lt;code&gt;POSTGRES_PASSWORD&lt;/code&gt; pero nosotros también definiremos &lt;code&gt;POSTGRES_DB&lt;/code&gt; para darle un nombre personalizado a la base de datos que crea la imagen por defecto.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ ¡Asegurate de elegir una contraseña segura para la base de datos!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;ports&lt;/code&gt; 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&gt;

&lt;p&gt;Finalmente los &lt;code&gt;volumes&lt;/code&gt; 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/" rel="noopener noreferrer"&gt;esta&lt;/a&gt; sección de la documentación.&lt;/p&gt;

&lt;p&gt;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" rel="noopener noreferrer"&gt;la imagen oficial.&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-rails-db&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_DB=docker-rails-dev&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD=password&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;5432:5432&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dbdata:/var/lib/postgresql/data'&lt;/span&gt;
  &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-rails-redis&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;6379:6379&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nuestro último servicio lo llamaremos &lt;code&gt;web&lt;/code&gt; y será la imagen que hemos construido con nuestro &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-rails-db&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_DB=docker-rails-dev&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD=password&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;5432:5432&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dbdata:/var/lib/postgresql/data'&lt;/span&gt;
  &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-rails-redis&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;6379:6379&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-rails&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-rails-web&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;3000:3000&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;redis&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_HOST=db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_USER=postgres&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD=password&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;REDIS_URL=redis://redis:6379&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La primer etiqueta nueva con la que nos topamos es &lt;code&gt;build&lt;/code&gt;, la cual indica el directorio donde se encuentra nuestro Dockerfile; dado a que nuestro Dockerfile está en la raíz solamente pondremos &lt;code&gt;.&lt;/code&gt;; 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" rel="noopener noreferrer"&gt;esta&lt;/a&gt; sección de la documentación para asegurarte que Compose lo encuentre.&lt;/p&gt;

&lt;p&gt;La etiqueta &lt;code&gt;image&lt;/code&gt; en este caso servirá para nombrar la imagen que construirá Compose, ya que al estar presente &lt;code&gt;build&lt;/code&gt; no irá al repositorio a buscar una imagen preconstruida.&lt;/p&gt;

&lt;p&gt;Por último, la etiqueta &lt;code&gt;depends_on&lt;/code&gt; informará a Compose que no se debe de tratar de iniciar el contenedor hasta que estén creados los servicios &lt;code&gt;db&lt;/code&gt; y &lt;code&gt;redis&lt;/code&gt;, 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/" rel="noopener noreferrer"&gt;Docker Network&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;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" rel="noopener noreferrer"&gt;nombramos&lt;/a&gt; de la siguiente manera.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-rails-db&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_DB=docker-rails-dev&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD=password&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;5432:5432&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dbdata:/var/lib/postgresql/data'&lt;/span&gt;
  &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-rails-redis&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;6379:6379&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-rails&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-rails-web&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;3000:3000&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;redis&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_HOST=db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_USER=postgres&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD=password&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;REDIS_URL=redis://redis:6379&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.:/app&lt;/span&gt;
&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;dbdata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;¡Y listo! Nuestro &lt;code&gt;docker-compose.yml&lt;/code&gt; está listo, ahora solo falta un paso para empezar a crear nuestra aplicación contenida en Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ojos que no ven, .dockerignore que no siente
&lt;/h2&gt;

&lt;p&gt;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&gt;node_modules&lt;/code&gt; y la carpeta &lt;code&gt;.git&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
Para ahorrarnos este espacio crearemos un archivo llamado &lt;code&gt;.dockerignore&lt;/code&gt; en la raíz de nuestro proyecto y añadiremos estas dos carpetas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;".git &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; node_modules"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .dockerignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para más información sobre lo que puede contenener un archivo &lt;code&gt;.dockerignore&lt;/code&gt; puedes consultar la &lt;a href="https://docs.docker.com/engine/reference/builder/#dockerignore-file" rel="noopener noreferrer"&gt;documentación oficial de Docker&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Unas bases de datos para llevar
&lt;/h2&gt;

&lt;p&gt;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;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose run web db:create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando le dice a Docker que use la imagen (que construirá) para correr un comando, en este caso &lt;code&gt;db:create&lt;/code&gt;. Docker, con lo especificado en el &lt;code&gt;docker-compose.yml&lt;/code&gt; sabe que como &lt;em&gt;web&lt;/em&gt; depende de &lt;em&gt;db&lt;/em&gt; tendrá que correr primero la instancia de Postgres, por lo que la base de datos se creará en este contenedor.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;¿Por qué solamente &lt;code&gt;db:create&lt;/code&gt; y no &lt;code&gt;rails db:create&lt;/code&gt; o &lt;code&gt;rake db:create&lt;/code&gt;? En nuestro &lt;code&gt;Dockerfile&lt;/code&gt; dimos como punto de entrada el comando &lt;code&gt;rails&lt;/code&gt;, 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/" rel="noopener noreferrer"&gt;docker exec&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Nuestra aplicación en un contenedor
&lt;/h2&gt;

&lt;p&gt;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/" rel="noopener noreferrer"&gt;modo separado&lt;/a&gt; y podremos ver el fruto de nuestro trabajo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;¡Y listo! Ya podrás accesar a traves de tu navegador a &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;localhost:3000&lt;/a&gt; y ver la página de bienvenida de Rails.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffiscat1lxr91qo1jnbaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffiscat1lxr91qo1jnbaj.png" alt="Welcome to Rails!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;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&gt;

&lt;p&gt;Espero que te haya sido útil, cualquier cosa puedes &lt;a href="https://luisangel.me/about#contacto" rel="noopener noreferrer"&gt;contactarme&lt;/a&gt; y responderé lo más pronto posible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bibliografía
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/samples/rails/" rel="noopener noreferrer"&gt;Docker Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gorails.com/episodes/docker-basics-for-gorails" rel="noopener noreferrer"&gt;Go Rails&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>rails</category>
      <category>ruby</category>
    </item>
  </channel>
</rss>
