Aprende a usar Docker — Parte 1

Aprende a empezar a utilizar Docker para crear contenedores y compartir código de forma más fácil con esta serie de tutoriales.

He visto muchas guías últimamente de Docker, pero casi la mayoría no se pone a ver detalles para iniciar con Docker, es por ello que estaré generando este post y actualizando cada que me sea posible para hacer más fácil una guía de Docker para empezar a utilizarlo.

Cabe mencionar que esta guía no usa más que imágenes de otros sitios, pero no sus contenidos, así que es única y diferente.

¿Qué es Docker?

Pero primero lo primero, ¿qué demonios es Docker?…¿unos Jeans?, sí, hay una marca de Jeans llamada Dockers (ese es su logo), pero no es eso, Docker nació de un “chiste pero es anécdota” que a muchos devs nos sucedía y que a la gente nueva le sigue sucediendo hoy en día…veamos el siguiente meme:

Bueno, alguien en algún punto pensó, esto es una realidad y empezaron a haber servicios que presidieron a Docker, sin embargo dada su dificultad, muchos no eran útiles u óptimos, por ejemplo llegué a ver que incluso había gente que recomendaba hace unos ayeres en posts cuando me iniciaba en Docker que les pasaras los “discos virtuales” que generan las máquinas virtuales como VirtualBox o VMWare, así ellos las montaban y listo, ¿pero se pusieron a pensar que la mayoría de los servicios corren en Linux sin interfaz gráfica?

Es entonces que nacen otros recursos, por ejemplo Vagrant, fue un servicio que dijo “bueno, ¿y si virtualizamos todo?” y ahí hubo un buen paso para resolver esta situación, pero Vagrant no era suficiente, era algo complejo a veces ya que dependía en ocasiones de cosas tipo VirtualBox o cambiarle el cómo virtualizaba, su configuración era muy especial, Linux vs Windows y demás cosas…es ahí donde surge Docker.

Docker es un sistema para virtualizar las cosas en contenedores de forma fácil basada en una guía descrita en un archivo llamado Dockerfile. Pero esto sigue sonando muy complicado, ¿qué demonios es Docker para mi que no sé nada de ello?

Para que entendamos Docker de forma fácil, vamos a ver un ejemplo que no es tan común, pero espero, les sirva para entenderlo.

Lo primero es la virtualización, pensemos en el viejo “libro de visitas”, donde ibas a un museo y te dejaban un libro donde ponías “Nombre — Fecha-Comentario” tipo “Está muy bonito el museo, ojalá pudieran poner más piezas” y de ahí surgió la idea de volverlo digital, y en los viejos sitios veíamos estos “libros de visitas”:

A grandes rasgos muchos dirán “esto es digitalizar”, y es correcto, sin embargo, es algo idéntico a la virtualización, al final del día la virtualización es la simulación de una cosa que normalmente ocuparía un hardware, pero dentro de un software, como en este caso nuestro libro físico se convierte en el hardware, pero ahora lo simulamos en una página web y entonces lo virtualizamos…¿se entiende?

Ahora veamos la segunda parte, ¿contenedores?. Bueno, vamos a usar en este caso un ejemplo de tés (odio los tés…pero es bueno para explicar), hay de manzanilla, de limón, de menta, de muchos sabores…¿y esto cómo se relaciona?. Bueno como sabemos cada té viene en una bolsita que a su vez viene en una caja. ¿Cierto?

Imaginemos que tenemos una caja con muchos sabores, esta caja es Docker… es donde vivirá nuestra aplicación o en este caso, los sabores de té…adentro tenemos las bolsitas de manzanilla, limón, menta, estos son los contenedores y cada bolsita como digo, tiene un sabor, entonces, esta es la aplicación.

Si lo tomamos así:

  • Caja -> Docker
  • Bolsita -> Contenedor
  • Sabor -> Aplicación

¿Esto significa que solamente puede haber un “sabor” en la bolsita?, no, ¿quizá a alguien le gusta manzanilla con limón y alguien lo vende combinado, no?, bueno, no sé si pase, pero no necesariamente, puede haber varios sabores en la bolsita, así, como puede haber varias aplicaciones en un contenedor.

docker kernel

Veamos esta imagen, ¿inglés, en serio?, creí que esto era español, sí sí, la imagen no es mía, revisa su parte inferior…pero vamos a reusar la imagen sin la información del link, si vemos hay 3 contenedores con: Tomcat+Java+Debian, SQLServer + .NET + Ubuntu, Static Binary + Alpine y un “Kernel”

El “Kernel” lo consideramos como Docker, que es donde van a correr y ejecutarse los contenedores (recuperando, la cajita de tés), cada aplicación es un sabor, Tomcat es Manzanilla, Java Limón y Debian es Menta, todos en una bolsita…

Ahora vamos a la parte técnica, supongo ya se entendió que son los contenedores…

Cada contenedor requiere de un sistema operativo, es decir, en dónde va a vivir, por ejemplo en el caso anterior hay Debian, Ubuntu y Alpine, y arriba de ellos las aplicaciones a ejecutar, esto es una regla porque, Docker, no es un sistema operativo, es un kernel, es decir, es el núcleo donde el sistema operativo descansa o se ejecuta mejor dicho, ¿qué sistema descansa realmente? 😉😉.

Ya entendimos qué son los contenedores, la virtualización y vemos que Docker es una plataforma donde se ejecutarán estos contenedores con sus aplicaciones, ¿qué sigue?. Pues bueno, ya sabemos cómo está articulado, ya podemos poner “Docker” en el curriculum y si nos preguntan ya sabemos qué es. Ahora, vamos a entender cómo iniciar a utilizarlo.

Instalando Docker

Aquí no te voy a poner cómo instalarlo, para eso existen guías oficiales y sí, en inglés, te dejo dos, Ubuntu y Windows, porque Mac y los demás, no me gustan 🙁:

Install Docker Engine on Ubuntu

Install Docker Desktop on Windows

Cabe mencionar que hasta WSL 2 (Windows Subsystem For Linux, investiga qué es, esta guía no te lo dirá …) usar Docker en Windows era una pesadilla, ahora es, hermoso…

El Dockerfile

Bueno, ya que tenemos Docker instalado, necesitamos entender cómo demonios arranca Docker.

De forma más “básica” (¿qué demonios tiene de básico la consola y tirar comandos me pregunto yo?) Docker utiliza un Dockerfile y comandos, muchos comandos con flags/banderas/opciones (o como le conozcas) para iniciar, sin embargo gracias a que los devs sabemos que muchos no nos gusta tirar tanta opción en un comando tamaño camioneta, algún dev se le ocurrió convertir las banderas en un archivo YML que ahora se le conoce como “Docker-Compose” y con este nos facilitamos más la vida, pero lo veremos más adelante.

Entonces, ¿qué es el Dockerfile?, bueno, Docker debe saber qué aplicaciones tendrá, cómo las tendrá, qué sistema operativo, todo, Docker por sí mismo no tiene idea de nada y nosotros debemos decirle qué acciones seguir. El Dockerfile es eso, los pasos que seguirá Docker para montar nuestros contenedores.

El Dockerfile inicia siempre por un FROM que nos indica qué sistema operativo va a utilizar o qué “proyecto” será el de nuestro arranque, en muuuuuuchas ocasiones veremos que dice algo como FROM node:stable o cosas así, esto se refiere a que Docker deberá ir al Hub (el Hub es un repositorio donde se tienen ya preparadas de forma profesional y bien acomodada la información y requerimientos para arrancar con una base) y entonces desde ahí pullear ya sea la aplicación base o el sistema operativo.

Cuando inicia con FROM ubuntu por ejemplo, significa que entonces arrancará con Ubuntu como base, y de ahí tú le irás indicando a Docker qué pasos deberá seguir.

Después de nuestro FROM hay palabras reservadas o clave que identifica Docker dentro de nuestro Dockerfile que deberemos ir aprendiendo, aquí solo veremos 5 y una por que siempre es bonito decir que hicimos algo y sentirnos mejor… FROM , LABEL ,RUN , EXPOSE y CMD … existen otros pero en esta parte, solo veremos estos 5.

El FROM ya sabemos qué es, el LABEL es una forma de indicarle a Docker algunas “meta informaciones” es decir, información extra ajena a todo lo interno, en este caso por ejemplo usaremos LABEL description="Este es mi poderoso Dockerfile" o LABEL author="Yo mero" . Antes se usaba MAINTAINER pero Docker decidió que esto era muy simple y no dejaba opciones a más usos, por ello lo “deprecó”. Entonces con esto pueden “embellecer” su Dockerfile con sus datos.

EXPOSE lo veremos junto a CMD antes que RUN , básicamente EXPOSE solamente “expone” uno o más puertos, por ejemplo si estamos montando un servidor web podemos usar EXPOSE 80 443 y entonces el Docker podrá recibir y “dar salida” al puerto 80 y 443. Esto es muy útil ya que la mayoría de servicios en Docker deben tener entradas y salidas de información.

Mientras que el comando CMD es idéntico a ENTRYPOINT que es otro comando pero como dije no lo veremos, y CMD solo puede haber uno y debe ir SIEMPRE al final de nuestro Dockerfile, ¿pero qué hace?, CMD ejecuta un punto de entrada, normalmente en nuestras aplicaciones como NodeJS ejecutamos un npm start y nuestra app empieza a correr, bueno, con CMD ese es el comando que le diremos que será “lo último que hará” para que arranque todo…

Es por ello que por ejemplo en este caso de Node, CMD se ejecutaría: CMD npm start y listo. Para arrancar Nginx por ejemplo: CMD nginx ¿Qué complicado no?, pero espera, ¿qué tal si queremos “opciones” en el arranque?, bueno, este comando tiene muchas opciones de uso, yo prefiero “el modo shell” por lo que así tal cual, todo a la derecha de CMD se ejecutará como si lo hicieramos nosotros por ende: CMD npm start --mi-bandera=true --algo --otracosa="si" .

Ahora viene RUN , este comando nos permite ejecutar secuencias de comandos como si nosotros fuéramos quienes escribimos esas líneas, por ejemplo en distros basadas en Debian como Ubuntu/Xubuntu/Kubuntu/Lubuntu y cuantas más “[-]Ubuntu” haya, tiramos un apt update o apt install libdevc por poner ejemplos, bueno, gracias a RUN podemos poner estos comandos, por ejemplo:

RUN apt update 
RUN apt install htop
RUN apt install nano
RUN apt install libdevc \
        wget \
        curl
RUN wget https://unaweb.com/unarchivo.zip && unzip unarchivo.zip

Y como podrás ver nos permite correr “múltiples líneas” (por el “\”) o “comandos anidados” (por el &&), cabe aclarar que esto me lo saqué de la manga, así que no creo que esté bien…pero se entiende la idea. ¿Pero qué no puede hacer RUN ? pues cosas que realmente necesiten “echar una mano de nosotros” osea si queremos editar un archivo, con RUN no podremos, tipo nano miarchivo.txt y querramos que RUN sepa que vamos a editarle X cosa no podrá peeeeeeeeeeero, claro, siempre existe un comando Linux para ello, podemos entonces copiar, mover, cambiar permisos, instalar, hacer y deshacer con comandos Linux ejecutados por RUN .

Docker-Compose

Ya entendemos qué es Docker, qué es el Dockerfile, cómo se integra uno a nivel básico, entonces, ¿qué carajos sigue?, el Docker-Compose para facilitarnos la vida…¿por qué?, bueno como mencionaba, Docker arranca con comandos, por ejemplo docker run hello-world es el “Hello world” de Docker. Pero, existen otros bien complejos como este que me topé:

docker run --name pandora_community --rm \
-p 8085:80 \
-p 41121:41121 \
-p 162:162 \
-e DBHOST=mysqlhost.local \
-e DBNAME=pandora \
-e DBUSER=pandora \
-e DBPASS=pandora \
-e DBPORT=3306 \
-e SLEEP=5 \
-e RETRIES=3 \
-e INSTANCE_NAME=pandora_community \
-ti rameijeiras/pandorafms-community:740

Y como les decía, todo esto, se puede convertir en un poderoso docker-compose y ¡baam!, banderas fáciles.

En docker-compose se usa el formato YML (yo prefiero JSON pero aquí se usa YML y no hay JSON 🙁) que básicamente interpreta espacios/tabs de forma diferente y debemos poner atención a sus “sub-ramas”, por ejemplo:

server:  
   build: ./nginx  
   links:    
      - node:node  
   ports:    
      - "80:80"
      - "443:443"
api:  
   build: ./node  
   ports:    
      - "3000"

Donde podemos tener ciertas configuraciones “replicadas”, en este caso podemos linkear varios contenedores, o agregar varios puertos (nótese que no estamos viendo “buenas prácticas”, no digan nada por el 443:443 si eres pro en Docker ya y ves eso, aunque no sé qué harías en este post pero de igual forma, lo siento, simplemente ejemplifico)

Ahora, veamos este Docker-Compose a forma “destripada”, nos dice que primeramente tendremos 2 contenedores llamados: server y api (cada contenedor por cierto puede tener su nombre, así como nuestros hijos o perritos😍)

Después le indicamos que el build o la construcción mejor dicho para nuestro contenedor se encuentra en una carpeta llamada nginx y node y dentro de cada carpeta habrá un Dockerfile con sus instrucciones a ejecutar.

Después los linkeamos no voy a explicar esto a fondo pero piensa que son 2 servidores diferentes y debes tener forma de que el servidor A pueda ver a B para conectarse, es una forma de decirlo vagamente.

Esto no quiere decir que debas hacerlo así o que si quiera se requiera, simplemente es una opción y por último ports que puede interpretarse como el puerto externo/interno que usará Docker, es decir, externamente nuestro servidor recibe por el puerto 80, pero queremos que nuestro contenedor lo procese por el 8080, por ejemplo en el caso de los ambientes de desarrollo en PHP con artisan, este, arranca por default en el 8080, entonces podríamos visitar localhost e internamente docker nos mapea el puerto al 8080, es decir, lo convierte…

Veamos entonces el comando original, aquí podemos ver -p que es 8085:80 entonces nos convierte el 8085 al 80 y es el puerto.

docker run --name pandora_community --rm \
-p 8085:80 \

En Docker-Compose nos ahorra tener que ejecutar este -p gracias al ports interno del YML.

Y entonces, una vez que ya tenemos esto, simplemente con un docker-compose se ejecuta. ¡Listo!. Aviso: el archivo siempre se debe llamar docker-compose.yml si nos queremos ahorrar una bandera, en caso de que tengamos multi-ambientes por ejemplo uno de dev y otro de QA/pre-producción, podemos llamarlos dev.yml y qa.yml y entonces, a través del comando: docker-compose -f dev.yml cambiamos a que el Docker-Compose ejecutará el archivo dev.yml en este caso.

Docker-Compose también tiene banderas propias, pero ya son menos de las que tendríamos que correr sin este y es más fácil modificar el archivo, subirlo a Git y que los nuevos containers se re-generen a través de un docker-compose que andar modificando las chorromil banderas u opciones.

¡Y eso es todo por esta parte!.

¿Qué viene en la siguiente parte?, bueno, ya sabemos como dije, qué es Docker, crear contenedores, Docker-Compose, ya tenemos nuestra base, ahora hay que ver cómo demonios le haría para meterle mi proyecto a un Contenedor y hacer algo más “real” y para ello usaremos la parte 2:

¿Cuál es tu reacción?
+1
0
+1
0
+1
0
+1
0
+1
0
Total
0
Shares
Publicación anterior

Comandos para leer archivos en Linux

Siguiente Publicación

Figma es adquirida por Adobe

Publicaciones Relacionadas