<?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>Forem: Abraão Duarte</title>
    <description>The latest articles on Forem by Abraão Duarte (@abraaoduarte).</description>
    <link>https://forem.com/abraaoduarte</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%2F55836%2F378305aa-d28a-4f49-b143-7d1ee5481f16.jpg</url>
      <title>Forem: Abraão Duarte</title>
      <link>https://forem.com/abraaoduarte</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/abraaoduarte"/>
    <language>en</language>
    <item>
      <title>Simple Node Application with Docker + Nginx + Postgres + Docker Compose</title>
      <dc:creator>Abraão Duarte</dc:creator>
      <pubDate>Tue, 11 Jun 2024 12:07:00 +0000</pubDate>
      <link>https://forem.com/abraaoduarte/simple-node-application-with-docker-nginx-postgres-docker-compose-16p3</link>
      <guid>https://forem.com/abraaoduarte/simple-node-application-with-docker-nginx-postgres-docker-compose-16p3</guid>
      <description>&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%2Fj9cpt9ghace9pu2iprse.jpg" 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%2Fj9cpt9ghace9pu2iprse.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hi everyone, this is my first time trying to create a small tutorial where I will show how to run a Node application with Docker, Nginx with load balancing, Postgres, and Docker Compose. If you have any feedback at the end, please let me know; I will appreciate it. Also, English is not my native language, so if you find grammar errors, sorry about it.&lt;/p&gt;

&lt;p&gt;I will assume that you have Docker and Docker Compose installed on your machine. This tutorial was made on Ubuntu OS.&lt;/p&gt;

&lt;p&gt;If you don't have Docker and Docker Compose installed, you can visit the Docker website to see &lt;a href="https://docs.docker.com/engine/install/" rel="noopener noreferrer"&gt;how to install Docker&lt;/a&gt;. For Docker Compose, you can check this link: &lt;a href="https://docs.docker.com/compose/install/" rel="noopener noreferrer"&gt;Docker Compose&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's get down to business.&lt;/p&gt;

&lt;h4&gt;
  
  
  1 - Create a route using Hono.js
&lt;/h4&gt;

&lt;p&gt;Hono.js is a nice framework that helps us build Node apps. This article does not aim to teach &lt;code&gt;Hono.js&lt;/code&gt;; I will create a simple route to print &lt;strong&gt;Hello World!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, create a new folder on your machine using the command line:&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;mkdir &lt;/span&gt;example


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

&lt;/div&gt;

&lt;p&gt;Enter your folder and let's install some libraries. I will be using pnpm, a package manager like npm or yarn but with some differences. If you don't have it installed, you can access the straightforward instructions in the documentation: &lt;a href="https://pnpm.io/pt/installation" rel="noopener noreferrer"&gt;pnpm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install hono and typescrypt&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

~ pnpm init // To create the initial package.json
~ pnpm &lt;span class="nb"&gt;install &lt;/span&gt;hono
~ pnpm &lt;span class="nb"&gt;install&lt;/span&gt; @hono/node-server
~ pnpm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; typescript


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

&lt;/div&gt;

&lt;p&gt;After installing these packages, you should run the command below to create a default &lt;code&gt;tsconfig.json&lt;/code&gt;, which is the TypeScript configuration of the project.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

~ npx tsc &lt;span class="nt"&gt;--init&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now create a folder called &lt;code&gt;src&lt;/code&gt;, and inside it, create the file &lt;code&gt;server.ts&lt;/code&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;mkdir &lt;/span&gt;src
~ &lt;span class="nb"&gt;touch &lt;/span&gt;src/server.ts


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

&lt;/div&gt;

&lt;p&gt;In the &lt;code&gt;server.ts&lt;/code&gt; add the code below.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Hono&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hono&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;serve&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@hono/node-server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hono/logger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;     &lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&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="mi"&gt;7&lt;/span&gt;         &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Hono&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt;         &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="mi"&gt;9&lt;/span&gt; 
&lt;span class="mi"&gt;10&lt;/span&gt;        &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&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="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&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 World!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="mi"&gt;12&lt;/span&gt;        &lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="mi"&gt;13&lt;/span&gt;            &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="mi"&gt;14&lt;/span&gt;                &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="mi"&gt;15&lt;/span&gt;                &lt;span class="na"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="mi"&gt;16&lt;/span&gt;            &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="mi"&gt;17&lt;/span&gt;            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;info&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="mi"&gt;18&lt;/span&gt;                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Listening on http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="mi"&gt;19&lt;/span&gt;            &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="mi"&gt;20&lt;/span&gt;        &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="mi"&gt;21&lt;/span&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="mi"&gt;22&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="mi"&gt;23&lt;/span&gt;
&lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;



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

&lt;/div&gt;

&lt;p&gt;Here we have a simple server that will provide an endpoint returning "Hello World!".&lt;/p&gt;

&lt;p&gt;You should install the &lt;code&gt;tsx&lt;/code&gt; package to run the server:&lt;/p&gt;

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

~ pnpm install -D tsx


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

&lt;/div&gt;

&lt;p&gt;And in the &lt;code&gt;package.json&lt;/code&gt; under the scripts section, we add this line:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx tsx ./src/server.ts"&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&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%2Fx01ae2q9iccwvjvx7yo2.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%2Fx01ae2q9iccwvjvx7yo2.png" alt="package.json"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now in your terminal you can run:&lt;/p&gt;

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

~ pnpm start


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

&lt;/div&gt;

&lt;p&gt;Now our app is running. You just need to open your browser and go to the address &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt; and you will see the page with the &lt;strong&gt;Hello World!&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  2 Configure docker for our server
&lt;/h4&gt;

&lt;p&gt;Now we will configure a Dockerfile for our app. I will not explain the Docker syntax in detail, but this is a simple Dockerfile.&lt;/p&gt;

&lt;p&gt;In the root of the project create a Dockerfile&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;Now put this code inside the Dockerfile:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

1 FROM node:22-alpine
2
3 COPY . /app
4
5 WORKDIR /app
6
7 RUN npm install -g pnpm
8
9 RUN pnpm install
10
11 EXPOSE 3000
12
13 CMD ["pnpm", "start"]



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

&lt;/div&gt;

&lt;p&gt;1 - &lt;code&gt;FROM&lt;/code&gt; - This will tell the name of the image that we want to use.&lt;br&gt;
2 - &lt;code&gt;COPY&lt;/code&gt; - We are making a copy of everything from our project and putting in the app folder from our container.&lt;br&gt;
3 - &lt;code&gt;Workdir&lt;/code&gt; - We tell the container from what folder we want to execute our commands.&lt;br&gt;
4 - &lt;code&gt;RUN&lt;/code&gt; - We use this to install dependencies inside our container, in this case we are installing &lt;strong&gt;pnpm&lt;/strong&gt;.&lt;br&gt;
5 - &lt;code&gt;EXPOSE&lt;/code&gt; - Here we say what port our container will use. PS: Is not the port of our machine (host).&lt;br&gt;
6 - &lt;code&gt;CMD&lt;/code&gt; - We pass which commands the container should run at the end.&lt;/p&gt;

&lt;p&gt;Now create the build from our dockerfile:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

~ docker build &lt;span class="nt"&gt;-t&lt;/span&gt; my-server:1.0 &lt;span class="nb"&gt;.&lt;/span&gt; // You can put the name you want


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

&lt;/div&gt;

&lt;p&gt;The dot &lt;code&gt;.&lt;/code&gt; is for the command run the Dockerfile from the folder you are.&lt;/p&gt;

&lt;p&gt;If you want to see the container just use the command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

~ docker ps &lt;span class="nt"&gt;-a&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now run the container with this command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

~ docker run my-server:1.0


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

&lt;/div&gt;

&lt;p&gt;Access the &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt; you will see a problem: &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%2F69unne58iqv1a9se4lip.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%2F69unne58iqv1a9se4lip.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We cannot access the address because the app is running only inside the container, and we didn't specify which port from our machine the container should use.&lt;/p&gt;

&lt;p&gt;Let's try again, but now mapping the port from the container to a port on our machine (host):&lt;/p&gt;

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

~ docker run -p 3000:3000 my-server:1.0 


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

&lt;/div&gt;

&lt;p&gt;Now if you access the &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt; you'll see that the app running because we told Docker to map port 3000 from the container to port 3000 on our machine. PS: You could use another port here if you want.&lt;/p&gt;

&lt;p&gt;Now the app is working with Docker; let's configure Nginx.&lt;/p&gt;

&lt;h4&gt;
  
  
  3 - Configure Nginx with load balancing
&lt;/h4&gt;

&lt;p&gt;Nginx is an open-source web server software used for reverse proxy, load balancing, and caching.&lt;/p&gt;

&lt;p&gt;In the root of the project, create a new folder called &lt;strong&gt;nginx&lt;/strong&gt; , and inside it, create the &lt;code&gt;Dockerfile&lt;/code&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;mkdir &lt;/span&gt;nginx
~ &lt;span class="nb"&gt;touch &lt;/span&gt;nginx/Dockerfile


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

&lt;/div&gt;

&lt;p&gt;Before we configure Nginx, let's see it working on our machine. Put this code inside the &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

1 FROM nginx:latest
2
3 EXPOSE 80


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

&lt;/div&gt;

&lt;p&gt;Here we are getting the latest image from nginx from &lt;a href="https://hub.docker.com/_/nginx" rel="noopener noreferrer"&gt;Dockerhub&lt;/a&gt; and exposing the port 80 from the container. Now we can build and run it. Go to the nginx folder in your terminal and run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

~ docker build &lt;span class="nt"&gt;-t&lt;/span&gt; my-server-nginx:1.0 &lt;span class="nb"&gt;.&lt;/span&gt; // My container will have the name my-server-nginx:1.0
~ docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 9000:80 my-server-nginx:1.0


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

&lt;/div&gt;

&lt;p&gt;The second command runs our Nginx, listening to port 9000 on our machine. If you access &lt;a href="http://localhost:9000/" rel="noopener noreferrer"&gt;http://localhost:9000/&lt;/a&gt; you'll see the page:&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%2Fgrkkjyrcuysngcui0xau.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%2Fgrkkjyrcuysngcui0xau.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's configure load balancing for our Nginx. First, inside the nginx folder, create &lt;code&gt;nginx.conf&lt;/code&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;nginx.conf


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

&lt;/div&gt;

&lt;p&gt;Let's edit the ´nginx.conf' and add these lines:&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%2Fe1uuw0vjx46n5gh5h51c.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%2Fe1uuw0vjx46n5gh5h51c.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;upstream backend&lt;/code&gt; is responsible for our load balancing. Load balancing is a technique that distributes network traffic across multiple servers to prevent bottlenecks and improve performance. For more information, you can visit this &lt;a href="https://aws.amazon.com/what-is/load-balancing/?nc1=h_ls" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PS&lt;/strong&gt;: The &lt;code&gt;proxy_pass&lt;/code&gt; domain (line 18) should match the name you put in the upstream (line 7), in this case, &lt;code&gt;backend&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the upstream, we specify that we'll have two servers. Every time we access &lt;a href="http://myserver.local" rel="noopener noreferrer"&gt;http://myserver.local&lt;/a&gt; Nginx will redirect the request to one of these two servers, preventing server overload.&lt;/p&gt;

&lt;p&gt;In the Nginx Dockerfile, we can add a new line after the instruction &lt;code&gt;FROM&lt;/code&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;COPY&lt;/span&gt;&lt;span class="s"&gt; ./nginx.conf /etc/nginx/nginx.conf&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Your &lt;code&gt;Dockerfile&lt;/code&gt; should look 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%2Fr7qf8v68zuph258csoy5.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%2Fr7qf8v68zuph258csoy5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make it easy to run everything together, let's configure Docker Compose.&lt;/p&gt;

&lt;h4&gt;
  
  
  4 - Configure Docker Compose
&lt;/h4&gt;

&lt;p&gt;In the root of the project, create &lt;code&gt;docker-compose.yml&lt;/code&gt; and add the code below:&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.9'&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;app&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="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&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;./:/usr/app&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/usr/app/node_modules&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;networks&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-network&lt;/span&gt;

  &lt;span class="na"&gt;app2&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="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&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;./:/usr/app&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/usr/app/node_modules&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;3001:3000&lt;/span&gt;
    &lt;span class="na"&gt;networks&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-network&lt;/span&gt;

  &lt;span class="na"&gt;nginx&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="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./nginx/.&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;my-server-nginx&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="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80:80"&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;app&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app2&lt;/span&gt;
    &lt;span class="na"&gt;networks&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-network&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app-network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Note that we have two instances or containers for our server, &lt;code&gt;app&lt;/code&gt; and &lt;code&gt;app2&lt;/code&gt;. If you change these names, you'll need to change the name in the &lt;code&gt;nginx.conf&lt;/code&gt; inside the upstream.&lt;/p&gt;

&lt;p&gt;Also, in &lt;code&gt;nginx.conf&lt;/code&gt; inside the upstream, you should put the port that you exposed in your container, in our case, &lt;code&gt;3000&lt;/code&gt;. I don't know why, but when I tried to put the port of my machine, it didn't work.&lt;/p&gt;

&lt;p&gt;To access &lt;a href="http://myserver.local/" rel="noopener noreferrer"&gt;http://myserver.local/&lt;/a&gt; you will need to edit your &lt;code&gt;/etc/hosts&lt;/code&gt; file.&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;sudo &lt;/span&gt;vim /etc/hosts


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

&lt;/div&gt;

&lt;p&gt;At the end of the file, add this line:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

127.0.0.1 myserver.local


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

&lt;/div&gt;

&lt;p&gt;Now save the file and try to exit from vim 🤣&lt;/p&gt;

&lt;p&gt;In your terminal run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

~ docker-compose up


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

&lt;/div&gt;

&lt;p&gt;This command will start the apps and Nginx. Now you can access the route at &lt;a href="http://myserver.local/" rel="noopener noreferrer"&gt;http://myserver.local/&lt;/a&gt;, and every time you refresh the page, you will see that the request is sent to one of the servers, sometimes to &lt;code&gt;app&lt;/code&gt; and sometimes to &lt;code&gt;app2&lt;/code&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%2Fggds4qwkrne8fsqsha42.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%2Fggds4qwkrne8fsqsha42.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  5 - Configure Postgres
&lt;/h4&gt;

&lt;p&gt;I will not connect the app with the database; I will show just how to set up Postgres, and you can connect as you wish.&lt;/p&gt;

&lt;p&gt;In our &lt;code&gt;docker-compose.yml&lt;/code&gt;, add the following lines after the Nginx section:&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;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&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;postgres&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&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&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;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myserver&lt;/span&gt;
    &lt;span class="na"&gt;networks&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-network&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;postgres:/data/postgres&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;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;You can stop the containers using this command and start again:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

~ docker-compose down // stop the containers
~ docker-compose up


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

&lt;/div&gt;

&lt;p&gt;To view your database, you can install &lt;a href="https://dbeaver.io/download/" rel="noopener noreferrer"&gt;dbeaver&lt;/a&gt; I have been using DBeaver for a long time (thanks &lt;a href="https://x.com/original_bop" rel="noopener noreferrer"&gt;bop&lt;/a&gt; for recommending it 🙏🏻).&lt;/p&gt;

&lt;p&gt;Notice that we have three environment variables that Docker will use. You can change their values if you want.&lt;/p&gt;

&lt;p&gt;In DBeaver, you can click on new database connection, select Postgres, and fill in the database, password, and user fields with the values with environment variables in the &lt;code&gt;docker-compose.yml&lt;/code&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%2Fc1jtybfe3sa1nr4hf2qp.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%2Fc1jtybfe3sa1nr4hf2qp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that the:&lt;br&gt;
1 - &lt;code&gt;host&lt;/code&gt; = localhost # default&lt;br&gt;
2 - &lt;code&gt;username&lt;/code&gt; = docker # This comes from &lt;code&gt;POSTGRES_USER&lt;/code&gt; inside &lt;code&gt;docker-compose.yml&lt;/code&gt;&lt;br&gt;
3 - &lt;code&gt;password&lt;/code&gt; = postgres # This comes from &lt;code&gt;POSTGRES_PASSWROD&lt;/code&gt; inside &lt;code&gt;docker-compose.yml&lt;/code&gt;&lt;br&gt;
4 - &lt;code&gt;database&lt;/code&gt; = myserver # This comes from &lt;code&gt;POSTGRES_DB&lt;/code&gt; inside &lt;code&gt;docker-compose.yml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With all this, you will have a simple start project with hono.js + nginx + postgres + docker.&lt;/p&gt;

&lt;p&gt;And that's it, folks! Thank you for reading this far. If you liked the post, please give it a like.&lt;/p&gt;

&lt;p&gt;If you have feedback or questions, let me know.&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/abraaoduarte/docker-node-nginx-sample" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;SDG&lt;/small&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>docker</category>
      <category>nginx</category>
      <category>postgres</category>
    </item>
    <item>
      <title>CLEAN CODE - BOAS PRÁTICAS</title>
      <dc:creator>Abraão Duarte</dc:creator>
      <pubDate>Thu, 10 Jun 2021 22:29:10 +0000</pubDate>
      <link>https://forem.com/abraaoduarte/clean-code-boas-praticas-19n0</link>
      <guid>https://forem.com/abraaoduarte/clean-code-boas-praticas-19n0</guid>
      <description>&lt;p&gt;Atualmente estou lendo o livro Clean Code, escrito por Robert C. Martin, conhecido como Uncle Bob, por isso, decidi escrever um artigo com algumas dicas importantes que encontrei na leitura e que tem me motivado a escrever códigos melhores.&lt;/p&gt;

&lt;p&gt;Boa parte do tempo dos desenvolvedores de software é gasto escrevendo códigos, portanto devemos ter um cuidado em como escrevemos esses códigos, nós nos expressamos por meio dos códigos que escrevemos e, eles devem ser legíveis e de fácil compreensão.&lt;/p&gt;

&lt;p&gt;Talvez você já tenha percebido que nos passamos grande parte de nosso tempo dando manutenção, seja em sistemas legados e antigos, seja nos nossos próprios códigos que escrevemos a pouco tempo, estamos sempre acrescentando algo novo, corrigindo erros, melhorando, etc. Justamente por causa disso que devemos nos esforçar por escrever códigos melhores, mais legíveis, para que a manutenção e mesmo a evolução do sistema seja mais fácil e menos dolorosa.&lt;/p&gt;

&lt;p&gt;Quando nos deparamos em situações onde precisamos dar manutenção em algum código ruim, essa tarefa pode ser tornar demorada, difícil e cara, pois iremos gastar um tempo maior do que gastaríamos caso esse código estivesse mais legível 😠. E já vou adiantando, escrever código limpo não é uma tarefa simples e fácil, antes é algo trabalhoso, em outras palavras, você irá suar a camisa, nesse processo você irá errar, e também ver outros errarem, mas não desanime. No fim das contas como o próprio autor do livro diz:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Escrever código limpo é uma arte e vai tempo e prática. 😲&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O que seria um código limpo? Juntando algumas definições que encontrei no livro, pode se dizer que: ‘&lt;strong&gt;um código limpo é elegante e eficiente, que faz somente uma coisa, aquilo que ele se propõe a fazer. É algo simples e direto, legível e claro. É um código bem testado, bem escrito&lt;/strong&gt;’.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Para escrever código limpo precisamos estar atentos aos detalhes, pois eles são importantes e no fim das contas fazem a diferença.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dado essa introdução, irei apresentar algumas sugestões que encontrei no livro e que acho válido compartilhar, os códigos de exemplo estarão em Javascript, porém os conceitos podem ser aplicados em qualquer linguagem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nomes são importantes, portanto seja cuidadoso.
&lt;/h2&gt;

&lt;p&gt;Você já deve ter se deparado com nomes de variáveis, funções, métodos que eram obscuros e difíceis de compreender. Para entendermos esses nomes, gastamos um tempo maior que gastaríamos se o nome estivesse claro. Isso mostra que dar nomes corretos e claros fazem diferença.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Use nomes que revelam seu propósito.
&lt;/h3&gt;

&lt;p&gt;Um nome deve ter significado que diz o que ele faz ou ao que ele se refere. &lt;strong&gt;Se um nome precisa de um comentário, então ele já não revela seu proposito.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Exemplo ruim: 🙈&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const d = new Date();
const y = d.getYear();
const m = d.getMonth();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exemplo bom: 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const date = new Date();
const year = d.getYear();
const month = d.getMonth();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Use distinções significativas
&lt;/h3&gt;

&lt;p&gt;Exemplo ruim: 🙈&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;getDetails();
getData();
getRecord();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Às três funções parecem ser a mesma coisa, não existe uma distinção clara que diz o que essa função está fazendo.&lt;/p&gt;

&lt;p&gt;Um exemplo melhor pode ser o seguinte: 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;getUser(); // É melhor que os exemplos acima.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Use nomes fáceis de se pronunciar, ou pelo menos que sejam pronunciáveis.
&lt;/h3&gt;

&lt;p&gt;Você já se deparou com nome de variáveis que são impronunciáveis? Isso é uma má prática.&lt;/p&gt;

&lt;p&gt;Veja o seguinte exemplo: 🙈&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const yyyymmdstr = ‘2021-06-09’;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É uma variável que não tem como pronunciar seu nome. Poderíamos rescrever da seguinte maneira: 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const currentDate = ‘2021-06-09’;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Use nomes que sejam fáceis de se buscar.
&lt;/h3&gt;

&lt;p&gt;Por exemplo, nomes de uma letra só: &lt;code&gt;const d = new Date();&lt;/code&gt; são difíceis de se pesquisar e irá trazer uma infinidade de resultados&lt;/p&gt;

&lt;p&gt;Outro exemplo: 🙈&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;setTimeout(blastOff, 86400000);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pesquisar por número que não trazem nenhum significado não, é algo muito bom, e podem acabar retornando resultados inesperados, podemos escrever da seguinte maneira: 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const MILLISECONDS_PER_DAY = 86400000;

setTimeout(blastOff, MILLISECONDS_PER_DAY);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa maneira você pode pesquisar pelo nome da variável e também está claro o que esse numero representa.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Nomes de classes devem ter nomes com substantivos
&lt;/h3&gt;

&lt;p&gt;Exemplo: 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User {}
class Customer {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Nome de métodos é uma boa prática ter verbos
&lt;/h3&gt;

&lt;p&gt;Exemplo: 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;getUser();
deleteUser();
handleVote();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Escreva funções melhores
&lt;/h2&gt;

&lt;p&gt;Estamos escrevendo funções a todo momento, é importante que essas sejam claras e legíveis.&lt;/p&gt;

&lt;p&gt;Funções devem ser pequenas, você já deve ter se deparado em algum momento com funções com dezenas de linhas, que fazem várias coisas. Funções assim são difíceis de dar manutenção, pois é difícil entende-las.&lt;/p&gt;

&lt;p&gt;Algumas dicas para escrever funções melhores&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Faça apenas uma coisa
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Funções devem fazer somente uma coisa e devem fazê-la bem.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Uma boa forma de sabermos se nossa função faz mais de uma coisa é se conseguimos extrair outras funções dela.&lt;/p&gt;

&lt;p&gt;Exemplo ruim: 🙈&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function emailClients(clients) {
    clients.forEach(client =&amp;gt; {
        const clientRecord = database.lookup(client);
        if (clientRecord.isActive()) {
            email(client);
        }
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa função tem mais de uma responsabilidade, ela pega os dados do cliente e verifica se o cliente está ativo.&lt;/p&gt;

&lt;p&gt;Poderíamos separar da seguinte maneire: 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function emailActiveClients(clients) {
    clients.filter(isActiveClient).forEach(email);
}

function isActiveClient(client) {
    const clientRecord = database.lookup(client);
    return clientRecord.isActive();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Veja, cada função é responsável por fazer apenas 1 coisa.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As funções devem fazer uma coisa. Devem fazê-la bem. Devem fazer apenas ela. 😲&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Um nível de abstração por função
&lt;/h3&gt;

&lt;p&gt;Vários níveis de abstração dentro de uma função sempre geram confusão.&lt;br&gt;
Exemplo: 🙈&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function parseBetterJSAlternative(code) {
    const REGEXES = [ // ... ];
    const statements = code.split(" ");
    const tokens = [];
    REGEXES.forEach(REGEX =&amp;gt; {
        statements.forEach(statement =&amp;gt; { // ... });
    });
    const ast = [];
    tokens.forEach(token =&amp;gt; { // lex... });
    ast.forEach(node =&amp;gt; { // parse... }); }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Veja essa função, é difícil entender o que acontece mesmo ela sendo pequena. Imagina uma função com o triplo do tamanho, fazendo várias coisas, é difícil dar manutenção nessas funções.&lt;/p&gt;

&lt;p&gt;Veja como poderíamos escrever: 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function parseBetterJSAlternative(code) {
    const tokens = tokenize(code);
    const syntaxTree = parse(tokens);
    syntaxTree.forEach(node =&amp;gt; { // parse... });
}

function tokenize(code) {
    const REGEXES = [ // ... ];
    const statements = code.split(" ");
    const tokens = [];
    REGEXES.forEach(REGEX =&amp;gt; {
        statements.forEach(statement =&amp;gt; {
            tokens.push(/* ... */);
        });
    });
    return tokens;
}

function parse(tokens) {
    const syntaxTree = [];
    tokens.forEach(token =&amp;gt; {
        syntaxTree.push(/* ... */);
    });
    return syntaxTree;
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Use nomes descritivos
&lt;/h3&gt;

&lt;p&gt;Mesma regra que usamos para variáveis, que sejam claro e legível e diga o que a função faz.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Não tenha medo de criar nomes extensos, pois eles são melhores que um pequeno e enigmático.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Parâmetros de funções
&lt;/h3&gt;

&lt;p&gt;Devemos evitar passar vários parâmetros para uma função, o ideal é que nossas funções recebam no máximo 2 parâmetros.&lt;/p&gt;

&lt;p&gt;Veja o seguinte exemplo: 🙈&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createMenu(title, body, buttonText, cancellable) {
    // doSomething
}
createMenu("Foo", "Bar", "Baz", true);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Veja que é confuso e muito fácil esquecer de passar um parâmetro e quebrar a função.&lt;/p&gt;

&lt;p&gt;Prefira fazer assim: 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createMenu({ title, body, buttonText, cancellable }) {
    // doSomething
}
createMenu({
    title: "Foo",
    body: "Bar",
    buttonText: "Baz",
    cancellable: true
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa maneira fica mais clara, você sabe o que é o que.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Parâmetros lógicos
&lt;/h3&gt;

&lt;p&gt;Parâmetros lógicos é uma má prática, pois mostra explicitamente que a função faz mais de uma coisa.&lt;/p&gt;

&lt;p&gt;Veja: 🙈&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createFile(name, temp) {
    if (temp) {
        fs.create(`./temp/${name}`);
    } else {
        fs.create(name);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O parâmetro &lt;code&gt;temp&lt;/code&gt; é um booleano, isso implica que a função tem mais de uma responsabilidade.&lt;/p&gt;

&lt;p&gt;Poderíamos fazer: 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createFile(name) {
    fs.create(name);
}

function createTempFile(name) {
    createFile(`./temp/${name}`);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Veja que evitamos passar valores booleanos como parâmetro de função.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Evite efeitos colaterais
&lt;/h3&gt;

&lt;p&gt;Efeitos colaterais são mentiras. Sua função promete fazer apenas uma coisa, mas ela também faz outras coisas escondidas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Efeitos colaterais são perigosos, e muitas vezes difíceis de se identificar.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Veja esse exemplo: 🙈&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let name = "Ryan McDermott";

function splitIntoFirstAndLastName() {
    name = name.split(" ");
}
splitIntoFirstAndLastName();
console.log(name);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A variável &lt;code&gt;name&lt;/code&gt; está sendo modificada na função &lt;code&gt;splitIntoFirstAndLastName&lt;/code&gt; isso é ruim, pois em um arquivo com dezenas de linhas, você se perderia para encontrar os lugares onde essa variável está sendo modificada. Você não saberia qual é o valor de &lt;code&gt;name&lt;/code&gt; uma vez que em cada função ela pode ter um valor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evite variáveis globais.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Veja como poderíamos fazer: 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function splitIntoFirstAndLastName(name) {
    return name.split(" ");
}
const name = "Ryan McDermott";
const newName = splitIntoFirstAndLastName(name); console.log(name); // 'Ryan McDermott';
console.log(newName); // ['Ryan', 'McDermott'];

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

&lt;/div&gt;



&lt;p&gt;A variável &lt;code&gt;name&lt;/code&gt; é um parâmetro da função, e assim não tem nenhum efeito colateral ao alterar esse parâmetro na função.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Evite repetição
&lt;/h3&gt;

&lt;p&gt;Duplicação de código pode ser um grande mal no seu software, sempre que você ver que você está repetindo muito código, extraia isso para funções.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escreva comentários com responsabilidade
&lt;/h2&gt;

&lt;p&gt;Por vezes o uso de comentários é para compensar o nosso fracasso em nos expressar no código.&lt;/p&gt;

&lt;p&gt;É melhor você ter um código legível com poucos comentários do que um código complexo, difícil de ler com vários comentários.&lt;/p&gt;

&lt;p&gt;Não insira comentários em um código ruim, refatore ele.&lt;/p&gt;

&lt;p&gt;Comentários imprecisos são muito piores do que nenhum. O único lugar onde pode-se encontrar a verdade é no código. Só ele pode dizer o que ele realmente faz, comentários podem mentir.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comentários ruins
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Comentários esquecidos no código.&lt;/li&gt;
&lt;li&gt;Comentários redundantes, por exemplo:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Function that get users
    const getUsers = () =&amp;gt; {...}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Comentários longos&lt;/li&gt;
&lt;li&gt;Comentários ruidosos
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    // Return the day of month
    const getDayOfMonth = () =&amp;gt; {...}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Códigos como comentários&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;A conclusão é que se você é um programador você deveria se importar com seu código, se seguirmos essas dicas, ou pelo menos algumas delas, já estaremos escrevendo códigos melhores.&lt;/p&gt;

&lt;p&gt;Ao escrever código limpo estaremos ajudando futuras pessoas que venham dar manutenção no nosso código, e também estaremos ajudando a nós mesmo, caso no futuro tenhamos que dar manutenção no código que fizemos.&lt;/p&gt;

&lt;p&gt;Este é apenas alguns pontos que eu achei interessante nos primeiros 4 capítulos do livro, espero ainda trazer mais alguns artigos a respeito do assunto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fonte
&lt;/h2&gt;

&lt;p&gt;Martin, Robert C. Código Limpo: Habilidades práticas do agile software. Ed. Revisada São Paulo: Alta Books, 2011.&lt;/p&gt;

&lt;p&gt;Exemplos: &lt;a href="https://github.com/ryanmcdermott/clean-code-javascript"&gt;https://github.com/ryanmcdermott/clean-code-javascript&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>javascript</category>
      <category>bestpractices</category>
    </item>
  </channel>
</rss>
