<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>web development on luis angel ortega</title><link>https://luisangel.me/tags/web-development/</link><description>Recent Web Development on luis angel ortega</description><generator>Hugo</generator><language>en-US</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>Sat, 05 Nov 2022 11:53:11 -0500</lastBuildDate><atom:link href="https://luisangel.me/tags/web-development/index.xml" rel="self" type="application/rss+xml"/><item><title>Dropdowns and Toggles with Pure CSS</title><link>https://luisangel.me/post/2022/11/05/dropdowns-and-toggles-with-css/</link><pubDate>Sat, 05 Nov 2022 11:53:11 -0500</pubDate><author>hey@luisangel.me (Luis Angel Ortega)</author><guid>https://luisangel.me/post/2022/11/05/dropdowns-and-toggles-with-css/</guid><description>&lt;p>We could imagine the technologies of the platform on which I work, &lt;a href="https://www.joinbuildit.com/">Build It&lt;/a>, as a dish; where Ruby on Rails is our main dish but is accompanied by a good portion of JavaScript through &lt;a href="https://stimulus.hotwired.dev/">Stimulus JS&lt;/a>, and while this brings the functionality and that magical feeling of a single page application (SPA), there are things we want to keep simple instead of using a sledgehammer to kill an ant, as a university professor used to say. Therefore, we decided to take a page from &lt;a href="https://apple.com/mx">Apple&lt;/a> when handling dropdown menus or dropdowns and do it through pure CSS and HTML; without requiring a line of JavaScript.&lt;/p>
&lt;h2 id="the-pillars">The Pillars&lt;/h2>
&lt;p>Our two pillars in the view will be &lt;code>&amp;lt;input&amp;gt;&lt;/code> elements of checkbox type and &lt;code>&amp;lt;label&amp;gt;&lt;/code> tags. We will form our basic skeleton as follows:&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>We will be using the checked property of checkbox-type inputs to control the content we show and when we show it. For this, we will be relying on the &lt;code>&amp;lt;label&amp;gt;&lt;/code> element since by linking it through its &lt;code>for&lt;/code> property it will also be affected by the class change when the checked property of our checkbox is present.&lt;/p>
&lt;p>All our code will really be inside &lt;code>&amp;lt;label&amp;gt;&lt;/code> in two sections: container and toggle as shown below.&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;!-- The element with which the user will interact --&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;!-- What we want to show--&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="the-magic">The Magic&lt;/h2>
&lt;p>Now that we have our HTML skeleton ready, it&amp;rsquo;s time to add the CSS that will give our component the magical touch:&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>Our input with the toggle id will never be shown so that we do not have the checkbox present on our page, what we will show and with which the user interacts is what is inside our div with toggle class. Once they click on our toggle, the input will have the value of checked and with &lt;code>#toggle:checked+label&lt;/code> we affect the style of our &lt;code>&amp;lt;label&amp;gt;&lt;/code> to obtain a result like the following&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/dropdowns-toggle-css-1.gif" alt="Demo 1">&lt;/p>
&lt;p>And with a little more style (courtesy of Thulio Philipe) we can have results like this&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/dropdowns-toggle-css-2.gif" alt="Demo 2">&lt;/p>
&lt;p>Or as the examples we have inside 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>A small popover that is always present, giving vital information to the user&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/dropdowns-toggle-css-4.gif" alt="Demo 4">&lt;/p>
&lt;p>Or a filter menu that can be shown easily.&lt;/p>
&lt;p>As we can see, modern CSS allows us to make interactive pages without the need for a script for it; giving us a new solution to a problem with endless ways to solve it, so it will be necessary to consider the needs of the project and what is most suitable.&lt;/p>
&lt;p>Finally, I leave you &lt;a href="https://github.com/LinkSake/toggle-dropdown-css">a repository&lt;/a> with a couple of examples seen in this article for future reference and I invite you to visit &lt;a href="https://www.joinbuildit.com/early_access/client">the platform&lt;/a> and especially &lt;a href="https://www.joinbuildit.com/u/luis-ortega-160">my profile&lt;/a>, where we can connect for future projects.&lt;/p></description></item><item><title>Thinking Outside the Box an Online Resume With Docz</title><link>https://luisangel.me/post/2021/10/21/thinking-outside-the-box-an-online-resume-with-docz/</link><pubDate>Thu, 21 Oct 2021 15:32:45 -0500</pubDate><author>hey@luisangel.me (Luis Angel Ortega)</author><guid>https://luisangel.me/post/2021/10/21/thinking-outside-the-box-an-online-resume-with-docz/</guid><description>&lt;p>One of the best traits of humankind is its curiosity. It is so human that in honor of it we named a Mars rover &amp;ldquo;Curiosity&amp;rdquo; in 2003.&lt;/p>
&lt;p>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/">Docz&lt;/a> - a software documentation tool that is completely open source.&lt;/p>
&lt;h2 id="what-is-docz">What is Docz?&lt;/h2>
&lt;p>Docz is a &lt;a href="https://www.gatsbyjs.com/">Gatsby-based&lt;/a> project that simplifies the process of documenting other projects without worrying about configuration, speed and support.&lt;/p>
&lt;p>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>
&lt;p>Is this simplicity and friendliness that makes Docz a great option for more than just docs.&lt;/p>
&lt;h2 id="creating-our-docz-project">Creating our Docz project&lt;/h2>
&lt;p>Before we can jump into Docz, there are some prerequisites that you will need have in order to create the project:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm#overview">NodeJS&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://yarnpkg.com/getting-started/install">Yarn&lt;/a> or &lt;a href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm#overview">npm&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Now that you have the prerequisites, let’s start by creating a new React app with &lt;code>create-react-app&lt;/code> (CRA)&lt;/p>
&lt;p>Go to your terminal and run:&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>npx create-react-app my-resume
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If you don’t have CRA installed, npm will ask you if it’s okay to install &lt;code>create-react-app&lt;/code> type &lt;code>y&lt;/code> to continue and let CRA create the new project.&lt;/p>
&lt;blockquote>
&lt;p>We are using the command &lt;code>npx&lt;/code> instead of &lt;code>npm&lt;/code> 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">here&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;p>Now lets move to the directory of our project and install Docz.&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">cd&lt;/span> my-resume
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>yarn add docz &lt;span style="color:#737994;font-style:italic"># or npm install docz&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then let’s remove everything that CRA created for us inside the &lt;code>src&lt;/code> folder, since we don’t need it.&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>rm src/*
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Also, it is a good idea to add to the .gitignore the .docz folder since we only needed for development.&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-.gitignore" data-lang=".gitignore"># .gitignore

# Docz generated files
.docz/
&lt;/code>&lt;/pre>&lt;p>Let’s go and create a file named &lt;code>index.mdx&lt;/code> and a &lt;em>hello world&lt;/em> header in the following way.&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-mdx" data-lang="mdx">&amp;lt;!-- src/index.mdx --&amp;gt;

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

# Hello world from Docz!
&lt;/code>&lt;/pre>&lt;p>And it’s time to run our development server to see what we have just created.&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>yarn docz dev &lt;span style="color:#737994;font-style:italic"># or npm run docz dev&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>If you get an error &lt;a href="https://github.com/gatsbyjs/gatsby/issues/19922">ERROR #98123&lt;/a> while trying to run the development server, just delete your &lt;code>yarn.lock&lt;/code> or &lt;code>package-json.lock&lt;/code> and the &lt;code>node_modules&lt;/code> folder and install the dependencies again.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;em>Et voila!&lt;/em> We have successfully created our Docz project.&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/cv-docz-1.png" alt="Hello from Docz">&lt;/p>
&lt;blockquote>
&lt;p>Now is a good time to commit your files!&lt;/p>
&lt;/blockquote>
&lt;h2 id="your-time-to-shine">Your time to shine&lt;/h2>
&lt;p>Before we start adding more pages, let’s create a configuration file named &lt;code>doczrc.js&lt;/code> 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">all the configuration&lt;/a> of our project.&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-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#737994;font-style:italic">// doczrc.js
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#737994;font-style:italic">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">export&lt;/span> &lt;span style="color:#ca9ee6">default&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> title&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#34;Luis Angel Ortega&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> description&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#34;Hello, I&amp;#39;m Luis Angel and this is my resume made with Docz!&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ignore&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> [&lt;span style="color:#a6d189">&amp;#34;README.md&amp;#34;&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>The title key will set the suffix for our &lt;a href="https://www.w3schools.com/tags/tag_title.asp">title tag&lt;/a> 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>
&lt;p>Then, the description key that we added will modify the &lt;a href="https://moz.com/learn/seo/meta-description">meta description tag&lt;/a> on our webpage to display it when it’s looked up or shared online.&lt;/p>
&lt;p>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>
&lt;p>Now let’s add more pages! I’ll add a contact page with my socials and resume one in the following way&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-mdx" data-lang="mdx">&amp;lt;!-- src/contact.mdx --&amp;gt;

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

# Contact me! 🗣

---

Let&amp;#39;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>&lt;/pre>&lt;pre tabindex="0">&lt;code class="language-mdx" data-lang="mdx">&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=&amp;#39;growthconstant.co&amp;#39; target=&amp;#39;_blank&amp;#39;&amp;gt;Growth Constant&amp;lt;/a&amp;gt;, (Mar. 2021 - Currently)&amp;lt;/summary&amp;gt;
 &amp;lt;div style={{marginLeft: &amp;#39;1em&amp;#39;}}&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=&amp;#39;virtualdash.co&amp;#39; target=&amp;#39;_blank&amp;#39;&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=&amp;#39;facturasamurai.com&amp;#39; target=&amp;#39;_blank&amp;#39;&amp;gt;Factura Samurai&amp;lt;/a&amp;gt;, (Aug. - Dec. 2020)&amp;lt;/summary&amp;gt;
 &amp;lt;div style={{marginLeft: &amp;#39;1em&amp;#39;}}&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=&amp;#39;biobot.farm&amp;#39; target=&amp;#39;_blank&amp;#39;&amp;gt;biobot.farm&amp;lt;/a&amp;gt;, (Aug. 2019 - Jun. 2020)&amp;lt;/summary&amp;gt;
 &amp;lt;div style={{marginLeft: &amp;#39;1em&amp;#39;}}&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&amp;#39;s Degree in Information Technologies and Telecomunications. &amp;lt;a href=&amp;#39;ulsachihuahua.edu.mx/site&amp;#39; target=&amp;#39;_blank&amp;#39;&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: &amp;#39;1em&amp;#39;}}&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: &amp;#39;1em&amp;#39;}}&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: &amp;#39;1em&amp;#39;}}&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: &amp;#39;1em&amp;#39;}}&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: &amp;#39;1em&amp;#39;}}&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: &amp;#39;1em&amp;#39;}}&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>&lt;/pre>&lt;p>As you can see, using MDX means that we can use &lt;a href="https://www.markdownguide.org/">Markdown syntax&lt;/a> and &lt;a href="https://es.reactjs.org/docs/introducing-jsx.html">JSX&lt;/a> in the same document, giving a lot of flexibility and customization to our Docz projects.&lt;/p>
&lt;p>At the end they will look something like this:&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/cv-docz-2.png" alt="Contact page">&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/cv-docz-3.png" alt="Resume page">&lt;/p>
&lt;h2 id="spice-it-adding-a-custom-component">Spice it! Adding a custom component&lt;/h2>
&lt;p>Now let’s focus on our &lt;code>index.mdx&lt;/code> file. Let’s change it’s title to &amp;ldquo;About me&amp;rdquo;&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-mdx" data-lang="mdx">&amp;lt;!-- src/index.mdx --&amp;gt;
---
name: About me
route: /
---

# Hello world from Docz!
&lt;/code>&lt;/pre>&lt;p>And then, create a &lt;code>components&lt;/code> folder inside of the &lt;code>src&lt;/code> directory. There create a &lt;code>welcome.jsx&lt;/code> component, this will replace our Markdown heading to make the root page more interesting.&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-jsx" data-lang="jsx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#737994;font-style:italic">// src/components/welcome.jsx
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#737994;font-style:italic">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">import&lt;/span> React from &lt;span style="color:#a6d189">&amp;#39;react&amp;#39;&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:#ca9ee6">const&lt;/span> Welcome &lt;span style="color:#99d1db;font-weight:bold">=&lt;/span> ( props ) =&amp;gt; {
&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:#ca9ee6">const&lt;/span> style &lt;span style="color:#99d1db;font-weight:bold">=&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> container&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> display&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#39;flex&amp;#39;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> flexDirection&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#39;column&amp;#39;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> textContainer&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> textAlign&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#39;center&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> imgContainer&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> paddingTop&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#39;1em&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> img&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> display&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#39;flex&amp;#39;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> margin&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#39;auto&amp;#39;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> maxWidth&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#39;40%&amp;#39;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> borderRadius&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#39;50%&amp;#39;&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>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ca9ee6">return&lt;/span> (
&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">style&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>{style.container}&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">style&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>{style.textContainer}&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#ca9ee6">h1&lt;/span>&amp;gt;{props.title}&amp;lt;/&lt;span style="color:#ca9ee6">h1&lt;/span>&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#ca9ee6">span&lt;/span>&amp;gt;{props.children}&amp;lt;/&lt;span style="color:#ca9ee6">span&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>&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">style&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>{style.imgContainer}&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &amp;lt;&lt;span style="color:#ca9ee6">img&lt;/span> &lt;span style="color:#8caaee">style&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>{style.img} &lt;span style="color:#8caaee">src&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>{props.img} &lt;span style="color:#8caaee">alt&lt;/span>&lt;span style="color:#99d1db;font-weight:bold">=&lt;/span>{props.title}/&amp;gt;
&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>&amp;gt;
&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>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">export&lt;/span> &lt;span style="color:#ca9ee6">default&lt;/span> Welcome
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>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>
&lt;p>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>
&lt;p>&lt;img src="https://luisangel.me/images/post/cv-docz-4.png" alt="Welcome page">&lt;/p>
&lt;h2 id="its-alive-time-to-deploy">It&amp;rsquo;s alive! Time to deploy&lt;/h2>
&lt;p>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>
&lt;p>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;/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-js" data-lang="js">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#737994;font-style:italic">// doczrc.js
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#737994;font-style:italic">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ca9ee6">export&lt;/span> &lt;span style="color:#ca9ee6">default&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> title&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#34;Luis Angel Ortega&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> description&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#34;Hello, I&amp;#39;m Luis Angel and this is my resume made with Docz!&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ignore&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> [&lt;span style="color:#a6d189">&amp;#34;README.md&amp;#34;&lt;/span>],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> dest&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#34;/docs&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> base&lt;span style="color:#99d1db;font-weight:bold">:&lt;/span> &lt;span style="color:#a6d189">&amp;#34;docz-resume&amp;#34;&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>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>
&lt;p>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>
&lt;p>Once we have everything correctly configured, we need to build the project with the following command:&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>yarn docz build &lt;span style="color:#737994;font-style:italic"># or npm run docz build&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>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>
&lt;p>&lt;img src="https://luisangel.me/images/post/cv-docz-5.png" alt="Repo page">&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/cv-docz-6.png" alt="Settings page">&lt;/p>
&lt;p>Then select your main branch (or the branch on which you are working on) and select the docs folder.&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/cv-docz-7.png" alt="Pages page">&lt;/p>
&lt;p>And that is it! In a few minutes your website should be live on the link that GitHub has given you.&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/cv-docz-8.png" alt="Done!">&lt;/p>
&lt;p>&lt;img src="https://luisangel.me/images/post/cv-docz-9.png" alt="Handsome you">&lt;/p>
&lt;h2 id="the-future-awaits">The future awaits&lt;/h2>
&lt;p>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">documentation&lt;/a> to learn more.&lt;/p>
&lt;p>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>
&lt;p>Find the repo of the project &lt;a href="https://github.com/LinkSake/docz-resume">here&lt;/a>. For end result, check out &lt;a href="https://linksake.github.io/docz-resume/">GitHub&lt;/a>.&lt;/p></description></item><item><title>Docker + Rails: A Solution for Your Headaches</title><link>https://luisangel.me/post/2021/09/02/docker-and-rails/</link><pubDate>Thu, 02 Sep 2021 15:15:49 -0500</pubDate><author>hey@luisangel.me (Luis Angel Ortega)</author><guid>https://luisangel.me/post/2021/09/02/docker-and-rails/</guid><description>&lt;p>Have you ever spent a week just trying to run the project you just joined? Or does your application not run in production as it did locally?
There are a multitude of factors that can contribute to this, which is why &lt;a href="https://www.docker.com/">Docker&lt;/a> offers us a solution with which we can have greater control over these variables across the necessary computers.&lt;/p>
&lt;p>With that said, in this article we will see how to make our lives easier by having our entire Ruby on Rails application running on Docker; including any necessary databases.&lt;/p>
&lt;h2 id="prerequisites">Prerequisites&lt;/h2>
&lt;p>To follow this guide, you will need to have &lt;a href="https://docs.docker.com/get-docker/">Docker installed&lt;/a> as well as a project you want to &lt;em>dockerize&lt;/em>. If you just want to practice, you can use &lt;a href="https://github.com/LinkSake/docker-rails">this example project&lt;/a> which requires a connection to &lt;a href="https://en.wikipedia.org/wiki/PostgreSQL">Postgres&lt;/a> and &lt;a href="https://en.wikipedia.org/wiki/Redis">Redis&lt;/a> to function.&lt;/p>
&lt;p>Are you impatient? You can clone &lt;a href="https://github.com/LinkSake/docker-rails/tree/docker">this branch&lt;/a> of the project where the necessary files to run the project inside Docker are already present!&lt;/p>
&lt;h2 id="first-comes-the-dockerfile">First Comes the Dockerfile&lt;/h2>
&lt;p>The first thing we will do is create a custom &lt;a href="https://docs.docker.com/get-started/overview/#docker-objects">image&lt;/a> for our project, so we will create a file at the root of it called &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>The first line of our file will define the image we will base on, in this case, it will be the &lt;a href="https://hub.docker.com/_/ruby">official Ruby image&lt;/a>, but we will use the Alpine version to have a lighter image as a result.&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>⚠️ Make sure the Ruby version (ruby:X.X.X-alpine) is the same as in your project, or you will have errors when trying to build the image. You can find the version used by your project in your Gemfile.&lt;/p>
&lt;/blockquote>
&lt;p>Next comes the most difficult part of this Dockerfile, installing the necessary dependencies for the project to function; those shown here are the ones that work for our &lt;a href="https://github.com/LinkSake/docker-rails">example project&lt;/a>, which include the necessary ones to make a connection with Postgres, but you will have to discover which ones are necessary for your project.&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>You can wait to build the image (&lt;code>docker build .&lt;/code>) to check the error printed by Docker, with that you can find out what dependencies are missing 😉&lt;/p>
&lt;/blockquote>
&lt;p>The last line (&lt;code>rm -rf /var/cache/apk/*&lt;/code>) deletes the packages of the dependencies we just installed, this will save space in the image.&lt;/p>
&lt;p>Next, we need to create a directory inside the container where we can copy the code of our application for its execution, we will do this with the following command inside our 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>Remember to change &lt;code>docker-rails&lt;/code> to your project name!&lt;/p>
&lt;/blockquote>
&lt;p>Just as we gave your project a home inside the container we will create, the gems of the same need a folder too. Therefore, we will inform &lt;a href="https://bundler.io/">bundler&lt;/a> where to place them through an environment variable.&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>And although we have already installed the necessary dependencies to run Rails within the container, your project will need some gems and some JavaScript packages to function correctly, we will take care of that as follows.&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>Now that we have everything necessary for your project to function, we will copy the code to the container inside the folder we created with the &lt;code>WORKDIR&lt;/code> command.&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>Why do we first copy the manifests (package.json, Gemfile, etc.) and then the rest of the project? This avoids having to reinstall the dependencies (since they stay in the cache) after changing the base code and rebuilding the image; this way only when the manifests change will their installation commands be run again.&lt;/p>
&lt;/blockquote>
&lt;p>Finally, we will tell Docker what command to run when we start our container (&lt;code>rails&lt;/code>), as well as the arguments for it (&lt;code>s -b 0.0.0.0&lt;/code>) and which port to expose so that we can access our application.&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>WORKROOM /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">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>The default port over which Rails runs is 3000, but if you have designated another port within your application make sure to expose it correctly.&lt;/p>
&lt;/blockquote>
&lt;p>And with this we have our Dockerfile ready, although we are far from having our application ready. If we build our image with &lt;code>docker build .&lt;/code> and try to run it with &lt;code>docker start docker-rails&lt;/code> we would encounter an error, since Rails does not find the databases it needs to start correctly; but we will soon take care of that.&lt;/p>
&lt;h2 id="then-the-docker-composeyml">Then the docker-compose.yml&lt;/h2>
&lt;p>To coordinate all the services we need for the correct functioning of our application (in this case 2 databases: Postgres and Redis) we will use &lt;a href="https://docs.docker.com/compose/">docker-compose&lt;/a>, this Docker utility will help us create multiple containers from different images, &lt;a href="https://docs.docker.com/compose/networking/">connect them&lt;/a>, give them &lt;a href="https://docs.docker.com/compose/environment-variables/">environment variables&lt;/a> and even &lt;a href="https://docs.docker.com/storage/volumes/">volumes&lt;/a>.&lt;/p>
&lt;p>We will start by creating a file called &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>And on its first line we will specify which &lt;a href="https://docs.docker.com/compose/compose-file/#compose-and-docker-compatibility-matrix">version&lt;/a> of the tool we want to use, in this case we will use the most recent at the time of writing this article.&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>Next, we will indicate the services we want docker-compose to run, we will do this under the &lt;code>services&lt;/code> label. We will give each service a name, which will be important when we are configuring our image, so make sure to name it in a way that makes sense to you. Let&amp;rsquo;s start with the Postgres service, which we will call &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>YAML files are sensitive to indentation, so make sure everything is in order and indented correctly.&lt;/p>
&lt;/blockquote>
&lt;p>The &lt;code>db&lt;/code> tag is the name we gave to the service and within which we will specify all the configuration for it.&lt;/p>
&lt;p>The first thing we encounter is &lt;code>image&lt;/code>, which as its name indicates is the name of the image we want to use for that service, in this case it is the official Postgres image in its latest version (you can specify a version by replacing &lt;code>latest&lt;/code> with another valid version).&lt;/p>
&lt;p>Then we encounter &lt;code>container_name&lt;/code>, which is also self-explanatory and which will come in handy when checking our containers with &lt;code>docker ps&lt;/code>.&lt;/p>
&lt;p>&lt;code>environment&lt;/code> refers to the environment variables, and if we refer to the &lt;a href="https://hub.docker.com/_/postgres">Docker Postgres image documentation&lt;/a> we can see that the only mandatory variable is &lt;code>POSTGRES_PASSWORD&lt;/code> but we will also define &lt;code>POSTGRES_DB&lt;/code> to give a custom name to the database that the image creates by default.&lt;/p>
&lt;blockquote>
&lt;p>⚠️ Be sure to choose a secure password for the database!&lt;/p>
&lt;/blockquote>
&lt;p>&lt;code>ports&lt;/code> are the ports that we will need to pass from inside the container to our machine, the ones indicated in the file are the ones that Postgres uses by default.&lt;/p>
&lt;p>Finally, the &lt;code>volumes&lt;/code> are the persistent information we will need so as not to run the migrations every time we turn on the container, this is because Docker deletes all data once we shut down the information, if you want to learn more about this topic I recommend &lt;a href="https://docs.docker.com/storage/volumes/">this&lt;/a> section of the documentation.&lt;/p>
&lt;p>Now, the next service is Redis but we will not delve much into it as it only has a couple of labels which we have already reviewed, for more information you can visit &lt;a href="https://hub.docker.com/_/redis">the official image&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>Our last service we will call &lt;code>web&lt;/code> and it will be the image we have built with our &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>The first new tag we encounter is &lt;code>build&lt;/code>, which indicates the directory where our Dockerfile is located; since our Dockerfile is at the root we will only put &lt;code>.&lt;/code>; if your Dockerfile is not at the root or has another name it is advisable to read &lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#build">this&lt;/a> section of the documentation to make sure Compose finds it.&lt;/p>
&lt;p>The &lt;code>image&lt;/code> tag in this case will serve to name the image that Compose will build, since &lt;code>build&lt;/code> is present it will not go to the repository to look for a pre-built image.&lt;/p>
&lt;p>Finally, the &lt;code>depends_on&lt;/code> tag will inform Compose that it should not try to start the container until the &lt;code>db&lt;/code> and &lt;code>redis&lt;/code> services are created, as well as it will connect them internally so that we can access them through a URL (as can be seen in the Redis environment variable) or by their respective credentials (as is the case with Postgres), if you want to learn how Docker handles this you can read about &lt;a href="https://docs.docker.com/compose/networking/">Docker Network&lt;/a>.&lt;/p>
&lt;p>Now that we have finished with the services, the only thing we must do is list the volumes we will use and which we &lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#volumes">named&lt;/a> in the following way.&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>And that&amp;rsquo;s it! Our &lt;code>docker-compose.yml&lt;/code> is ready, now there&amp;rsquo;s only one step left to start creating our Docker-contained application.&lt;/p>
&lt;h2 id="out-of-sight-dockerignore-out-of-mind">Out of Sight, .dockerignore Out of Mind&lt;/h2>
&lt;p>Many times we do not want certain files to be in our Docker image because they are not necessary for its construction (or are generated in it) and only end up making the project larger than it needs to be, such as the &lt;code>node_modules&lt;/code> and &lt;code>.git&lt;/code> folder.
To save this space, we will create a file called &lt;code>.dockerignore&lt;/code> at the root of our project and add these two folders:&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>For more information on what a &lt;code>.dockerignore&lt;/code> file can contain, you can consult the &lt;a href="https://docs.docker.com/engine/reference/builder/#dockerignore-file">official Docker documentation&lt;/a>&lt;/p>
&lt;h2 id="databases-2-go">Databases 2 Go&lt;/h2>
&lt;p>Before running the project it will be necessary to create the database that Rails expects, and creating it is so simple that it can be done in a single command.&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>This command tells Docker to use the image (which it will build) to run a command, in this case &lt;code>db:create&lt;/code>. Docker, with what is specified in the &lt;code>docker-compose.yml&lt;/code>, knows that since &lt;em>web&lt;/em> depends on &lt;em>db&lt;/em> it will have to run the Postgres instance first, so the database will be created in this container.&lt;/p>
&lt;blockquote>
&lt;p>Why only &lt;code>db:create&lt;/code> and not &lt;code>rails db:create&lt;/code> or &lt;code>rake db:create&lt;/code>? In our &lt;code>Dockerfile&lt;/code> we gave &lt;code>rails&lt;/code> as the entry point, so only the parameters are necessary. If we wanted to perform another command inside the container this would have to be through &lt;a href="https://docs.docker.com/engine/reference/commandline/exec/">docker exec&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;h2 id="our-application-in-a-container">Our Application in a Container&lt;/h2>
&lt;p>With the database created, there&amp;rsquo;s only one command left that will run the containers in &lt;a href="https://docs.docker.com/compose/reference/up/">detached mode&lt;/a> and we will be able to see the fruit of our labor.&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>And that&amp;rsquo;s it! You can now access through your browser to &lt;a href="http://localhost:3000/">localhost:3000&lt;/a> and see the Rails welcome page.&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="conclusion">Conclusion&lt;/h2>
&lt;p>This whole process may be a bit intimidating at first, especially if you are not familiar with Docker, but the result is a much simpler development environment for everyone involved in the project, as now just by having Docker installed they can start programming; not to mention the benefits that this technology can bring to your production environment when combined with Kubernetes or Docker Swarm.&lt;/p>
&lt;p>I hope you found this useful, anything you can &lt;a href="https://luisangel.me/es/about">contact me&lt;/a> and I will respond as soon as possible.&lt;/p>
&lt;h2 id="references">References&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></channel></rss>