🐳 Docker para desarrolladores
Tags: docker, frontend, github, devops
Published: 2021-08-12 23:05:11

Docker es una herramienta maravillosa para desarrolladores y el concepto de empaquetar tus dependencias en un solo lugar que corre en cualquier lugar suena casi utóṕico.

## En este artículo aprenderás

1. Cómo leer un Dockerfile
2. Problemas comunes al correr tu Dockerfile
3. Analizar Dockerfile de una SPA
4. Cómo construir tus propios dockerfile
5. Keywords básicas sobre los Dockerfile
6. Qué es alpine y porqué es usado
7. Donde buscar imágenes para tus contenedores

Usaré un ejemplo para que podamos entender mejor el funcionamiento de un Dockerfile, un ejemplo para una aplicación de react

```docker

FROM node:current-alpine3.14

WORKDIR /usr/src/app

COPY package.json /app

COPY . .

RUN npm set progress=false && npm install

EXPOSE 8086

CMD ["npm", "run", "storybook"]

```

Si empleamos la similitud entre un contenedor de esos que los barcos transportan y los docker lo podemos entender de una manera mucho más sencilla y práctica.

Es verdad que dentro de un contenedor puedes meter una cantidad exacta de mercancía, pero de diferentes tipos y estos poseen un tamaño específico para que sean fáciles de identificar y de llevar por los barcos.

En docker funciona de forma similar, solo que nuestra mercancía es nuestra aplicación y las reglas son las siguientes.

De manera práctica nos encontraremos con 

## FROM

```docker
FROM node:current-alpine3.14
```

Esto significa que se genera un contenedor a partir de una **imagen**, podemos pensar en ella como un molde que es la primera capa de nuestro contenedor. Ella tendrá configuraciones específicas que servirán para correr los comandos consecuentes, puedes ver que uso node:current-alpine3.14

Esta imagen la encuentro en la página de [docker hub](https://hub.docker.com/_/node), que podemos pensar en ella como un repositorio de imágenes, comúnmente buscarás **imágenes oficiales** (estas tienen un símbolo de imagen oficial a lado del nombre). 

En docker funciona de forma similar, solo que nuestra mercancía es nuestra aplicación y las reglas son las siguientes.

Ahora conocemos que esto de node:current-alpine3.14 es el nombre completo de la imagen que usamos como base, pero ¿Qué es alpine? Alpine es el sistema operativo (basado en linux) de nuestra imagen. Este nombre es famoso porque representa una imagen con un peso mínimo de mega bytes , y esto se busca para que tu contenedor final no pese mucho, ya que no conviene mucho tener tu aplicación de 50mb y que tu imagen base pese 250 mb.

## Workdir

```docker
WORKDIR /usr/src/app
```

El WORKDIR indica el directorio de trabajo, nos referimos a el como un directorio que se crea dentro del contenedor que se usará como base para correr los comandos consecuentes.

Entonces conocemos que el workdir se refiere más a nuestro contenedor que a tu aplicación por eso verás que en muchos lugares se le conoce como /app, si tu aplicación usa sus archivos en src/, nada de preocupaciones, recuerda que se habla del contenedor y no tanto de tu aplicación, esto vendrá en los próximos comandos.

## COPY

```docker
COPY package.json /app

COPY . .
```

Los comandos COPY, hacen honor a su nombre de copiar los archivos de tu aplicación a la del contenedor /app.

Primero copiamos el package.json porque de allí correremos comandos npm.

Luego empleamos el COPY . . 

Admito que esto no es muy explicativo pero básicamente es copiar lo de tu directorio al directorio de trabajo (WORKDIR) el que ya habíamos específicado anteriormente. 

Podríamos traducir a COPY . /app

El WORKDIR indica el directorio de trabajo, nos referimos a el como un directorio que se crea dentro del contenedor que se usará como base para correr los comandos consecuentes.

## RUN

```docker
RUN npm set progress=false && npm install
```

Este puede aparecer bastante en el desarrollo de una aplicación, y hace lo que su nombre, corre en tu contenedor lo que le pongas a su izquierda así de simple.

Usualmente cuando agarras una aplicación , lo primero que haces es instalar las dependencias porque sino la aplicación no corre, esto es un clásico. Bueno en docker sucede similar, corre el npm install que harías normalmente. Sobre el set progress=false es para que no meustre la barra de progreso al instalar dependencias , el && une comandos por lo que le coloco npm install.

## EXPOSE

```docker
EXPOSE 8086
```

EXPOSE sirve para decir que el puerto que tu contenedor usará. 

Aquí está el dilema y es que colocarlo no hará efecto a la hora de correr el contenedor, entonces esto sirve más de documentación. Lee sobre como correr un contenedor

En mi opinión está bien colocarlo porque la documentación es muy importante pero es bueno tener en cuenta que su utilidad es esa y a la hora de correrlo no esperar que abra en ese puerto por defecto.

## CMD

```docker
CMD ["npm", "run", "storybook"]
```

CMD es la consola que corre el comando que coloques entre sus corchetes, esto sucederá cuando se termine de correr el contenedor.

Quizá al final de la construcción de la imagen no se ejecute pero su función se realizará al final de correr el contenedor y no la construcción.

## Recapitulando

```docker

# Usar una imagen  
FROM node:current-alpine3.14

# Establecer el directorio de trabajo de nuestro contenedor
WORKDIR /usr/src/app

# Copiar el package.json a la carpeta /app de nuestro contenedor
COPY package.json /app

# Copiará otros archivos de la aplicación
COPY . .

# Ejecutar el comando npm set progress=false && npm install
RUN npm set progress=false && npm install

# Exponer el puerto 8086 de el contenedor docker, fin de documentación
EXPOSE 8086

# Correrá este comando al final cuando se esté corriendo el contenedor
CMD ["npm", "run", "storybook"]
```

## Finalizando

Al final de todo esto recuerda que puedes ejecutar el comando `docker build -t aplicacion-docker .`

`-t` significa que colocarás un tag que vendría a ser un nombre, aquí no puedes usar letras mayúsculas así que separo con un guión.

El `.` al final significa que buscará dentro de la carpeta un Dockerfile y lo leerá para crear una imagen a partir de las instrucciones, si abres la terminal desde otra carpeta y quieres correr el comando debes sustituir ese punto con la ubicación de el Dockerfile, lo mismo sucede si tienes más de un Dockerfile en tu aplicación pero esto es algo que no suele suceder.

También quiero destacar que tu archivo se debe llamar Dockerfile, si le llamas DockerFile, u otro nombre te mandará error, este es un error frecuente también, recuerda Dockerfile.