<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Julian Lasso 🇨🇴</title>
    <description>The latest articles on DEV Community by Julian Lasso 🇨🇴 (@julianlasso).</description>
    <link>https://dev.to/julianlasso</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%2F1161243%2Fa79f3ab8-1a52-4815-b041-83bde83e4082.jpg</url>
      <title>DEV Community: Julian Lasso 🇨🇴</title>
      <link>https://dev.to/julianlasso</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/julianlasso"/>
    <language>en</language>
    <item>
      <title>How to install Docker CLI on Windows without Docker Desktop and not die trying</title>
      <dc:creator>Julian Lasso 🇨🇴</dc:creator>
      <pubDate>Wed, 27 Mar 2024 19:59:15 +0000</pubDate>
      <link>https://dev.to/julianlasso/how-to-install-docker-cli-on-windows-without-docker-desktop-and-not-die-trying-4033</link>
      <guid>https://dev.to/julianlasso/how-to-install-docker-cli-on-windows-without-docker-desktop-and-not-die-trying-4033</guid>
      <description>&lt;p&gt;In this post, we will explore how to install and configure Docker CLI on Windows without the need for Docker Desktop. Although Docker Desktop is a convenient and popular tool for managing Docker containers in development environments, there are situations where a lighter or more specific alternative is preferred or required. Whether due to licensing restrictions, minimal resource needs, or personal preferences, installing only Docker CLI can be the ideal solution. I will guide you through the necessary steps to set up your Windows environment to use Docker CLI, leveraging the capabilities of WSL 2 (Windows Subsystem for Linux version 2) and without the overhead of Docker Desktop. This will not only provide you with more granular control over your Docker containers but will also optimize resource usage on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preliminary steps for installation
&lt;/h2&gt;

&lt;p&gt;The following steps have been tested on Windows 10, but I assume they will work the same for Windows 11.&lt;/p&gt;

&lt;p&gt;The first thing to do is to install WSL, and for that, open a PowerShell console and type the following command.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wsl &lt;span class="nt"&gt;--install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After the previous step, you need to restart the operating system.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: As I read, the following command does the same but additionally restarts the computer when it finishes the necessary installation.&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Enable-WindowsOptionalFeature &lt;span class="nt"&gt;-Online&lt;/span&gt; &lt;span class="nt"&gt;-FeatureName&lt;/span&gt; Microsoft-Windows-Subsystem-Linux
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;When the computer has restarted, a window like the following will open:&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%2Fc2z6qvlbb51gkedjebkz.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%2Fc2z6qvlbb51gkedjebkz.png" alt="Consola terminando de instalar linux"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After waiting for some time, an English message will appear, which will tell you to enter the username for your Linux user and will also ask for the password. Write down your username and password carefully because we will need them later.&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%2Fx0cz8vlxnnxgjizpoqi1.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%2Fx0cz8vlxnnxgjizpoqi1.png" alt="Consola solicitando nombre de usuario para la distribución linux"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v8yq217z1hhimxpicfb.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%2F4v8yq217z1hhimxpicfb.png" alt="Consola solicitando contraseña y confirmación de la misma para nuestro usuario en linux"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once it has finished successfully, then it's time to start installing the Docker CLI and we will be located in the console of our Linux distribution.&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%2F3b48np7aawtrk95clc6b.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%2F3b48np7aawtrk95clc6b.png" alt="Consola linux lista para empezar a trabajar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: It's important to keep in mind that the distribution installed by default is Ubuntu 22 at the time of writing this tutorial.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once at this point, the first thing to do is to update the repositories and programs of the distribution with the following command:&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;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This action will request the password that we assigned to our user.&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%2Ffj09j3k22ma6aspay5h3.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%2Ffj09j3k22ma6aspay5h3.png" alt="Solicitud de contraseña para actualizar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: don't forget to say yes (press Y) to confirm that you want to proceed with installing the updates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Adding the official Docker CLI repository
&lt;/h2&gt;

&lt;p&gt;When the updates are finished, then we will run the following command to perform some necessary installations prior to Docker CLI.&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;apt &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;apt-transport-https ca-certificates curl gnupg lsb-release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After that, we will run the following command to add the necessary signature for the Docker CLI repository.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://download.docker.com/linux/ubuntu/gpg | &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/share/keyrings/docker-archive-keyring.gpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now it's time to add the Docker CLI repository in Ubuntu for its subsequent installation with the following command.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [arch=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dpkg &lt;span class="nt"&gt;--print-architecture&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
  &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;lsb_release &lt;span class="nt"&gt;-cs&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; stable"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/docker.list &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Installing Docker CLI
&lt;/h2&gt;

&lt;p&gt;Since we now have the Docker CLI repository ready, it's time to do the required installation with the following command:&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;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;At this point, we now have Docker CLI installed in our WSL, let's test it with the following commands:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker --version
docker-compose --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We should get a response similar to the one in the following image:&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%2Ft3oety4mky1eimg1jwr6.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%2Ft3oety4mky1eimg1jwr6.png" alt="Comprobación de los comandos docker y docker-compose"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to run Docker without root user
&lt;/h2&gt;

&lt;p&gt;Now we will create the &lt;code&gt;docker&lt;/code&gt; group and add our user to that group so our user can run containers without needing to run commands as &lt;code&gt;root&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;sudo &lt;/span&gt;groupadd docker
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker &lt;span class="nv"&gt;$USER&lt;/span&gt;
newgrp docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: When you try to create the docker group, you will probably get a message saying the group already exists. If that's the case, don't worry, just proceed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now what we need to do is start Docker and verify it's working correctly, and for that we'll use the following commands:&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;service docker start
&lt;span class="nb"&gt;sudo &lt;/span&gt;service docker status
docker run hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When you run the &lt;code&gt;sudo service docker status&lt;/code&gt; command, you'll get something like the following image:&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%2F8yli1dddkhjnpq6jcp3n.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%2F8yli1dddkhjnpq6jcp3n.png" alt="sudo service docker status"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To exit that, press the Q key&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When using the &lt;code&gt;docker run hello-world&lt;/code&gt; command, you may receive a message like the one in the following image:&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%2F1cyi5vrk5ycg4o0l5flg.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%2F1cyi5vrk5ycg4o0l5flg.png" alt="Error al correr el hola mundo de Docker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't forget to run the following command and then run the Docker hello-world again:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;Now if everything went well, you should get an image like the following when running the Docker hello-world:&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%2Fmxx13j3efpvnj5nardkh.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%2Fmxx13j3efpvnj5nardkh.png" alt="Hola Mundo de Docker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With everything we've done previously, it's time to make this work "natively" in Windows through PowerShell.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker in the PowerShell console
&lt;/h2&gt;

&lt;p&gt;Now that Docker is installed, it's time to make it work in the PowerShell console. At the moment, Docker works great but in the console of our WSL.  &lt;/p&gt;

&lt;p&gt;When opening a PowerShell console we can use the following commands:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wsl docker &lt;span class="nt"&gt;--version&lt;/span&gt; 
wsl docker-compose &lt;span class="nt"&gt;--version&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%2Fpivkn7fic2oqluzwwkny.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%2Fpivkn7fic2oqluzwwkny.png" alt="Ejecución de comandos docker en la PowerShell"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea is that we can use the commands but without the wsl prefix. To do this, we need to modify the &lt;code&gt;Microsoft.PowerShell_profile.ps1&lt;/code&gt; file, but to know where to create it, we should run the following command in a PowerShell console:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$PROFILE&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%2Fdmqytugybeu3abne2civ.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%2Fdmqytugybeu3abne2civ.png" alt="Ejecucuón del comando echo $PROFILE"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the previous image, it shows a path and if you check that path, it probably won't exist. Well, we must create those folders and the file itself. Once you've done that, you should put the following text in the file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Function Start-WslDocker {
    wsl docker $args
}

Function Start-WslDockerCompose {
    wsl docker-compose $args
}

Set-Alias -Name docker -Value Start-WslDocker

Set-Alias -Name docker-compose -Value Start-WslDockerCompose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With the above, don't forget to close the PowerShell consoles and reopen them so they take the changes. And with that, we should be able to run the following Docker commands normally in the PowerShell console:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nt"&gt;--version&lt;/span&gt;
docker ps
docker-compose &lt;span class="nt"&gt;--version&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%2Frfzrupdizf8u8ug32hbk.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%2Frfzrupdizf8u8ug32hbk.png" alt="Comando de Docker en la PowerShell"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Visual managers
&lt;/h2&gt;

&lt;p&gt;If somehow you don't like managing Docker from the console, but you long for a visual manager in the style of Docker Desktop, then I have two very powerful and free solutions for both personal and business use.&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%2Ffbb8omwh5ddm163k1e59.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%2Ffbb8omwh5ddm163k1e59.png" alt="Portainer CE"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/portainer/portainer" rel="noopener noreferrer"&gt;Portainer CE (Community Edition)&lt;/a&gt; is a lightweight service delivery platform for containerized applications that facilitates the management of Docker, Swarm, Kubernetes, and ACI environments. This is an open-source project with community support, offering a free option for both businesses and personal use.&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%2Fgwjapn2yuv7t6agodbf9.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%2Fgwjapn2yuv7t6agodbf9.png" alt="Lazydocker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jesseduffield/lazydocker" rel="noopener noreferrer"&gt;Lazydocker&lt;/a&gt; is a simple terminal UI for both docker and docker-compose, written in Go with the gocui library. Its goal is to simplify Docker management, making it more accessible and less tedious for those who prefer to work from the terminal. It provides a clear overview of Docker containers, images, and volumes, allowing users to perform common actions with just a keypress or click, making it an efficient tool for both personal and business use. As an open-source project, Lazydocker is a free option that facilitates uncomplicated Docker management, making it ideal for personal and business use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final conclusions
&lt;/h2&gt;

&lt;p&gt;As you can see, the Docker CLI can be managed in Windows without the need to rely on Docker Desktop, and easily through the console.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.paulsblog.dev/how-to-install-docker-without-docker-desktop-on-windows/" rel="noopener noreferrer"&gt;How To Install Docker Without Docker Desktop On Windows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cuteprogramming.blog/2023/05/21/using-docker-and-kubernetes-without-docker-desktop-on-windows-11/" rel="noopener noreferrer"&gt;Using Docker and Kubernetes without Docker Desktop on Windows 11&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_nicolas_louis_/how-to-run-docker-on-windows-without-docker-desktop-hik"&gt;How to run docker on Windows without Docker Desktop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/wsl/install" rel="noopener noreferrer"&gt;How to install Linux on Windows with WSL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/engine/install/ubuntu/" rel="noopener noreferrer"&gt;Install Docker Engine on Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lindevs.com/install-lazydocker-on-ubuntu" rel="noopener noreferrer"&gt;Install Lazydocker on Ubuntu 22.04&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.letscloud.io/community/how-to-install-portainer" rel="noopener noreferrer"&gt;How to Install Portainer 2.0 on your Docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>containers</category>
      <category>docker</category>
      <category>tutorial</category>
      <category>windows</category>
    </item>
    <item>
      <title>Cómo instalar Docker CLI en Windows sin Docker Desktop y no morir en el intento</title>
      <dc:creator>Julian Lasso 🇨🇴</dc:creator>
      <pubDate>Tue, 19 Mar 2024 15:50:50 +0000</pubDate>
      <link>https://dev.to/julianlasso/como-instalar-docker-cli-en-windows-sin-docker-desktop-y-no-morir-en-el-intento-35kp</link>
      <guid>https://dev.to/julianlasso/como-instalar-docker-cli-en-windows-sin-docker-desktop-y-no-morir-en-el-intento-35kp</guid>
      <description>&lt;p&gt;En este post, exploraremos cómo instalar y configurar Docker CLI en Windows sin la necesidad de Docker Desktop. Aunque Docker Desktop es una herramienta conveniente y popular para manejar contenedores Docker en entornos de desarrollo, hay situaciones en las que se prefiere o se requiere una alternativa más ligera o específica. Ya sea por restricciones de licencia, necesidades de recursos mínimos o preferencias personales, instalar solo Docker CLI puede ser la solución ideal. Te guiaré a través de los pasos necesarios para configurar tu entorno Windows para usar Docker CLI, aprovechando las capacidades de WSL 2 (Subsistema de Windows para Linux versión 2) y sin la sobrecarga de Docker Desktop. Esto no solo te proporcionará un control más granular sobre tus contenedores Docker, sino que también optimizará el uso de recursos en tu máquina.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pasos Previos a la instalación
&lt;/h2&gt;

&lt;p&gt;Los siguientes pasos los he probado en Windows 10, pero supongo funcionarán igual para windows 11.&lt;/p&gt;

&lt;p&gt;Lo primero que hay que hacer es instalar el wsl y para ello abre una consola de PowerShell y escribe el siguiente comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wsl &lt;span class="nt"&gt;--install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después del paso anterior, hay que reiniciar el sistema operativo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota: Según leo, el siguiente comando hace lo mismo pero adicional reinicia el computador cuando termina de hacer la instalación necesaria.&lt;/p&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;Enable-WindowsOptionalFeature &lt;span class="nt"&gt;-Online&lt;/span&gt; &lt;span class="nt"&gt;-FeatureName&lt;/span&gt; Microsoft-Windows-Subsystem-Linux
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;Cuando el computador se haya reiniciado, se abrirá una ventana como la siguiente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2z6qvlbb51gkedjebkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2z6qvlbb51gkedjebkz.png" alt="Consola terminando de instalar linux" width="393" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Después de esperar un tiempo, saldrá un mensaje en inglés, que te dirá que introduzcas el nombre de usuario para tu usuario en linux y también pedirá la contraseña. Anota muy bien tu usuario y contraseña porque lo necesitaremos más adelante.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx0cz8vlxnnxgjizpoqi1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx0cz8vlxnnxgjizpoqi1.png" alt="Consola solicitando nombre de usuario para la distribución linux" width="800" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v8yq217z1hhimxpicfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v8yq217z1hhimxpicfb.png" alt="Consola solicitando contraseña y confirmación de la misma para nuestro usuario en linux" width="800" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una vez se haya terminado con éxito, entonces llega el momento de empezar a instalar Docker CLI y estaremos ubicados en la consola de nuestra distribución linux.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3b48np7aawtrk95clc6b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3b48np7aawtrk95clc6b.png" alt="Consola linux lista para empezar a trabajar" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota: es importante tener presente que la distribución que se instala por defecto es Ubuntu 22 al momento de escribir este tutorial.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Una vez en este punto, lo primero que hay que hacer, es actualizar los repositorios y los programas de la distribución con el siguiente comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta acción solicitará la contraseña que asignamos a nuestro usuario.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffj09j3k22ma6aspay5h3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffj09j3k22ma6aspay5h3.png" alt="Solicitud de contraseña para actualizar" width="589" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota: no olvide decir que si (tecla Y) para confirmar que se desea realizar la instalación de las actualizaciones.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Agregando el repositorio oficial de Docker CLI
&lt;/h2&gt;

&lt;p&gt;Cuando ya se termine de hacer las actualizaciones, entonces ejecutaremos el siguiente comando para realizar unas instalaciones necesarias previas a Docker CLI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;apt-transport-https ca-certificates curl gnupg lsb-release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Después ejecutaremos el siguiente comando para agregar la firma necesaria para el repositorio de Docker CLI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://download.docker.com/linux/ubuntu/gpg | &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/share/keyrings/docker-archive-keyring.gpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Llegó el momento de agregar el repositorio en Ubuntu de Docker CLI para su posterior instalación con el siguiente comando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [arch=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dpkg &lt;span class="nt"&gt;--print-architecture&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
  &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;lsb_release &lt;span class="nt"&gt;-cs&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; stable"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/docker.list &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Instalando Docker CLI
&lt;/h2&gt;

&lt;p&gt;Como ahora tenemos el repositorio de Docker CLI listo, es momento de hacer la instalación requerida con el siguiente comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este punto ya tenemos Docker CLI instalado en nuestro WSL, vamos a probarlo con los siguientes comandos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker --version
docker-compose --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deberíamos tener una respuesta similar a la de la siguiente imagen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft3oety4mky1eimg1jwr6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft3oety4mky1eimg1jwr6.png" alt="Comprobación de los comandos docker y docker-compose" width="401" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cómo hacer que Docker ejecute con el usuario normal
&lt;/h2&gt;

&lt;p&gt;Ahora vamos a crear el grupo &lt;code&gt;docker&lt;/code&gt; y agregamos nuestro usuario a dicho grupo para que nuestro usuario pueda ejecutar los contenedores sin necesidad de ejecutar los comandos como un &lt;code&gt;root&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;groupadd docker
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker &lt;span class="nv"&gt;$USER&lt;/span&gt;
newgrp docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Nota: cuando se intente crear el grupo docker, probablemente salga un mensaje que diga que el grupo ya existe, sí es así, no te preocupes, sigue adelante.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ahora lo que necesitamos hacer es iniciar Docker y comprobar su correcto funcionamiento y para ello usaremos los siguientes comandos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;service docker start
&lt;span class="nb"&gt;sudo &lt;/span&gt;service docker status
docker run hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cuando se corre el comando &lt;code&gt;sudo service docker status&lt;/code&gt; se obtiene algo como la siguiente imagen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yli1dddkhjnpq6jcp3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yli1dddkhjnpq6jcp3n.png" alt="sudo service docker status" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Para salir de esa parte, presionas la tecla Q&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cuando se usa el comando &lt;code&gt;docker run hello-world&lt;/code&gt; probablemente puedes recibir un mensaje como el de la siguiente imagen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1cyi5vrk5ycg4o0l5flg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1cyi5vrk5ycg4o0l5flg.png" alt="Error al correr el hola mundo de Docker" width="800" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No olvides correr el siguiente comando y vuelves a correr el hola mundo de Docker.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Ahora si todo ha salido bien, deberías obtener una imagen como la siguiente al correr el hola mundo de Docker.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxx13j3efpvnj5nardkh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxx13j3efpvnj5nardkh.png" alt="Hola Mundo de Docker" width="654" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Con todo lo que hemos realizado anteriormente, es momento de hacer que esto funciones de forma "nativa" en Windows a través de la PowerShell.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker bajo la consola de PowerShell
&lt;/h2&gt;

&lt;p&gt;Ahora que Docker está instalado, es momento de hacerlo funcionar en la consola de la PowerShell. En estos momentos Docker funciona muy bien pero en la consola de nuestro WSL.&lt;/p&gt;

&lt;p&gt;Al abrir una consola de PowerShell podemos usar los siguientes comandos.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpivkn7fic2oqluzwwkny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpivkn7fic2oqluzwwkny.png" alt="Ejecución de comandos docker en la PowerShell" width="426" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La idea es que podamos usar los comandos pero sin el prefijo wsl. Para hacer esto, el archivo &lt;code&gt;Microsoft.PowerShell_profile.ps1&lt;/code&gt; pero para saber dónde lo creamos, deberíamos ejecutar el siguiente comando en una consola de PowerShell&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$PROFILE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdmqytugybeu3abne2civ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdmqytugybeu3abne2civ.png" alt="Ejecucuón del comando echo $PROFILE" width="565" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como podrás observar en la imagen anterior, esta muestra una ruta y si verificas dicha ruta, probablemente no existirá, pues bien, debemos crear dichas carpetas y el archivo como tal. Una vez lo hayas realizado, deberías poner el siguiente texto en el archivo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Function Start-WslDocker {
    wsl docker $args
}

Function Start-WslDockerCompose {
    wsl docker-compose $args
}

Set-Alias -Name docker -Value Start-WslDocker

Set-Alias -Name docker-compose -Value Start-WslDockerCompose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con lo anterior, no olvide cerrar las consolas de PowerShell y volverlas a abrir para que tomen los cambios. Y con lo anterior deberíamos poder ejecutar los siguientes comandos de Docker con total normalidad en la consola PowerShell.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frfzrupdizf8u8ug32hbk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frfzrupdizf8u8ug32hbk.png" alt="Comando de Docker en la PowerShell" width="661" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Gestores visuales
&lt;/h2&gt;

&lt;p&gt;Sí de alguna forma no le gusta gestionar Docker desde consola, sino que añora un gestor visual al mejor estilo Docker Desktop, entonces le tengo dos soluciones muy poderosas y gratuitas tanto a nivel personal como a nivel empresarial.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/portainer/portainer"&gt;Portainer CE (Comunity Edition)&lt;/a&gt; es una plataforma web ligera de entrega de servicios para aplicaciones contenerizadas que facilita la gestión de Docker, Swarm, Kubernetes y entornos ACI. Este es un proyecto de código abierto y cuenta con el apoyo de la comunidad, ofreciendo una opción gratuita tanto para empresas como para uso personal.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/jesseduffield/lazydocker"&gt;Lazydocker&lt;/a&gt; es una interfaz de usuario en terminal simple tanto para docker como para docker-compose, escrita en Go con la biblioteca gocui. Su objetivo es simplificar la gestión de Docker, haciendo que sea más accesible y menos tedioso para aquellos que prefieren trabajar desde la terminal. Proporciona una visión general clara de los contenedores, imágenes y volúmenes de Docker, permitiendo a los usuarios realizar acciones comunes con solo presionar una tecla o hacer clic, lo que lo convierte en una herramienta eficiente tanto para uso personal como empresarial. Al ser un proyecto de código abierto, Lazydocker es una opción gratuita que facilita la gestión de Docker sin complicaciones, haciéndolo ideal para uso personal y empresarial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusiones finales
&lt;/h2&gt;

&lt;p&gt;Como pueden ver, Docker CLI si puede ser gestionado en Windows sin la necesidad de depender de Docker Desktop y de forma fácil y sencilla a través de la consola.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.paulsblog.dev/how-to-install-docker-without-docker-desktop-on-windows/"&gt;How To Install Docker Without Docker Desktop On Windows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cuteprogramming.blog/2023/05/21/using-docker-and-kubernetes-without-docker-desktop-on-windows-11/"&gt;Using Docker and Kubernetes without Docker Desktop on Windows 11&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_nicolas_louis_/how-to-run-docker-on-windows-without-docker-desktop-hik"&gt;How to run docker on Windows without Docker Desktop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/wsl/install"&gt;How to install Linux on Windows with WSL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/engine/install/ubuntu/"&gt;Install Docker Engine on Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lindevs.com/install-lazydocker-on-ubuntu"&gt;Install Lazydocker on Ubuntu 22.04&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.letscloud.io/community/how-to-install-portainer"&gt;How to Install Portainer 2.0 on your Docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>spanish</category>
      <category>containers</category>
      <category>docker</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Clean Architecture (Application Layer)</title>
      <dc:creator>Julian Lasso 🇨🇴</dc:creator>
      <pubDate>Tue, 26 Sep 2023 16:17:43 +0000</pubDate>
      <link>https://dev.to/julianlasso/clean-architecture-application-layer-3n1e</link>
      <guid>https://dev.to/julianlasso/clean-architecture-application-layer-3n1e</guid>
      <description>&lt;p&gt;Continuing from the previous post about &lt;a href="https://dev.to/julianlasso/clean-architecture-domain-layer-3bdd"&gt;"Clean Architecture (Domain Layer)"&lt;/a&gt;, it's the perfect time to delve deep into what the &lt;strong&gt;application layer&lt;/strong&gt; entails in this architectural context.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Does the Application Layer Entail?
&lt;/h2&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%2Fmfr2nu3hlqwayrs6yz64.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%2Fmfr2nu3hlqwayrs6yz64.png" alt="Clean Architecture Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Application Layer can be considered the epicenter of the project. As its name suggests, it's in this stratum where the application is developed in its tangible form, bringing to life the logic previously defined in the domain layer. In other words, it's the space where use cases are materialized and executed, ultimately defining the application's behavior.&lt;/p&gt;

&lt;p&gt;In this layer, I've focused on the following crucial aspects, including:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commands and Their Validators&lt;/strong&gt;: Here, commands represent the actions that can be performed within the domain. Validators play a fundamental role in ensuring that the parameters provided to these commands are correct and comply with defined rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;: The Application Layer is where the core logic of the application is concretely implemented. These use cases describe specific scenarios in which the main functionality of the application is used to achieve specific goals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Persistence&lt;/strong&gt;: Although the application is not directly connected to a database or other persistence systems at this stage, abstract classes and interfaces are defined here that the future infrastructure layer will use to manage data persistence. This ensures a smooth transition to the infrastructure layer when needed.&lt;/p&gt;

&lt;p&gt;You can find the repository for the application layer at the following link, where I have achieved 99% unit test coverage:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-application" rel="noopener noreferrer"&gt;Application Layer Repository&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure
&lt;/h2&gt;

&lt;p&gt;Here is the current structure of the domain layer:&lt;/p&gt;


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

&lt;p&gt;📦src&lt;br&gt;
 ┣ 📂commands&lt;br&gt;
 ┃ ┣ 📂inputs&lt;br&gt;
 ┃ ┃ ┣ 📜complete-to-do-command.input.ts&lt;br&gt;
 ┃ ┃ ┣ 📜create-to-do-command.input.ts&lt;br&gt;
 ┃ ┃ ┣ 📜create-user-command.input.ts&lt;br&gt;
 ┃ ┃ ┣ 📜get-all-to-dos-command.input.ts&lt;br&gt;
 ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┗ 📜login-command.input.ts&lt;br&gt;
 ┃ ┣ 📂validators&lt;br&gt;
 ┃ ┃ ┣ 📂base&lt;br&gt;
 ┃ ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┃ ┗ 📜validator.base.ts&lt;br&gt;
 ┃ ┃ ┣ 📜complete-to-do.validator.ts&lt;br&gt;
 ┃ ┃ ┣ 📜create-to-do.validator.ts&lt;br&gt;
 ┃ ┃ ┣ 📜get-all-to-dos.validator.ts&lt;br&gt;
 ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┣ 📜login.validator.ts&lt;br&gt;
 ┃ ┃ ┗ 📜new-user.validator.ts&lt;br&gt;
 ┃ ┣ 📜complete-to-do.command.ts&lt;br&gt;
 ┃ ┣ 📜create-to-do.command.ts&lt;br&gt;
 ┃ ┣ 📜get-all-to-dos.command.ts&lt;br&gt;
 ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┣ 📜login.command.ts&lt;br&gt;
 ┃ ┗ 📜new-user.command.ts&lt;br&gt;
 ┣ 📂common&lt;br&gt;
 ┃ ┣ 📂config&lt;br&gt;
 ┃ ┃ ┣ 📜app.config.ts&lt;br&gt;
 ┃ ┃ ┗ 📜index.ts&lt;br&gt;
 ┃ ┣ 📂enums&lt;br&gt;
 ┃ ┃ ┣ 📜config.enum.ts&lt;br&gt;
 ┃ ┃ ┣ 📜db-order.enum.ts&lt;br&gt;
 ┃ ┃ ┗ 📜index.ts&lt;br&gt;
 ┃ ┣ 📂exceptions&lt;br&gt;
 ┃ ┃ ┣ 📜application.exception.ts&lt;br&gt;
 ┃ ┃ ┗ 📜index.ts&lt;br&gt;
 ┃ ┣ 📂interfaces&lt;br&gt;
 ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┣ 📜jwt-data-user.intertface.ts&lt;br&gt;
 ┃ ┃ ┗ 📜query-options.interface.ts&lt;br&gt;
 ┃ ┣ 📂libs&lt;br&gt;
 ┃ ┃ ┣ 📂jwt&lt;br&gt;
 ┃ ┃ ┃ ┣ 📂interface&lt;br&gt;
 ┃ ┃ ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┃ ┃ ┣ 📜jwt-header.interface.ts&lt;br&gt;
 ┃ ┃ ┃ ┃ ┣ 📜jwt.interface.ts&lt;br&gt;
 ┃ ┃ ┃ ┃ ┗ 📜payload.interface.ts&lt;br&gt;
 ┃ ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┃ ┗ 📜jwt.lib.ts&lt;br&gt;
 ┃ ┃ ┗ 📜index.ts&lt;br&gt;
 ┃ ┗ 📜index.ts&lt;br&gt;
 ┣ 📂persistence&lt;br&gt;
 ┃ ┣ 📂exceptions&lt;br&gt;
 ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┗ 📜persistence.exception.ts&lt;br&gt;
 ┃ ┣ 📂models&lt;br&gt;
 ┃ ┃ ┣ 📂base&lt;br&gt;
 ┃ ┃ ┃ ┣ 📜document.base.ts&lt;br&gt;
 ┃ ┃ ┃ ┗ 📜index.ts&lt;br&gt;
 ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┣ 📜to-do.mode.ts&lt;br&gt;
 ┃ ┃ ┗ 📜user.mode.ts&lt;br&gt;
 ┃ ┣ 📂repositories&lt;br&gt;
 ┃ ┃ ┣ 📂base&lt;br&gt;
 ┃ ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┃ ┗ 📜repository.base.ts&lt;br&gt;
 ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┣ 📜to-dos.repository.ts&lt;br&gt;
 ┃ ┃ ┗ 📜users.repository.ts&lt;br&gt;
 ┃ ┗ 📜index.ts&lt;br&gt;
 ┣ 📂use-cases&lt;br&gt;
 ┃ ┣ 📂base&lt;br&gt;
 ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┗ 📜use-case.base.ts&lt;br&gt;
 ┃ ┣ 📜complete-to-do.use-case.ts&lt;br&gt;
 ┃ ┣ 📜create-to-do.use-case.ts&lt;br&gt;
 ┃ ┣ 📜create-user.use-case.ts&lt;br&gt;
 ┃ ┣ 📜get-all-to-dos.use-case.ts&lt;br&gt;
 ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┗ 📜login.use-case.ts&lt;br&gt;
 ┣ 📜app.ts&lt;br&gt;
 ┗ 📜index.ts&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Diagrams&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;If, for any reason, you don't wish to review the code, here are modeling diagrams for the most relevant sections.&lt;/p&gt;

&lt;h3&gt;
  
  
  Application and Use Cases
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-application/raw/main/assets/app-use-cases.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FProfeJulianLasso%2Ftodo-backend-application%2Fraw%2Fmain%2Fassets%2Fapp-use-cases.webp" alt="Application and Use Cases"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Commands, Inputs, and Validators
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-application/raw/main/assets/commands-inputs-validators-diagram.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FProfeJulianLasso%2Ftodo-backend-application%2Fraw%2Fmain%2Fassets%2Fcommands-inputs-validators-diagram.webp" alt="Commands, Inputs, and Validators"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  JWT Handling Library
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-application/raw/main/assets/lib-jwt-diagram.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FProfeJulianLasso%2Ftodo-backend-application%2Fraw%2Fmain%2Fassets%2Flib-jwt-diagram.webp" alt="JWT Handling Library"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Persistence
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-application/raw/main/assets/persistence-diagram.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FProfeJulianLasso%2Ftodo-backend-application%2Fraw%2Fmain%2Fassets%2Fpersistence-diagram.webp" alt="Persistence"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;The next step is to establish the infrastructure layer, and for that, I'll be working with NestJs, TypeOrm, and PostgreSQL. However, it's important to note that, in theory, the choice of framework, ORM, and the type of database should be transparent to the application layer.&lt;/p&gt;

&lt;p&gt;Additionally, it's important to mention that in this application layer, I have used &lt;a href="https://www.npmjs.com/package/zod" rel="noopener noreferrer"&gt;Zod&lt;/a&gt; for data validation. Ideally, and in theory, we should avoid any dependencies on external libraries. In this regard, the ideal practice would be to develop our own validation engine, an option I will consider at a later time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Words
&lt;/h2&gt;

&lt;p&gt;As always, I appreciate any doubts, questions, concerns, or contributions you may have.&lt;/p&gt;

&lt;p&gt;I am completely open to receiving any kind of feedback. Please don't hesitate to contact me; I will be delighted to hear your comments.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>architecture</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Arquitectura limpia (capa de aplicación)</title>
      <dc:creator>Julian Lasso 🇨🇴</dc:creator>
      <pubDate>Tue, 26 Sep 2023 15:57:19 +0000</pubDate>
      <link>https://dev.to/julianlasso/arquitectura-limpia-capa-de-aplicacion-5afa</link>
      <guid>https://dev.to/julianlasso/arquitectura-limpia-capa-de-aplicacion-5afa</guid>
      <description>&lt;p&gt;Dando continuidad a la publicación anterior sobre la &lt;a href="https://dev.to/julianlasso/arquitectura-limpia-capa-de-dominio-5hig"&gt;"Arquitectura Limpia (Capa de Dominio)"&lt;/a&gt;, es el momento propicio para explorar a fondo lo que conlleva la &lt;strong&gt;capa de aplicación&lt;/strong&gt; en este contexto arquitectónico.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué implica la capa de aplicación?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fN5_Ffyn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/jasontaylor.dev/wp-content/uploads/2020/01/Figure-01-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fN5_Ffyn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/jasontaylor.dev/wp-content/uploads/2020/01/Figure-01-2.png" alt="Diagrama de Arquitectura Limpia" width="531" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La Capa de Aplicación puede considerarse como el epicentro del proyecto. Tal como sugiere su nombre, es en este estrato donde se desarrolla la aplicación en su forma tangible, dando vida a la lógica previamente definida en la capa de dominio. En otras palabras, es el espacio donde se materializan los casos de uso que, en última instancia, definen el comportamiento de la aplicación.&lt;/p&gt;

&lt;p&gt;Esta capa me he centrado en los siguientes aspectos cruciales, que incluyen:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comandos y sus Validadores&lt;/strong&gt;: Aquí, los comandos representan los datos que requiere el dominio. Los validadores desempeñan un papel fundamental al verificar que los parámetros proporcionados a estos comandos sean correctos y cumplan con las reglas definidas en la lógica del dominio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Casos de Uso&lt;/strong&gt;: La presente capa es el lugar donde se implementa de manera concreta la lógica central de la aplicación. Estos casos de uso describen escenarios específicos en los que se utiliza la funcionalidad principal de la aplicación para lograr objetivos específicos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Persistencia&lt;/strong&gt;: Aunque en esta etapa la aplicación aún no se conecta directamente a una base de datos u otros sistemas de persistencia, aquí he definido las clases abstractas e interfaces que la futura capa de infraestructura utilizará para gestionar la persistencia de datos. Esto asegura una transición fluida hacia la capa de infraestructura cuando sea necesario.&lt;/p&gt;

&lt;p&gt;Puedes encontrar el repositorio de la capa de aplicación en el siguiente enlace, donde he logrado una cobertura del 99% en pruebas unitarias:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-application"&gt;https://github.com/ProfeJulianLasso/todo-backend-application&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Estructura
&lt;/h2&gt;

&lt;p&gt;Lo siguiente es la estructura actual de la capa de dominio&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📦src
 ┣ 📂commands
 ┃ ┣ 📂inputs
 ┃ ┃ ┣ 📜complete-to-do-command.input.ts
 ┃ ┃ ┣ 📜create-to-do-command.input.ts
 ┃ ┃ ┣ 📜create-user-command.input.ts
 ┃ ┃ ┣ 📜get-all-to-dos-command.input.ts
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┗ 📜login-command.input.ts
 ┃ ┣ 📂validators
 ┃ ┃ ┣ 📂base
 ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┗ 📜validator.base.ts
 ┃ ┃ ┣ 📜complete-to-do.validator.ts
 ┃ ┃ ┣ 📜create-to-do.validator.ts
 ┃ ┃ ┣ 📜get-all-to-dos.validator.ts
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┣ 📜login.validator.ts
 ┃ ┃ ┗ 📜new-user.validator.ts
 ┃ ┣ 📜complete-to-do.command.ts
 ┃ ┣ 📜create-to-do.command.ts
 ┃ ┣ 📜get-all-to-dos.command.ts
 ┃ ┣ 📜index.ts
 ┃ ┣ 📜login.command.ts
 ┃ ┗ 📜new-user.command.ts
 ┣ 📂common
 ┃ ┣ 📂config
 ┃ ┃ ┣ 📜app.config.ts
 ┃ ┃ ┗ 📜index.ts
 ┃ ┣ 📂enums
 ┃ ┃ ┣ 📜config.enum.ts
 ┃ ┃ ┣ 📜db-order.enum.ts
 ┃ ┃ ┗ 📜index.ts
 ┃ ┣ 📂exceptions
 ┃ ┃ ┣ 📜application.exception.ts
 ┃ ┃ ┗ 📜index.ts
 ┃ ┣ 📂interfaces
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┣ 📜jwt-data-user.intertface.ts
 ┃ ┃ ┗ 📜query-options.interface.ts
 ┃ ┣ 📂libs
 ┃ ┃ ┣ 📂jwt
 ┃ ┃ ┃ ┣ 📂interface
 ┃ ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┃ ┣ 📜jwt-header.interface.ts
 ┃ ┃ ┃ ┃ ┣ 📜jwt.interface.ts
 ┃ ┃ ┃ ┃ ┗ 📜payload.interface.ts
 ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┗ 📜jwt.lib.ts
 ┃ ┃ ┗ 📜index.ts
 ┃ ┗ 📜index.ts
 ┣ 📂persistence
 ┃ ┣ 📂exceptions
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┗ 📜persistence.exception.ts
 ┃ ┣ 📂models
 ┃ ┃ ┣ 📂base
 ┃ ┃ ┃ ┣ 📜document.base.ts
 ┃ ┃ ┃ ┗ 📜index.ts
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┣ 📜to-do.mode.ts
 ┃ ┃ ┗ 📜user.mode.ts
 ┃ ┣ 📂repositories
 ┃ ┃ ┣ 📂base
 ┃ ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┃ ┗ 📜repository.base.ts
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┣ 📜to-dos.repository.ts
 ┃ ┃ ┗ 📜users.repository.ts
 ┃ ┗ 📜index.ts
 ┣ 📂use-cases
 ┃ ┣ 📂base
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┗ 📜use-case.base.ts
 ┃ ┣ 📜complete-to-do.use-case.ts
 ┃ ┣ 📜create-to-do.use-case.ts
 ┃ ┣ 📜create-user.use-case.ts
 ┃ ┣ 📜get-all-to-dos.use-case.ts
 ┃ ┣ 📜index.ts
 ┃ ┗ 📜login.use-case.ts
 ┣ 📜app.ts
 ┗ 📜index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Diagramas
&lt;/h2&gt;

&lt;p&gt;Sí por alguna razón no deseas revisar el código, aquí te dejo los diagramas de modelado de los apartados más relevantes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Aplicación y casos de uso
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-application/raw/main/assets/app-use-cases.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vl4sLGTt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/ProfeJulianLasso/todo-backend-application/raw/main/assets/app-use-cases.webp" alt="Aplicación y casos de uso" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Comandos, inputs y validadores
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-application/raw/main/assets/commands-inputs-validators-diagram.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0qwL79Jd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/ProfeJulianLasso/todo-backend-application/raw/main/assets/commands-inputs-validators-diagram.webp" alt="Comandos, inputs y validadores" width="800" height="1162"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Librería para el manejo de JWT
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-application/raw/main/assets/lib-jwt-diagram.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oFB-4dJE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/ProfeJulianLasso/todo-backend-application/raw/main/assets/lib-jwt-diagram.webp" alt="Librería para el manejo de JWT" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Persistencia
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-application/raw/main/assets/persistence-diagram.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pWNLp1A_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/ProfeJulianLasso/todo-backend-application/raw/main/assets/persistence-diagram.webp" alt="Persistencia" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué hace falta?
&lt;/h2&gt;

&lt;p&gt;El próximo paso es establecer la capa de infraestructura, y para ello, trabajaré con NestJs, TypeOrm y PostgreSQL. Sin embargo, es importante destacar que, en teoría, la elección del Framework, ORM y el tipo de base de datos debería ser transparente para la capa de aplicación.&lt;/p&gt;

&lt;p&gt;Además, es importante mencionar que en esta capa de aplicación, he utilizado &lt;a href="https://www.npmjs.com/package/zod"&gt;Zod&lt;/a&gt; para la validación de datos. Idealmente, y en teoría, deberíamos evitar cualquier tipo de dependencia de bibliotecas externas. En este sentido, la práctica ideal sería desarrollar nuestro propio motor de validación, una opción que consideraré en un momento posterior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Palabras finales
&lt;/h2&gt;

&lt;p&gt;Como siempre agradezco cualquier duda, pregunta, inquietud o aporte que desees realizar.&lt;/p&gt;

&lt;p&gt;Estoy totalmente abierto a recibir cualquier tipo de retroalimentación. No dudes en contactarme, estaré encantado de recibir tus comentarios.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>typescript</category>
      <category>node</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Clean Architecture (Domain Layer)</title>
      <dc:creator>Julian Lasso 🇨🇴</dc:creator>
      <pubDate>Tue, 19 Sep 2023 17:24:35 +0000</pubDate>
      <link>https://dev.to/julianlasso/clean-architecture-domain-layer-3bdd</link>
      <guid>https://dev.to/julianlasso/clean-architecture-domain-layer-3bdd</guid>
      <description>&lt;p&gt;In this post, I want to share my approach to developing the domain layer, applying the principles I've learned from the book &lt;a href="https://a.co/d/8OOpd8d" rel="noopener noreferrer"&gt;"Clean Architecture" by Robert C. Martin&lt;/a&gt;, as well as some concepts extracted from &lt;a href="https://a.co/d/5ek8rV4" rel="noopener noreferrer"&gt;"Domain-Driven Design Distilled" by Vaughn Vernon&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Clean Architecture&lt;/th&gt;
&lt;th&gt;Domain-Driven Design Distilled&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&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%2Fnvzc5hpr19xgva13y23y.jpg" alt="Clean Architecture"&gt;&lt;/td&gt;
&lt;td&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%2Fyhpiispb0przo66b4jfw.jpg" alt="Domain-Driven Design Distilled"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For this layer, I've used my small boilerplate, which you can check out at the following link: &lt;a href="https://dev.to/julianlasso/typescript-boilerplate-l9c"&gt;https://dev.to/julianlasso/typescript-boilerplate-l9c&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's all this about?
&lt;/h2&gt;

&lt;p&gt;My current project involves developing a To-Do application with user authentication. Despite being a seemingly straightforward task, it has become a valuable opportunity to apply the knowledge I've gained about clean architecture and the application of some concepts of what is Domain-Driven Design (DDD).&lt;/p&gt;

&lt;p&gt;The project has been organized into three main layers: Domain, Application, and Infrastructure, and possibly the Presentation layer in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Domain Layer
&lt;/h2&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%2Fmfr2nu3hlqwayrs6yz64.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%2Fmfr2nu3hlqwayrs6yz64.png" alt="Clean Architecture Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the domain layer, I've focused on four key aspects:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Value Objects&lt;/strong&gt;: They represent immutable and fundamental concepts in the application's domain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entities&lt;/strong&gt;: These are objects that have a unique identity and can change over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commands and Their Validators&lt;/strong&gt;: Handling the actions that can be performed in the domain and their associated validation rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aggregates&lt;/strong&gt;: Structures that encapsulate multiple value objects and entities.&lt;/p&gt;

&lt;p&gt;I've also considered the design of interfaces for future repositories and the handling of domain layer-specific exceptions. However, I'm evaluating whether information related to repository interfaces and commands along with their validators should be placed in the application layer. Time and experience will guide me in this decision.&lt;/p&gt;

&lt;p&gt;You can find the repository for the domain layer at the following link, where I've achieved 100% unit test coverage:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-domain" rel="noopener noreferrer"&gt;https://github.com/ProfeJulianLasso/todo-backend-domain&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure
&lt;/h2&gt;

&lt;p&gt;The following is the current structure of the domain layer.&lt;/p&gt;


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

&lt;p&gt;📦src&lt;br&gt;
 ┣ 📂aggregates&lt;br&gt;
 ┃ ┣ 📂base&lt;br&gt;
 ┃ ┃ ┣ 📜aggregate.base.ts&lt;br&gt;
 ┃ ┃ ┗ 📜index.ts&lt;br&gt;
 ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┣ 📜security.aggregate.ts&lt;br&gt;
 ┃ ┗ 📜to-do.aggregate.ts&lt;br&gt;
 ┣ 📂common&lt;br&gt;
 ┃ ┣ 📂enums&lt;br&gt;
 ┃ ┃ ┗ 📜.gitkeep&lt;br&gt;
 ┃ ┣ 📂exceptions&lt;br&gt;
 ┃ ┃ ┣ 📜domain.exception.ts&lt;br&gt;
 ┃ ┃ ┗ 📜index.ts&lt;br&gt;
 ┃ ┣ 📂interfaces&lt;br&gt;
 ┃ ┃ ┣ 📜complete-to-do.interface.ts&lt;br&gt;
 ┃ ┃ ┣ 📜create-to-do.interface.ts&lt;br&gt;
 ┃ ┃ ┣ 📜create-user.interface.ts&lt;br&gt;
 ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┣ 📜to-do.interface.ts&lt;br&gt;
 ┃ ┃ ┣ 📜user.interface.ts&lt;br&gt;
 ┃ ┃ ┗ 📜value-object-exception.interface.ts&lt;br&gt;
 ┃ ┗ 📜index.ts&lt;br&gt;
 ┣ 📂entities&lt;br&gt;
 ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┣ 📜to-do.entity.ts&lt;br&gt;
 ┃ ┗ 📜user.entity.ts&lt;br&gt;
 ┣ 📂services&lt;br&gt;
 ┃ ┗ 📜.gitkeep&lt;br&gt;
 ┣ 📂value-objects&lt;br&gt;
 ┃ ┣ 📂base&lt;br&gt;
 ┃ ┃ ┣ 📜boolean-value-object.base.ts&lt;br&gt;
 ┃ ┃ ┣ 📜config-value-object.base.ts&lt;br&gt;
 ┃ ┃ ┣ 📜id-value-object.base.ts&lt;br&gt;
 ┃ ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┃ ┣ 📜string-value-object.base.ts&lt;br&gt;
 ┃ ┃ ┗ 📜value-object.base.ts&lt;br&gt;
 ┃ ┣ 📜completed.value-object.ts&lt;br&gt;
 ┃ ┣ 📜index.ts&lt;br&gt;
 ┃ ┣ 📜status.value-object.ts&lt;br&gt;
 ┃ ┣ 📜to-do-description.value-object.ts&lt;br&gt;
 ┃ ┣ 📜to-do-id.value-object.ts&lt;br&gt;
 ┃ ┣ 📜to-do-title.value-object.ts&lt;br&gt;
 ┃ ┣ 📜user-email.value-object.ts&lt;br&gt;
 ┃ ┣ 📜user-id.value-object.ts&lt;br&gt;
 ┃ ┣ 📜user-name.value-object.ts&lt;br&gt;
 ┃ ┗ 📜user-password.value-object.ts&lt;br&gt;
 ┗ 📜index.ts&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Diagrams&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;If for some reason you do not wish to review the code, here are the modeling diagrams of the most relevant sections.&lt;/p&gt;

&lt;h3&gt;
  
  
  Aggregates
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-domain/raw/main/assets/aggregates-diagram.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FProfeJulianLasso%2Ftodo-backend-domain%2Fraw%2Fmain%2Fassets%2Faggregates-diagram.webp" alt="aggregates"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Entities
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-domain/raw/main/assets/entities-diagram.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FProfeJulianLasso%2Ftodo-backend-domain%2Fraw%2Fmain%2Fassets%2Fentities-diagram.webp" alt="entities"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Value Objects
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-domain/raw/main/assets/value-objects-diagram.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FProfeJulianLasso%2Ftodo-backend-domain%2Fraw%2Fmain%2Fassets%2Fvalue-objects-diagram.webp" alt="value objects"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final words
&lt;/h2&gt;

&lt;p&gt;I appreciate any questions, doubts, concerns, or contributions you may want to make.&lt;/p&gt;

&lt;p&gt;I'm completely open to receiving any type of feedback. Please don't hesitate to contact me; I'll be delighted to receive your comments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update September 23, 2023
&lt;/h2&gt;

&lt;p&gt;Commands and their validations are passed to the application layer.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>architecture</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Arquitectura limpia (capa de dominio)</title>
      <dc:creator>Julian Lasso 🇨🇴</dc:creator>
      <pubDate>Tue, 19 Sep 2023 16:54:11 +0000</pubDate>
      <link>https://dev.to/julianlasso/arquitectura-limpia-capa-de-dominio-5hig</link>
      <guid>https://dev.to/julianlasso/arquitectura-limpia-capa-de-dominio-5hig</guid>
      <description>&lt;p&gt;En esta publicación, quiero compartir mi enfoque en el desarrollo de la capa de dominio, aplicando los principios que he aprendido del libro &lt;a href="https://www.buscalibre.com.co/libro-arquitectura-limpia/9788441539907/p/49894543"&gt;"Arquitectura Limpia" de Robert C. Martin&lt;/a&gt;, así como algunos conceptos extraídos de &lt;a href="https://www.buscalibre.com.co/libro-domain-driven-design-distilled-libro-en-ingles/9780134434421/p/48375033"&gt;"Domain-Driven Design Distilled" de Vaughn Vernon&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Arquitectura Limpia&lt;/th&gt;
&lt;th&gt;Domain-Driven Design Distilled&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xzKnYfIf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.cdn1.buscalibre.com/fit-in/360x360/8c/ac/8cac7bd25a99235d5780944823367c52.jpg" alt="Arquitectura Limpia" width="279" height="360"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PDKt4IyN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.cdn1.buscalibre.com/fit-in/360x360/c1/f3/c1f3d32c5bd101c72b2b9dcaa9aac3bb.jpg" alt="Domain-Driven Design Distilled" width="276" height="360"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Para dicha capa he usado mi pequeño boilerplate el cuál puedes encontrar en la siguiente dirección si quieres darle un vistazo: &lt;a href="https://dev.to/julianlasso/boilerplate-para-typescript-jm3"&gt;https://dev.to/julianlasso/boilerplate-para-typescript-jm3&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿De qué se trata todo esto?
&lt;/h2&gt;

&lt;p&gt;Mi proyecto actual consiste en desarrollar una aplicación To-Do con autenticación de usuarios. A pesar de ser una tarea aparentemente sencilla, se ha convertido en una oportunidad valiosa para aplicar los conocimientos que he adquirido sobre arquitectura limpia y la aplicación de algunos conceptos de lo que es Diseño Impulsado por el Dominio (DDD).&lt;/p&gt;

&lt;p&gt;El proyecto se ha organizado en tres capas principales: Dominio, Aplicación e Infraestructura, y posiblemente la capa de Presentación en el futuro.&lt;/p&gt;

&lt;h2&gt;
  
  
  La capa de dominio
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fN5_Ffyn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/jasontaylor.dev/wp-content/uploads/2020/01/Figure-01-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fN5_Ffyn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/jasontaylor.dev/wp-content/uploads/2020/01/Figure-01-2.png" alt="Clean Architecture Diagram" width="531" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En la capa de dominio, me he enfocado en cuatro aspectos clave:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Objetos de Valor&lt;/strong&gt;: Representan conceptos inmutables y fundamentales en el dominio de la aplicación.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entidades&lt;/strong&gt;: Son objetos que poseen una identidad única y pueden cambiar con el tiempo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agregadores&lt;/strong&gt;: Estructuras que encapsulan múltiples objetos de valor y entidades.&lt;/p&gt;

&lt;p&gt;También he considerado el diseño de interfaces para futuros repositorios y el manejo de excepciones específicas de la capa de dominio. Sin embargo, estoy evaluando si la información relacionada con interfaces de repositorios y los comandos junto a sus validadores debería ubicarse en la capa de aplicación. El tiempo y la experiencia me guiarán en esta decisión.&lt;/p&gt;

&lt;p&gt;Puedes encontrar el repositorio de la capa de dominio en el siguiente enlace, donde he logrado una cobertura del 100% en pruebas unitarias:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-domain"&gt;https://github.com/ProfeJulianLasso/todo-backend-domain&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Estructura
&lt;/h2&gt;

&lt;p&gt;Lo siguiente es la estructura actual de la capa de dominio&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📦src
 ┣ 📂aggregates
 ┃ ┣ 📂base
 ┃ ┃ ┣ 📜aggregate.base.ts
 ┃ ┃ ┗ 📜index.ts
 ┃ ┣ 📜index.ts
 ┃ ┣ 📜security.aggregate.ts
 ┃ ┗ 📜to-do.aggregate.ts
 ┣ 📂common
 ┃ ┣ 📂enums
 ┃ ┃ ┗ 📜.gitkeep
 ┃ ┣ 📂exceptions
 ┃ ┃ ┣ 📜domain.exception.ts
 ┃ ┃ ┗ 📜index.ts
 ┃ ┣ 📂interfaces
 ┃ ┃ ┣ 📜complete-to-do.interface.ts
 ┃ ┃ ┣ 📜create-to-do.interface.ts
 ┃ ┃ ┣ 📜create-user.interface.ts
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┣ 📜to-do.interface.ts
 ┃ ┃ ┣ 📜user.interface.ts
 ┃ ┃ ┗ 📜value-object-exception.interface.ts
 ┃ ┗ 📜index.ts
 ┣ 📂entities
 ┃ ┣ 📜index.ts
 ┃ ┣ 📜to-do.entity.ts
 ┃ ┗ 📜user.entity.ts
 ┣ 📂services
 ┃ ┗ 📜.gitkeep
 ┣ 📂value-objects
 ┃ ┣ 📂base
 ┃ ┃ ┣ 📜boolean-value-object.base.ts
 ┃ ┃ ┣ 📜config-value-object.base.ts
 ┃ ┃ ┣ 📜id-value-object.base.ts
 ┃ ┃ ┣ 📜index.ts
 ┃ ┃ ┣ 📜string-value-object.base.ts
 ┃ ┃ ┗ 📜value-object.base.ts
 ┃ ┣ 📜completed.value-object.ts
 ┃ ┣ 📜index.ts
 ┃ ┣ 📜status.value-object.ts
 ┃ ┣ 📜to-do-description.value-object.ts
 ┃ ┣ 📜to-do-id.value-object.ts
 ┃ ┣ 📜to-do-title.value-object.ts
 ┃ ┣ 📜user-email.value-object.ts
 ┃ ┣ 📜user-id.value-object.ts
 ┃ ┣ 📜user-name.value-object.ts
 ┃ ┗ 📜user-password.value-object.ts
 ┗ 📜index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Diagramas
&lt;/h2&gt;

&lt;p&gt;Sí por alguna razón no deseas revisar el código, aquí te dejo los diagramas de modelado de los apartados más relevantes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agregados
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-domain/raw/main/assets/aggregates-diagram.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ljv3hMyL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/ProfeJulianLasso/todo-backend-domain/raw/main/assets/aggregates-diagram.webp" alt="agregados" width="800" height="743"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Entidades
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-domain/raw/main/assets/entities-diagram.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KDzf76Eb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/ProfeJulianLasso/todo-backend-domain/raw/main/assets/entities-diagram.webp" alt="entidades" width="800" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Objetos de Valor
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/todo-backend-domain/raw/main/assets/value-objects-diagram.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ulz8Wy-O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/ProfeJulianLasso/todo-backend-domain/raw/main/assets/value-objects-diagram.webp" alt="validadores" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Palabras finales
&lt;/h2&gt;

&lt;p&gt;Agradezco cualquier duda, pregunta, inquietud o aporte que desees realizar.&lt;/p&gt;

&lt;p&gt;Estoy totalmente abierto a recibir cualquier tipo de retroalimentación. No dudes en contactarme, estaré encantado de recibir tus comentarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Actualización 26 de septiembre 2023
&lt;/h2&gt;

&lt;p&gt;Los comandos y sus validaciones pasan a la capa de aplicación&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>typescript</category>
      <category>node</category>
      <category>spanish</category>
    </item>
    <item>
      <title>TypeScript Boilerplate</title>
      <dc:creator>Julian Lasso 🇨🇴</dc:creator>
      <pubDate>Sun, 17 Sep 2023 13:45:19 +0000</pubDate>
      <link>https://dev.to/julianlasso/typescript-boilerplate-l9c</link>
      <guid>https://dev.to/julianlasso/typescript-boilerplate-l9c</guid>
      <description>&lt;p&gt;I present this initial entry both as a resource for my future self and as a source of interest for those who share my passion.&lt;/p&gt;

&lt;p&gt;I have created a specific repository with the purpose of establishing a solid foundation from which to start projects using TypeScript from scratch, focused on server-side development (backend).&lt;/p&gt;

&lt;p&gt;The repository in question is hosted at the following address:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/boilerplate-project-typescript"&gt;https://github.com/ProfeJulianLasso/boilerplate-project-typescript&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What does this boilerplate offer?
&lt;/h2&gt;

&lt;p&gt;The focus of this project covers four fundamental aspects:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jestjs.io/"&gt;&lt;strong&gt;Unit Testing with Jest&lt;/strong&gt;&lt;/a&gt;: The ability to perform unit tests using the powerful Jest tool has been incorporated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://eslint.org/"&gt;&lt;strong&gt;Static Code Analysis with ESLint&lt;/strong&gt;&lt;/a&gt;: The code undergoes rigorous static analysis through ESLint to ensure its quality and compliance with standards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.conventionalcommits.org/"&gt;&lt;strong&gt;Commit Management with Conventional Commits&lt;/strong&gt;&lt;/a&gt;: The Conventional Commits methodology is adopted to maintain a clear and structured record of changes with the help of &lt;a href="https://commitlint.js.org/"&gt;commitlint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://prettier.io/"&gt;&lt;strong&gt;Code Formatting with Prettier&lt;/strong&gt;&lt;/a&gt;: The code is automatically formatted with Prettier, ensuring consistency in writing style.&lt;/p&gt;

&lt;p&gt;In addition to these aspects, the repository makes use of &lt;a href="https://typicode.github.io/husky/"&gt;&lt;strong&gt;Husky&lt;/strong&gt;&lt;/a&gt; to automate certain tasks when making commits and pushing to the repository.&lt;/p&gt;

&lt;p&gt;I invite everyone interested to collaborate on this project, and I would greatly appreciate any comments or observations you can provide.&lt;/p&gt;

&lt;p&gt;This is a valuable resource for both those who want to start projects with TypeScript from scratch and those looking to improve their skills in server-side development. I am proud to share this contribution with the community, hoping that it will be beneficial for other professionals and technology enthusiasts.&lt;/p&gt;

</description>
      <category>boilerplate</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Boilerplate para TypeScript</title>
      <dc:creator>Julian Lasso 🇨🇴</dc:creator>
      <pubDate>Sat, 16 Sep 2023 19:37:43 +0000</pubDate>
      <link>https://dev.to/julianlasso/boilerplate-para-typescript-jm3</link>
      <guid>https://dev.to/julianlasso/boilerplate-para-typescript-jm3</guid>
      <description>&lt;p&gt;Esta primera entrada la presento tanto como un recurso para mi yo el futuro y como una fuente de interés para aquellos que compartan mi pasión.&lt;/p&gt;

&lt;p&gt;He creado un repositorio específico con el propósito de establecer una base sólida desde la cual iniciar proyectos utilizando TypeScript desde cero, orientados al desarrollo del lado del servidor (backend).&lt;/p&gt;

&lt;p&gt;El repositorio en cuestión se encuentra alojado en la siguiente dirección:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ProfeJulianLasso/boilerplate-project-typescript"&gt;https://github.com/ProfeJulianLasso/boilerplate-project-typescript&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué ofrece este boilerplate?
&lt;/h2&gt;

&lt;p&gt;El enfoque de este proyecto abarca cuatro aspectos fundamentales:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jestjs.io/"&gt;&lt;strong&gt;Pruebas unitarias con Jest&lt;/strong&gt;&lt;/a&gt;: Se ha incorporado la capacidad de realizar pruebas unitarias utilizando la potente herramienta Jest.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://eslint.org/"&gt;&lt;strong&gt;Análisis estático del código con ESLint&lt;/strong&gt;&lt;/a&gt;: El código se somete a un riguroso análisis estático a través de ESLint para garantizar su calidad y cumplimiento de estándares.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.conventionalcommits.org/"&gt;&lt;strong&gt;Gestión de commits bajo Conventional Commits&lt;/strong&gt;&lt;/a&gt;: Se adopta la metodología de Conventional Commits para mantener un registro de los cambios de manera clara y estructurada con la ayuda de &lt;a href="https://commitlint.js.org/"&gt;commitlint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://prettier.io/"&gt;&lt;strong&gt;Formateo del código con Prettier&lt;/strong&gt;&lt;/a&gt;: El código se formatea automáticamente con Prettier, asegurando coherencia en el estilo de escritura.&lt;/p&gt;

&lt;p&gt;Además de estos aspectos, el repositorio hace uso de &lt;a href="https://typicode.github.io/husky/"&gt;&lt;strong&gt;Husky&lt;/strong&gt;&lt;/a&gt; para automatizar ciertas tareas al realizar commits y push al repositorio.&lt;/p&gt;

&lt;p&gt;Invito a todos los interesados a colaborar en este proyecto y agradecería mucho cualquier comentario u observación que me puedan ofrecer.&lt;/p&gt;

&lt;p&gt;Este es un recurso valioso tanto para aquellos que desean iniciar proyectos con TypeScript desde cero como para quienes buscan mejorar sus habilidades en el desarrollo del lado del servidor. Me enorgullece compartir esta contribución con la comunidad, bajo la esperanza de que resulte beneficioso para otros profesionales y entusiastas de la tecnología.&lt;/p&gt;

</description>
      <category>boilerplate</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>spanish</category>
    </item>
  </channel>
</rss>
