Disclaimer
En este post se va a hablar SOLO de docker, desde mi opinion personal docker a la actualidad (solo docker sin docker compose). No tiene una utilidad practica por lo que este articulo sera meramente teorico, tendra muchos ejemplos y lineas de comandos que se usan para interactuar con Docker Engine (el motor de docker)
Si deseas usar docker de manera profesional debes entender conceptos basicos explicados en este post y luego dirigirte a cualquiera de los siguientes articulos
docker LAMP
Docker LEMP
Docker MERN
Docker con github
Docker con CI CD
Buenas practicas de Docker Compose
¿Que es docker?
Hay muchos significados para docker
Es un Runtime (Un runtime environment carga todas las aplicaciones de un programa y las ejecuta en una plataforma)
es un sistema operativo basado en contenedores
Docker es una plataforma de software que le permite crear, probar e implementar aplicaciones rápidamente (sitio oficial)
Docker es un proyecto de código abierto que automatiza el despliegue de aplicaciones dentro de contenedores de software( WikiPedia)
¿Para que nos sirve docker?
- Tener un unico entorno de tu aplicacion que funcione en todas las maquinas
- Desplegar aplicaciones
- Hacer procesos repetitivos de manera automatica
- que tu equipo de trabajo tenga una sola version de tu proyecto
- Proteger tu aplicacion de conexiones externas y solo dejas las autorizadas
¿Como se instala?
- Docker se instala de varias maneras. Si deseas que haga un tutorial de como instalarlo y optimizarlo en los distintos sistema operativo dejamelo en la seccion de comentarios, sin embargo hare un resumen de como se instala
En linux
- Se purga cualquier indicio de docker
sudo apt-get remove docker docker-engine docker.io containerd runc
despues "oficialmente" hay 4 maneras de instalarlo
- Instalando docker desktop for linux (para principiantes)
- Instalando Docker desde los repositorios apt (intermedio)
- Instalandolo de manera manual y cuando tu decidas actualizarlo de esa manera tambien (para usuarios avanzados) https://docs.docker.com/engine/install/ubuntu/#install-from-a-package
Usando un script de instalacion que se encuentra en el repositorio oficial de docker (recomendado para propositos de prueba y desarrollo de entornos)
Windows
- se requiere WSL (Subsistema de Windows para Linux) , Virtualizacion y windows PRO
- aqui puedes bajar el instalador y sigues el asistente de instalacion
- https://docs.docker.com/desktop/install/windows-install/
Mac
- En el enlace se encuentran las instrucciones https://docs.docker.com/desktop/install/mac-install/
Nuestro Hola Mundo en Docker
En windows se recomienda reiniciar una vez instalado
Abrimos nuestro Docker desktop

Puede tardar un poco la primera vez .

Una vez iniciado ya podemos abrir cualquier consola y usar docker desde la linea de comandos y usar los comandos de docker
Comandos utiles al final del post

el comando clasico solo para ver la version de docker que tenemos instalada en tu computador
docker --version
Deberia darte algo como

Vamos a ejecutar el siguiente comando para correr la imagen «hola mundo»
docker run hello-world
Aqui Vamos a ver Varias cosas interesantes

- Se ejecuta el comando
- Indica que la imagen no la pudo encontrar por lo tanto la va a busar en los repositorios
- Baja la imagen de library/hello-world
- la imagen ya fue descargada e indica su ID Unico (2db29710123e) tambien muestra el fingerprint y el status (esto sera importante para identificar problemas de internet mas adelante)
- el mensaje de hello world indica que todo esta funcionando correctamente
- Te indica los pasos que sucedieron internamente en docker
- contacta el motor de docker
- busca la imagen en tus repositorios locales
- si encuentra la imagen crea un contenedor
- si no la encuentra la descarga, busca la mejor opcion disponible basado en la etiqueta que usaste en este caso no usamos etiquetas y por defecto uso :latest (ultima version)
- Ejecuta el comando que tenga la imagen por defecto
- el motor de docker muestra el resultado
- te invita a descargar una imagen que tiene mas caracteristicas, ubuntu
- te invita a crear tu propia imagen, para compartirlas y hacer automatizaciones en hub.docker.com
Instalando Ubuntu con docker
Ejecutamos el siguiente comando:
docker run ubuntu
Si es la primera vez que lo ejecutamos la va a descargar, creara el contenedor y se ejecutara

Nota: si ya esta en nuestros repositorios la imagen y estamos en Windows es probable que no te retorne ningun mensaje pero si crea el contenedor


Sin embargo, hay un detalle importante el contenedor no queda encendido, se apaga apenas ejecuta su rutina, esto sucede porque el contenedor por defecto tiene un ciclo de vida y se apaga hay una forma de mantenerlo encendido.
docker run --name ubuntu-keep-on -d ubuntu tail -f /dev/null
Analicemos este comando, hicimos uso de dos flags -d y –name y al final
Entre «docker run » ubuntu (nombre de la imagen) podemos usar flags (para mas informacion podemos hacer uso del comando «docker run –help» y ver las etiquetas disponibles
–name = indica el nombre del contenedor que va a tener en este caso ubuntu-keep-on
-d es una version corta para –detach el comando correra en segundo plano (background), sin esta bandera la consola no se va a poder usar y vamos a requerir usar otra
luego indicamos el nombre de la imagen en este caso ubuntu, seguido del comando tail de linux
El comando tail permite leer las partes finales de un archivo y se queda a la «escucha» de nuevos cambios de ese archivo.
Veremos en nuestro docker desktop con dos contenedores uno apagado y otro encendido,

este contenedor «ubuntu-keep-on» podemos acceder desde la consola.
Accediendo a nuestro contenedor de ubuntu
Podemos acceder a la consola de varias maneras sin embargo destacaremos 3 formas:
Docker Desktop, (funciona solo si esta encendido el contenedor)



2. Consola
docker exec -it (nombre del contenedor o su ID) bash
Nota: la etiqueta «-it» indica modo interactivo

Evaluemos estos comandos ejecutados en consola
- docker ps : muestra todos los contenedores activos, si usamos la bandera «-a» (all) mostrara todos los contenedores creados/ejecutadonse
- docker exec: corre un comando dentro de un contenedor (para mas informacion ejecutar «docker exec –help»)
- podemos ver que el comando docker exec funciona tanto con el nombre como con el CONTAINER ID
- exit: es para salir de la consola
3. Desde Visual Studio Code (mi favorita)
Desde Visual Studio Code podemos descargar un complemento oficial de microsoft llamado «docker«

Desde ella podemos manejar todas las funcionalidades de Docker, y en tres simples clicks abrir nuestra consola

Notese que el comando que usa es el indicado en la forma 2, con la unica diferencia que usa el ID del contenedor en su version larga

Si queremos detener el contenedor, podemos hacerlo a traves de docker desktop, desde la extension de visual studio code y tambien haciendo uso del comando
docker stop (nombre del contenedor o su ID)
Networking en docker (biding de puertos)
Hasta el momento solo hemos podido usar los contenedores dentro del «entorno de docker», no podemos conectarnos de manera externa, este articulo esta enfocado en aprender docker para el desarrollo de aplicaciones y servidores web por lo que usaremos Nginx
Vamos a instalar un servidor Ngnix para poder usarlo como servidor web
docker run -d --name proxy ngnix

en el apartado PORTS, vemos que esta en el puerto 80, pero no podemos acceder a el desde el navegador porque no hay un «binding» establecido

para poder exponer el puerto, debemos usar la flag «-p 7070:80«, donde el 7070 es el puerto punto de conexion en tu entorno local y el 80 es el puerto que vimos arriba en la imagen
representado de esta manera
quedando 7070 -> 80
Vamos a parar el contenedor
docker stop proxy
luego lo vamos a eliminamos
docker rm proxy
si queremos pararlo y eliminarlo a la vez podemos hacer uso del comando
docker rm -f proxy
ahora vamos a usar el siguiente comando para exponer el puerto y poder ver nuestro servidor Nginx en el navegador
docker run -d --name proxy -p 7070:80 nginx
ya podemos verlo, PERO no podemos hacer uso de archivos externos porque no hemos hecho el «binding» de volumenes lo veremos en la siguiente parte

Manejo (archivos) de datos de docker
Existen dos formas manejar archivos en docker
Bind Mount
Docker genera internamente sus archivos necesarios para funcionar pero no tenemos una forma facil de comunicarnos con el exterior con esos archivos, para ello debemos «bindear» usando la flag -v y usando el mismo esquema mencionado anteriormente
-v (directorio local) : (directorio contenedor)
Eliminamos el contenedor con
docker rm -f proxy
volvemos a crear el contenedor con la flag -v navegamos a traves de consola al directorio donde el archivo que queremos mostrar en nuestro servidor Nginx
docker run -d --name nginx_public -v ${PWD}:/usr/share/nginx/html:ro -p 80:80 nginx
Detalles del comando
${PWD} = variable de entorno para directorio actual (Print Working Directory)
:ro = al final del volumen indica que el volumen sera de solo lectura (read only) esto es opcional no afecta el funcionamiento para este caso en particular
En caso de Nginx, por defecto los archivos se /usr/share/nginx/html y lo que hacemos es crear un «puente» entre nuestra carpeta donde ejecutamos el comando y la carpeta /usr/share/nginx/html internamente en nuestro contenedor

En nuestro navegador ya podemos acceder y modificar libremente este archivo html desde Visual Studio Code

En nuestro navegador ya podemos acceder y modificar libremente este archivo html,
Hay que tener en cuenta que esta forma deja expuestos nuestros archivos fuera de docker y por ello problemas de seguridad
Ahora veremos la segunda forma ideal para produccion y tener un mejor resguardo de nuestros archivos.
Creando volumenes internamente (ideal para producción)
Un volumen es donde docker guarda los archivos, cada vez que creamos un contenedor, este crea un volumen.
Cada vez que creamos un contenedor este crea un volumen
Vamos a ver una lista de los volumenes que tenemos usando el siguiente comando.
docker volume ls

Veremos una lista de los contenedores, con letras y numeros al azar. estos son creados automaticamente cuando creamos cada contenedor
podemos eliminar los volumenes que no usamos con el comando, para liberar espacio en disco
docker volume prune

te preguntara que si estas seguro de eliminarlos, presionamos la tecla y y enter, luego te dice que volumenes se borraron y cuanto espacio de nuestro disco fue liberado,
tambien podemos darle nombres a nuestro volumen con el siguiente comando:
docker volume create my_new_volume

Veamos las caracteristicas de este volumen con el comando
docker volume inspect my_new_volume

Vemos cosas como la fecha de creacion, el tipo de driver, las etiquetas, el punto de montura.
podemos eliminar el volumen que hemos creado con el comando
docker volume rm my_new_volume
Vamos a crear un contendor con Nginx y un volumen llamado www, alli durante la creacion a copiar nuestros archivo a la carpeta html.
docker run -d --name db --mount src=wwwdata,dst=/usr/share/nginx/html -p 80:80 nginx
Copiando y extrayendo archivos en volumenes
Que archivo quiero copiar
Docker cp www/index.html nombredelcontenedor:/
no requiere que el contenedor este corriendo (esto nos sirve para arreglar problemas en produccion sin destruir la maquina)
TMPFS Mount: Guarda los archivos temporalmente y persiste los datos en la memoria del contenedor, cuando muera sus datos mueren con el contenedor.