---
title: Docker básico: Docker Desktop y objetos Docker
url: https://jarroba.com/docker-basico-docker-desktop-y-objetos-docker/
author: Ramón Invarato
date: 2024-03-17
modified: 2026-10-21
language: es
license: CC BY-NC-SA 3.0 (https://creativecommons.org/licenses/by-nc-sa/3.0/) — attribution: "Docker básico: Docker Desktop y objetos Docker", Ramón Invarato, jarroba.com
categories: Ingeniería del Software, Lenguajes de Programación
tags: Bind Mount Docker, docker, Docker Application, Docker Architecture, Docker CLI, Docker Command, Docker Compose, Docker Configuration, Docker Container, Docker Daemon, Docker Deployment, docker desktop, Docker Development, Docker Engine, Docker Environment, Docker Hub, Docker Image, Docker Infrastructure, Docker Installation, Docker Integration, Docker Kubernetes, Docker Network, Docker Platform, Docker Portability, Docker Registry, Docker Resources, Docker Run, Docker Runtime, Docker Service, Docker Volume, Dockerfile, Imagen Docker, Kubernetes, Volumen Docker
series: Docker (part 1 of 6)
---

# Docker básico: Docker Desktop y objetos Docker

> Curso gratuito y completo sobre Docker. Docker es una plataforma para construir, desplegar y ejecutar aplicaciones en contenedores.

Quiero ofrecerte lo más completo que me sea posible sobre **Docker** y sus grandes posibilidades, así como varias de sus herramientas (como **Docker Desktop, Docker Engine, Docker Daemon, Docker Compose**, hasta **Kubernetes**) de lo más básico a lo más avanzado.

 

**Cualquier persona** con unos conocimientos mínimos de informática **puede usar imágenes Docker** y hoy día recomendaría a todo el mundo que aprenda sobre Docker, pues ofrece muchos beneficios y uno de los más básicos es el poder aprender en casa de manera práctica prácticamente cualquier tecnología actual que quieras (desde tecnologías más comunes como bases de datos o servidores, hasta poder llegar a tecnologías empresariales de Big Data y Cloud gratis, si así lo deseas y tienes ganas); otro beneficio sería entender por completo las abstracciones informáticas, si no tienes la suerte de que alguien te lo explique; entre otros beneficios adicionales que detallaré.

 

Si no tienes pocos o ningún conocimiento sobre Docker, recomiendo leer este artículo como el primero; no obstante, si ya te has pegado con Docker, no es necesario leer estos artículos en orden si ya sabes algo, pudiendo ir directamente al artículo que te interese según tus conocimientos y perfil:

 
- **Para todos**(este artículo): teoría básica y usar Docker sin comandos, ejecutar imágenes ya construidas con Docker Desktop.
- **Desarrolladores**: teoría avanzada con comandos, uso de Docker Compose, construcción de imágenes con Dockerfile y nos centraremos en la creación de microservicios Dockerizados.
- **Sistemas**: Kubernetes, repositorios y desplegar proyectos Dockerizados.

 

Este primer artículo quiero que sea muy rápido (pese a todo lo que tiene Docker que ofrecer) y que puedas entender y usar Docker enseguida, sin usar ningún comando en absoluto; por lo que voy a mezclar la teoría con el uso real de Docker para que lo entiendas de la manera más sencilla y que puedas valerte por ti mismo (la teoría estrictamente técnica ya está perfectamente explicada en la web de documentación oficial de Docker: [Docker Docs](https://docs.docker.com/) ).

 

 

## Beneficios de Docker

 

Pero primero he de indicarte las **bondades de Docker**(y no me pagan nada por ello), pues hoy día la mejor manera de aprender sobre cualquier software técnico es usar Docker y, encima, aprenderás cómo se trabaja en una empresa moderna.

 

Solo con saber cómo se utilizan las **imágenes preconstruidas** de Docker te va a abrir un montón de puertas sin necesidad de tener apenas conocimientos, por ejemplo, así se me ocurren:

 
- ¿Quieres **aprender SQL o tener tu propia base de datos**en un momento? Pues, en cuestión de segundos y sin instalar nada, podrás usar cualquier base de datos que te imagines (MySQL, PostgreSQL, Cassandra, MongoDB, Neo4j, etc.) y practicar gratis desde tu casa.
- Que en la universidad estás practicando **MapReduce mediante Streaming** con **Spark** o con **Flink**, pero lo haces todo en local con Python o Java bajo esa sensación agridulce de que te falta por aprender cómo se trabaja en un entorno de verdad, pues montas una imagen y ya lo tienes simulado como si estuviera desplegado sobre un servidor empresarial ¿Qué quieres ver cómo funciona en un sistema multi-nodo? Pues copia y pega para desplegar más.
- ¿Necesitas entender cómo funcionan las **colas de mensajería**? Pues en un momento tendrás montado un **Kafka**o un**RabbitMQ** completamente funcional, hasta podrás ponerle conectores (como Debezium, por ejemplo).
- ¿Tienes **código Java, Python, PHP, Ruby, Go, etc**. o cualquiera que se te ocurra, pero no sabes o no tiene ganas de instalar el compilador en tu ordenador? No pasa nada, en unos segundos los tendrás ejecutando sin tener que instalar nada en tu ordenador.
- Que estás practicando con microservicios desplegados en **servidores**, pues sin instalar nada, monta un **Tomcat, Jetty, Httpd, Node.js, Django, etc**. en un momento completamente funcional.
- ¿Quieres aprender sobre la tecnología más avanzada de **Big Data** y/o **IA** a bajo nivel? Pues instala lo que quieras y aprende como un profesional que lo utiliza en una empresa real; por ejemplo, podrías usar: **ElasticSearch con Kibana, Druid, Hbase, etc.**
- ¿Requieres probar herramientas de **visualización de datos** en tu sistema? Pues adelante: **Grafana**, **Prometheus**, **Superset**, etc.
- Si eres desarrollador sabrás lo que es un “entorno de desarrollo” (otros entornos son integración, producción, etc.) y que a veces puede ser un poco desconcertante el nivel de abstracción que puede tener; pues qué pasa si te digo que entre el proyecto que programas en local y el “entorno de desarrollo” existe otro “entorno intermedio” que simula todo el **“entorno de desarrollo” dándote una visibilidad absoluta de todo cuanto ocurre, pero en local, siempre limpio y bajo tu control**. Habrás adivinado que se puede hacer con Docker.

 

Aparte de todo lo que se puede hacer a nivel de uso, también te cuento sus ventajas técnicas:

 
- **Se descentralizan los fallos:** Si un contenedor falla, no afectará a otros contenedores que se ejecutan en el mismo sistema.
- **Se independizan las dependencias y las versiones**: cada contenedor tiene sus propias dependencias y versiones, por lo que no se pisan entre sí (por ejemplo, si en nuestro ordenador primero instalamos Java 17, su instalador sobrescribirá la variable de entorno JAVA_HOME, pero luego, si instalamos Java 8 porque lo necesitamos para código viejo, éste también sobrescribirá la variable JAVA_HOME, por lo que el código nuevo que se ejecute en Java 17 dejará de funcionar; en Docker podremos tener un contenedor con Java 8 y otro con Java 17, cada uno con su código compatible).

 

 

## ¿Qué es Docker?

 

Todas las anteriores ventajas son de cosecha propia y como efecto secundario de para qué sirve realmente Docker. Pues realmente **Docker es una plataforma para construir, desplegar y ejecutar aplicaciones** (imágenes Docker)**en contenedores**(donde se ejecuta una instancia de una imagen).

 

No me extiendo más, pues la definición de Docker se aprende haciendo, así que empecemos por lo más básico (y ya lo más básico, que es el utilizar “imágenes Docker preconstruidas” que te mencioné antes, te proporcionará un montón de posibilidades).

 

 

## Instalar Docker

 

De Docker lo más importante es **“Docker CLI” que nos permitirá interactuar con el motor de Docker** (“Docker Engine”). Para tenerlo instalado en nuestro ordenador, podremos elegir entre una de las dos maneras siguientes, ELIGE UNA, aunque si estás empezando con Docker te recomiendo **“Docker Desktop”** (a continuación, te comentaré un montón de nombres que te pueden sonar raros, no te preocupes, los vamos a ir viendo y entendiendo):

 
- **“Docker CE”** (Docker Community Edition; open source y gratis)**:**Incluye “Docker Engine”, “Docker CLI”, “Docker Daemon”, “Docker Build” y “Docker Compose” (entre otros, que iremos viendo algunos en este artículo y otros en [el siguiente artículo](https://jarroba.com/docker-compose/)).
- **“Docker Desktop”**(también gratis): Incluye “Docker CE” (todo lo anterior), más una interfaz de usuario y Kubernetes local.

 

[![Diagrama de la arquitectura de Docker: Docker Desktop con Docker CE y consola sobre Docker Engine y el hardware](https://jarroba.com/wp-content/uploads/2024/03/Arquitctura-Docker-www.jarroba.com_-1024x727.png)](https://jarroba.com/wp-content/uploads/2024/03/Arquitctura-Docker-www.jarroba.com_.png)

 

Lo más sencillo es **instalar “Docker Desktop”**, pero solo está disponible para Windows, Mac y ciertos sistemas Linux. Se puede descargar gratis desde: [Get Started (Docker)](https://www.docker.com/get-started/)

 

[![Captura de la web Get Started de Docker con los botones de descarga para Windows, Mac y Linux resaltados](https://jarroba.com/wp-content/uploads/2024/03/DescargarDocker-www.jarroba.com_-1024x319.png)](https://jarroba.com/wp-content/uploads/2024/03/DescargarDocker-www.jarroba.com_.png)

 

Consejo

 

### ****Si usas Windows****

 

Docker funciona muy bien sobre Linux, por ello, cuando se indique durante la instalación que se elija entre Hyper-V y WSL 2, recomiendo **usar WSL 2**(de primeras no necesitarás conocer nada más sobre WSL 2, pero para temas avanzados sí lo necesitarás y será mejor trabajar sobre Linux, esto es WSL 2, puesto que la mayoría de los sistemas Docker empresariales están montados sobre Linux).

 

WSL 2 NO está habilitado por defecto en Windows. Para **habilitar rápidamente WSL 2**, buscar en Windows “**Activar o desactivar las características de Windows**” y en la ventana que se abre habilitar “**Subsistema de Windows para Linux**”, aceptar y reiniciar el ordenador.

 

[![Captura de Windows buscando «características de Windows» y activando Subsistema de Windows para Linux](https://jarroba.com/wp-content/uploads/2024/03/habilitar-caracteristicas-de-windows-subsistema-linux-para-windows-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/habilitar-caracteristicas-de-windows-subsistema-linux-para-windows-www.jarroba.com_.png)

 

Y en la “**Microsoft Store**” ya podremos instalar la distribución Linux que queramos. Para empezar, recomiendo “**Ubuntu**”.

 

[![Captura de Microsoft Store con la página de Ubuntu y el botón Obtener resaltado](https://jarroba.com/wp-content/uploads/2024/03/Descargar-Ubuntu-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/Descargar-Ubuntu-www.jarroba.com_.png)

 

Una vez instalado lo abrimos y seguimos los pasos para terminar de configurarlo, que realmente será **añadir un usuario de root y una contraseña** (memorízala o anótala, porque puede que la necesites).

 

Si ya tenías instalado WSL 2, recomiendo actualizarlo ejecutando en la línea de comandos de Windows el comando:

 

```bash
wsl --update
```

 

**Nota si tienes problemas con la instalación de WSL 2:** tienes información más completa sobre cómo habilitar WSL 2 en: [Instalación de Linux en Windows con WSL (Microsoft Learn)](https://learn.microsoft.com/es-es/windows/wsl/install)

 

Cuando **descarguemos el instalador, lo ejecutamos** y comenzará el proceso de instalación, seguimos los pasos hasta el final.

 

[![Captura del instalador de Docker Desktop con las opciones de usar WSL 2 y crear acceso directo marcadas](https://jarroba.com/wp-content/uploads/2024/03/DockerDesktopInstalacion-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/DockerDesktopInstalacion-www.jarroba.com_.png)

 

Cuando termine la instalación, nos pedirá **reiniciar el ordenador**.

 

Y cuando reinicie, iniciaremos Docker. Quizás se nos abra la siguiente ventana para terminar de configurar Docker, elegir “Use recommend settings” y terminamos:

 

[![Captura de Docker Desktop terminando la configuración con la opción de ajustes recomendados y Finish resaltados](https://jarroba.com/wp-content/uploads/2024/03/Completar-instalacion-Docker-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/Completar-instalacion-Docker-www.jarroba.com_.png)

 

Nota

 

### Instalar “Docker CE”

 

Puede que por alguna razón no podamos instalar “Docker Desktop” y necesitemos instalar “Docker CE”, por lo que [te lo explico en el siguiente artículo](https://jarroba.com/docker-compose/). Luego puedes volver a éste para leer la teoría básica, pero no podrás usar la interfaz gráfica, puesto que no tiene, aunque en el siguiente artículo aprenderás lo mismo, pero desde comandos.

 

 

## Iniciar “Docker Desktop”

 

Ejecutamos “Docker Desktop” (En Windows doble clic al acceso directo) y se nos abrirá una ventana con el programa. Lo primero que veremos es que si queremos registrarnos (“Sign up”), podemos hacerlo o no (“continue without signing in”), como veamos; aunque recomiendo registrarse para poder acceder a la “Docker Hub” desde esta aplicación.

 

[![Captura de la bienvenida de Docker Desktop con las opciones Sign up, Sign in y continuar sin iniciar sesión](https://jarroba.com/wp-content/uploads/2024/03/Docker-Desktop-Primer-uso-y-sign-up-www.jarroba.com_-1024x578.png)](https://jarroba.com/wp-content/uploads/2024/03/Docker-Desktop-Primer-uso-y-sign-up-www.jarroba.com_.png)

 

Luego es posible que nos pida que a qué nos dedicamos.

 

Tras lo anterior, ya estaríamos dentro. Donde si todo ha ido bien lo primero que nos dice es que el motor de Docker está en ejecución (“Engine running”), además, podremos ver el estado de Docker junto al reloj de Windows (nos pondrá “Docker Desktop is running”).

 

[![Captura de Docker Desktop en ejecución con el motor activo y el icono de estado junto al reloj de Windows](https://jarroba.com/wp-content/uploads/2024/03/Docker-Desktop-Primer-uso-en-ejecucion-www.jarroba.com_-1-1024x452.png)](https://jarroba.com/wp-content/uploads/2024/03/Docker-Desktop-Primer-uso-en-ejecucion-www.jarroba.com_-1.png)

 

Esta interfaz nos permitirá gestionar los contenedores de Docker, como veremos más adelante.

 

Siempre que queramos trabajar con Docker, lo tenemos que hacer sobre un **Docker en estado**iniciado (“**started**”).

 

**Nota si nos dice “Docker Engine stopped”:** podemos probar a reiniciar, si sigue dando problemas, es que algo nos falta y no está iniciándose correctamente, en Windows puede que WSL 2 no está bien instalado.

 

**Nota para cuando terminemos de usar Docker:** no es suficiente con salir de “Docker Desktop”, sino que es necesario detener el “Docker Engine” (que es lo que más recursos consume). Con “Docker Desktop”, cuando pulsemos en “Quit Docker Desktop” ya se encarga de detener el “Docker Engine” y terminará cerrando la aplicación “Docker Desktop”.

 

 

## **Docker Hub**

 

“Docker Hub” es el **repositorio de imágenes** (como la “tienda de aplicaciones” de Docker) y se pueden ver las imágenes que existen de tres maneras:

 
- Desde la**web**: [Explore Docker's Container Image Repository (Docker Hub)](https://hub.docker.com/search) (Donde veremos nada más entrar imágenes de tecnologías muy conocidas y que nos llamarán la atención, como la imagen de Python, Ubuntu, Redis, Nginx, etc.)

 

[![Captura de Docker Hub con resultados de imágenes populares (alpine, nginx, ubuntu, python) y el filtro de contenido confiable resaltado](https://jarroba.com/wp-content/uploads/2024/03/Docker-Hub-www.jarroba.com_-1024x877.png)](https://jarroba.com/wp-content/uploads/2024/03/Docker-Hub-www.jarroba.com_.png)

 

**Nota importante sobre este repositorio “Docker Hub”**: hay de todo, desde **imágenes oficiales** (“Docker Official Image”), **las verificadas** por el publicador (“Verified Publisher”), las patrocinadas (“Sponsored OSS”) y **las que no te aseguran fiabilidad alguna** (ten en cuenta que todo el mundo puede subir imágenes a “Docker Hub”, por lo que habrá imágenes que contengan virus o que directamente ni funcionen). Para obtener imágenes fiables, a la izquierda de la web se puede filtrar y recomiendo principalmente las imágenes oficiales (“Docker Official Image”), las verificadas por el publicador (“Verified Publisher”); si pulsas en el siguiente link ya te las dejo marcadas: [Explore Docker's Container Image Repository (Docker Hub)](https://hub.docker.com/search?q=&image_filter=official%2Cstore)

 
- Desde “**Docker Desktop**”: el buscador está en la parte de arriba de la aplicación y se conecta a la misma web que te indiqué antes, por lo que encontrarás lo mismo (el icono de sello verde junto al título de la imagen, indica que es una “imagen Docker” oficial):

 

[![Captura de Docker Desktop buscando «Python» en Docker Hub, con la imagen oficial python y los botones Pull y Run](https://jarroba.com/wp-content/uploads/2024/03/Docker-Hub-en-docker-hub-www.jarroba.com_-1024x579.png)](https://jarroba.com/wp-content/uploads/2024/03/Docker-Hub-en-docker-hub-www.jarroba.com_.png)

 

 

## **Objetos Docker: Imágenes y Contenedores**

 

Es importante conocer los **objetos Docker**(En “Docker Desktop” podremos ver muchos de ellos clasificados en el menú vertical de la izquierda; así también nos sirve esta parte de tutorial rápido de “Docker Desktop”):

 

[![Captura del menú lateral de Docker Desktop con las secciones Containers e Images resaltadas](https://jarroba.com/wp-content/uploads/2024/03/Contenedores-e-imagenes-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/Contenedores-e-imagenes-www.jarroba.com_.png)

 

**Imagen Docker**: es una **plantilla Software** de solo lectura **con “instrucciones”** (“capas” en Docker) para crear un contenedor Docker. A “plantilla Software” me refiero a un paquete ya “construido” (“build”) desde una plantilla de verdad (el Dockerfile, que te interesará si eres desarrollador y lo veremos en profundidad en el siguiente artículo). Las imágenes se pueden subir a repositorios para compartirlas (semejante a “git”, como puede ser al repositorio público de “Docker Hub” o a un repositorio privado como “Harbor”).

 

Por ejemplo, en el siguiente dibujo te muestro una representación de una “imagen Docker” de “MySQL” que utilizaremos más adelante (el dibujo con esta representación es mía para que entiendas en profundidad como están montadas). En esta “imagen Docker” hay ya preparadas una serie de instrucciones de ejemplo (por alguien del mundo, tú no tienes que hacer esto en este artículo, por cierto, me he basado en la documentación real):

 
- Una primera instrucción sería tener un sistema operativo “Linux Oracle” (podría estar sobre cualquier sistema operativo, Ubuntu, Debian, etc. Normalmente uno muy poco pesado).
- Otra instrucción podría ser tener instalado sobre ese sistema operativo un MySQL con su configuración ya preparada (por alguien que no eres tú).
- Y una última instrucción que sería “iniciar el servidor” de la base de datos (para que tú solo tengas que ejecutar el contenido de la Imagen sin tener que hacer nada de lo que te acabe de contar, solo tendrías que disfrutar de la tecnología, en este caso, podrías aprender SQL con una base de datos real y funcional).

 

[![Diagrama de una imagen Docker con Linux Oracle y MySQL, con la instrucción de iniciar el servidor](https://jarroba.com/wp-content/uploads/2024/03/Imagen-Docker-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/Imagen-Docker-www.jarroba.com_.png)

 

**Contenedor Docker:**es un **entorno aislado con todo lo necesario para ejecutarse** (Java, Python, bases de datos, código del proyecto que hayas desarrollado, dependencias, scripts, etc.) y no tiene conocimiento del sistema operativo sobre el que se ejecuta Docker (“Docker Desktop”, que incluye “Docker Engine” y éste último incluye “Docker Daemon”; siendo el “Docker Daemon” el servidor que ejecuta las imágenes de Docker y las mantiene como contenedores). Para crear un contenedor **se necesita de una imagen** Docker y durante la creación hay que definir una serie de parámetros (como los Volúmenes o las Redes, que son otros objetos Docker que veremos más adelante). Por lo que desde una misma imagen podremos tener cuantos contenedores queramos, todos funcionando en el mismo ordenador o distribuidos en varios ordenadores (con pasar la imagen a otro ordenador, haciendo “pull” desde un repositorio o copiándola, es muy sencillo crear un contenedor desde esta).

 

Es importante tener en cuenta los dos tipos de comportamiento de los contenedores cuando los iniciamos (esto es importante entenderlo, porque si montas un contenedor y ves que se detiene de inmediato, es bastante posible que sea por esto o por un error):

 
- **Contenedores efímeros**: son contenedores que se inician y terminan casi de inmediato, tras terminar de ejecutar su hilo principal (la imagen de Python, que te mostré antes, crea este tipo de contenedores, pues interesa que se ejecute nuestro código Python que pongamos dentro y tan pronto termine, pues que se detenga y libere recursos; podríamos tener código Python en bucle infinito, por lo que el Contenedor se mantendrá activo esperando a que termine indefinidamente). Normalmente este tipo de contenedores son tan rápidos que no nos da tiempo a interactuar con ellos.
- **Contenedores Daemon**(o de larga duración)**:**son contenedores que tienen su hilo principal ocupado eternamente, suelen ser servidores (servidores web, servidores de base de datos, etc.). Podremos interactuar con estos contenedores, ejecutar comandos en una terminal, ver su sistema de ficheros, etc. A continuación, probaremos uno de estos contenedores con un servidor de base de datos “MySQL” (que son los que interesan en este artículo y los que te recomiendo que utilices para aprender, por ejemplo, a escribir consultas SQL en la base de datos que quieras ¡Tienes todas a tu disposición de manera muy parecida!).

 

De seguido te muestro un dibujo de lo que haremos a continuación de verdad y para que veas la diferencia entre “imagen Docker” y “contenedor Docker”. Desde una “Imagen Docker” la ejecutamos (“run”) y nos creará un “contenedor Docker” funcionando con todo (un “Linux Oracle” con un MySQL que está iniciado y en ejecución sobre el Hardware de tu ordenador, pero separado de tu sistema operativo, por tanto, listo para ser usado) y con el que podremos trabajar (crear bases de datos y ejecutar consultas SQL). Cabe mencionar, que desde la “imagen Docker” podremos ejecutar tantos “contenedor Docker” como queramos (es decir, podríamos tener mil MySQL funcionando a la vez con tan solo pulsar un botón).

 

[![Diagrama del Docker Engine que con «run» convierte una imagen en un contenedor que usa el hardware](https://jarroba.com/wp-content/uploads/2024/03/Imagen-Docker-a-Contenedor-www.jarroba.com_-1024x672.png)](https://jarroba.com/wp-content/uploads/2024/03/Imagen-Docker-a-Contenedor-www.jarroba.com_.png)

 

 

## Descargar una imagen desde “Docker hub” con “Docker Desktop”

 

Para este artículo voy a usar de **ejemplo la** **imagen de “MySQL”**. Si no conoces MySQL comentarte rápidamente que es un motor de bases de datos relacionales de los más conocidos y fácil de aprender (más información en [MySQL](https://www.mysql.com/)), además, te voy a enseñar no solo a instalarlo, sino que a usarlo.

 

Para **descargar la imagen de MySQL**desde “Docker hub” vamos a la interfaz de “Docker Desktop” y arriba en el buscador (donde pone “Search”), **escribimos: mysql**

 

Nos aparecerá un **listado** con bastantes imágenes, pero aquí vamos a **elegir**la imagen que se llama “**mysql**” y vamos a elegir la **versión** llamada “**8.3**” (fijo esta versión a propósito, para que no tengas problemas en seguir este artículo, ya que otras versiones pueden cambiar).

 

[![Captura de Docker Desktop buscando «mysql» con el desplegable de etiquetas abierto y la versión 8.3 resaltada](https://jarroba.com/wp-content/uploads/2024/03/InstalarMySQL-en-Docker-compose-www.jarroba.com_-1024x580.png)](https://jarroba.com/wp-content/uploads/2024/03/InstalarMySQL-en-Docker-compose-www.jarroba.com_.png)

 

Tras seleccionar la versión tendremos dos **opciones para descargar la imagen**:

 
- **Pull**: descarga la imagen de “Docker Hub”.
- **Run**: descarga la imagen de “Docker Hub”, crea un contenedor local y ejecuta la imagen dentro.

 

Para ir paso a paso **seleccionaremos “Pull”**:

 

[![Captura de Docker Desktop con la imagen mysql en la etiqueta 8.3 y el botón Pull resaltado](https://jarroba.com/wp-content/uploads/2024/03/InstalarMySQL-en-Docker-compose-2-www.jarroba.com_-1024x214.png)](https://jarroba.com/wp-content/uploads/2024/03/InstalarMySQL-en-Docker-compose-2-www.jarroba.com_.png)

 

Una vez que esté descargada, iremos en el **menú de la izquierda** a “**Images**”, donde veremos nuestra imagen descargada “mysql” y aquí para **iniciar a la imagen** iremos a la derecha a pulsar en la **flecha de “Run”** (este botón, aunque se llama también “Run” no descarga la imagen, solo crea el contenedor donde se ejecuta la imagen, puesto que ya está descargada):

 

[![Captura de la sección Images de Docker Desktop con la imagen mysql 8.3 descargada y el botón Run resaltado](https://jarroba.com/wp-content/uploads/2024/03/MySQL-en-Docker-compose-run-www.jarroba.com_-1024x582.png)](https://jarroba.com/wp-content/uploads/2024/03/MySQL-en-Docker-compose-run-www.jarroba.com_.png)

 

Se nos abrirá una **ventana** que nos pide varios parámetros, aunque son todos opcionales para ejecutar a la imagen, algunas son obligatorias para que lo que está dentro de la imagen funcione (en este caso, la instalación de MySQL que está dentro de la imagen funcione bien).

 
- **Container name**: podremos poner un **nombre al contendor** si queremos (si no, se pone uno aleatorio), yo en el ejemplo pondré “**miMySQL-container**” para poder distinguir entre otros contenedores que podamos tener en el futuro. Por cierto, recomiendo poner el nombre que quieras (normalmente el mismo de la imagen), pero que incluya la palabra “contenedor” (o “container” en inglés), como puede ser “miContenedorMysql” o directamente “mysql-container”, pues así es más fácil de distinguir los contenedores de las imágenes y cuando llevas programando horas ayuda a distinguir rápidamente entre imágenes y contenedores (esto es una sugerencia mía, no es un estándar ni nada parecido).
- **Ports**: podremos mapear los **puertos** que queramos de nuestro ordenador (local) con los del contenedor (con los de su interior, que son los puertos que salen en gris a la derecha “3306” y “33060”). Esto será útil si trabajas con redes de contenedores y quieres conectarte a tu contenedor, pero para ahora mismo no son necesarios, por lo que en este ejemplo no pondré nada. Si no ponemos nada, por defecto es como poner lo mismo que está en gris (en el ejemplo será “3306:3306” y “33060:33060”, es decir, que por ejemplo podremos conectarnos desde nuestro ordenador a “localhost:3306”).
- **Volumes**: Si queremos podremos definir o un “Bind mount” (que podríamos traducir algo así como “montaje vinculado”) o un “Docker Volume” (“Volumen Docker”). Lo veremos más adelante, así que de momento lo dejaremos vacío
- **Environment variable**: Aquí definiremos las **variables entorno** que necesitemos. Si has trabajado con bases de datos, quizás te preguntes que ¿Cuál es la contraseña de root de MySQL? Pues aquí le diremos que NO nos pida contraseña de root (esto es muy inseguro, por lo que para entornos de Producción no es recomendable, pero para jugar con la base de datos es lo más sencillo) y pondremos exactamente en el campo “**variable**” el texto exacto “**MYSQL_ALLOW_EMPTY_PASSWORD**” (cópialo sin comillas) **y** en “**value**” la afirmación en inglés “**yes**” (sin comillas). Por cierto, esto no me lo he inventado, está en la documentación de la imagen de MySQL: [mysql – Official Image (Docker Hub)](https://hub.docker.com/_/mysql)

 

[![Captura de Docker Desktop con el formulario para ejecutar un contenedor mysql:8.3, con el nombre y la variable de entorno resaltados](https://jarroba.com/wp-content/uploads/2024/03/MySQL-en-Docker-compose-config-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/MySQL-en-Docker-compose-config-www.jarroba.com_.png)

 

**Nota por si quieres poner contraseña de root**: En vez de la anterior variable de entorno, en el campo “variable” pon “MYSQL_ROOT_PASSWORD” (sin comillas) y en “value” la contraseña que queramos, por ejemplo, “contraseniaroot”, pero acuérdate de ella porque te la pedirá más adelante.

 

**Pulsamos “Run”** para que se nos cree nuestro contenedor Docker con la imagen MySQL y los parámetros de configuración que acabamos de poner.

 

**Se nos abrirá el contenedor** directamente (fíjate que automáticamente en el menú de la izquierda nos ha cambiado a “Containers”) que acabamos de crear, arriba verás el nombre que le pusimos a nuestro contenedor (en mi ejemplo “miMySQL-container”) y en la primera **pestaña** llamada “**Logs**” **veremos las “trazas”**(también llamados “registros” o “logs”) de nuestro contenedor, esperaremos unos segundos hasta que aparezca el log que diga “**MySQL init process done. Ready for start up.**” (Lo que nos indicará que nuestro contenedor con MySQL instalado ya estará listo para ser utilizado). Estos logs son importantes, puesto que aquí nos informará tanto si ha ido bien como si algo ha ido mal (veremos errores).

 

[![Captura de Docker Desktop con los logs del contenedor MySQL indicando que el inicio ha terminado y está listo](https://jarroba.com/wp-content/uploads/2024/03/MySQL-en-Docker-compose-iniciado-www.jarroba.com_-1024x610.png)](https://jarroba.com/wp-content/uploads/2024/03/MySQL-en-Docker-compose-iniciado-www.jarroba.com_.png)

 

Aquí te animo a navegar en el menú lateral izquierdo entre “Containers” e “Images” para que veas las diferencias:

 
- **Images**: tenemos la imagen mysql que hemos descargado de “Docker Hub” (la imagen puede ocupar bastante en disco).
- **Containers**: tenemos nuestro contenedor “myMySQL-container” en ejecución que hemos creado desde la anterior imagen (como el contenedor está en ejecución, nuestro ordenador va a estar trabajando bastante).

 

[![Captura de Docker Desktop con la imagen mysql 8.3 en uso y el contenedor miMySQL-container en ejecución](https://jarroba.com/wp-content/uploads/2024/03/Imagen-y-Contenedor-Docker-www.jarroba.com_-1024x683.png)](https://jarroba.com/wp-content/uploads/2024/03/Imagen-y-Contenedor-Docker-www.jarroba.com_.png)

 

Para continuar, vete a “Containers” y pulsa sobre el nombre de tu contenedor (en mi ejemplo “myMySQL-container”).

 

Iremos a la **pestaña “Exec”**de nuestro contenedor, ésta es la interfaz de nuestro contenedor, donde estará el sistema de archivos del sistema operativo de nuestro contenedor (como es un sistema operativo Linux, podremos escribir sus comandos para ver los directorios como: ls ) ¿Pero no dijimos que no íbamos a programar nada? Escribir un comando y consultas SQL no es programar 😉 Para iniciar la terminal de MySQL, nos bastará con escribir el **comando: mysql**

 

[![Captura de la pestaña Exec de Docker Desktop con consultas SQL de ejemplo ejecutadas en el cliente mysql](https://jarroba.com/wp-content/uploads/2024/03/MySQL-en-Docker-probar-consultas-SQL-www.jarroba.com_-1024x689.png)](https://jarroba.com/wp-content/uploads/2024/03/MySQL-en-Docker-probar-consultas-SQL-www.jarroba.com_.png)

 

**Nota si has puesto contraseña root:** necesitas ejecutar: mysql -u root -p

 

Tras iniciar la **terminal de MySQL podremos escribir consultas SQL** que queramos, para este ejemplo he escrito las siguientes (te resumo rápido las sentencias SQL que he usado en el ejemplo, puesto que hay otros artículos de SQL y por si quieres aprovechar a aprender SQL con esto ya puedes practicar en un entorno real todo lo que quieras):

 
- **CREATE DATABASE**: crea una base de datos dentro del motor de MySQL.
- **USE**: para usar una de la base de datos que tengas creada.
- **CREATE TABLE**: dentro de la base de datos en uso, creará la tabla.
- **INSERT INTO**: insertar un registro con valores en una tabla creada.
- **SELECT**: Consultar los datos de una tabla.
- **DROP TABLE**: elimina una tabla existente.

 

```sql
CREATE DATABASE mi_bd;
USE mi_bd;
CREATE TABLE mi_tabla ( id INT AUTO_INCREMENT PRIMARY KEY, nombre VARCHAR(50), email VARCHAR(50) );
INSERT INTO mi_tabla (nombre, email) VALUES ('Ramon', 'ramon@jarroba.com');
SELECT * FROM mi_tabla;
DROP TABLE mi_tabla;
```

 

Otra cosa importante es ¿Y dónde se guardan los datos de las tablas que cree en mi base de datos? Pues si te vas a la **pestaña “Files”** y navegas al directorio “**/var/lib/mysql**” (este directorio lo conozco por la documentación de MySQL), ahí estarán los ficheros con toda nuestra información que guardemos en la base de datos (es donde MySQL guarda todo) ¿Para qué te cuento esto? Porque si te fijas a la izquierda del directorio “mysql” aparece una **nota “VOLUME”**, como no hemos hecho nada con los volúmenes, entonces, se nos ha montado un volumen automático y todo **volumen automático es temporal**, es decir, que si detienes este contenedor vas a perder todas las bases de datos, tablas y toda la información que has introducido en MySQL (digamos que está en la volátil memoria RAM, no en disco duro).

 

[![Captura de la pestaña Files de Docker Desktop con la carpeta /var/lib/mysql marcada como volumen automático](https://jarroba.com/wp-content/uploads/2024/03/MySQL-en-Docker-files-ficheros-www.jarroba.com_-1024x688.png)](https://jarroba.com/wp-content/uploads/2024/03/MySQL-en-Docker-files-ficheros-www.jarroba.com_.png)

 

¿Cómo hacemos para que los datos perduren cuando detengamos el contenedor? Lo veremos enseguida, pero para ello tenemos que volver a crear el contenedor.

 

Para continuar, y cuando hayas terminado de trabajar con nuestro contendor, **arriba a la derecha** hay varios controles (como el cuadrado de detener el contenedor, la flecha de iniciar el contenedor o el de reiniciarlo), pulsaremos en la **papelera para detener el contenedor y destruirlo** (esto solo elimina el contenedor, no la imagen descargada).

 

[![Captura de Docker Desktop con el estado del contenedor en ejecución y el botón de papelera para eliminarlo](https://jarroba.com/wp-content/uploads/2024/03/Estados-imagen-y-terminar-www.jarroba.com_-1024x151.png)](https://jarroba.com/wp-content/uploads/2024/03/Estados-imagen-y-terminar-www.jarroba.com_.png)

 

 

## Objetos Docker: Volumes

 

**Para persistir datos** en disco, para cuando en el futuro volvamos a iniciar un contenedor que hayamos detenido en el pasado (es decir, reiniciamos un contenedor), y queremos que se mantengan los datos (persistencia), **necesitamos volúmenes**. En Docker hay dos tipos de volúmenes:

 

**Docker Volume**(Volumen Docker): los creamos nosotros con el nombre que queramos y los administra Docker (en “Docker Desktop” los veremos en el menú lateral izquierdo en “volumes”). Un volumen es independiente de los contenedores (por lo que podrías utilizar el mismo volumen para varios contenedores) y se pueden preservar en donde quieras (por ejemplo, te los puedes llevar en un pendrive). Los volúmenes hay que eliminarlos a mano, sino existe para siempre. Un volumen se añade al crear el contenedor desde la imagen y basta con indicar su nombre.

 

**Bind mount** (Montaje Vinculado): creamos una carpeta normal en el sistema operativo de nuestro ordenador (host) y esta carpeta la vincularemos con un directorio de dentro del contenedor. Cuando se detiene el contenedor, podremos seguir trabajando con los ficheros en nuestro ordenador Host, además de quedar persistidos en dicha carpeta. Es cómodo para desarrollo y para pasar ficheros rápidamente, pues lo que editemos en esta carpeta desde el host se verá reflejado de inmediato dentro del contenedor y viceversa. Pero es peligroso, pues estamos dejando al contenedor crear ficheros en nuestro sistema de ficheros del ordenador host (lo que podría corromper y dañar a nuestro sistema operativo si no se usa correctamente, como puede ser la generación de archivos hasta llenar el disco o traspasar virus desde el contenedor, si la imagen no es fiable). Bind mount no es gestionado por Docker, sino por nosotros, si queremos más seguridad, entonces mejor utilizar Volume.

 

Te dejo un dibujo con lo que montaremos a continuación, que será una “imagen Docker” con MySQL asignada a un “volumen Docker” para persistir sus datos y que tiene mapeado el puerto 3306 del contenedor al 3306 de tu ordenador (que es lo mismo que dejarlo en blanco en el “host port”, como hicimos previamente). Además, crearemos otra imagen más con “Apache HTTP Server” (más conocido como “Httpd”), con la carpeta “www” como un “Bind mount de Docker” para poder crear una página web en tiempo real mientras se sirve en el servidor “Httpd”, además, mapearemos el puerto 80 del contenedor (que es al que escucha “Httpd”) al puerto 8000 de nuestro ordenador (con lo que podremos ver nuestra página web desde nuestro navegador favorito en la dirección [http://localhost:8000/](http://localhost:8000/) ).

 

[![Diagrama de Docker Engine con contenedores MySQL y Httpd, sus puertos mapeados, un volumen y un bind mount](https://jarroba.com/wp-content/uploads/2024/03/Contenedores-docker-con-puertos-volumen-y-bind-mount-www.jarroba.com_-1024x958.png)](https://jarroba.com/wp-content/uploads/2024/03/Contenedores-docker-con-puertos-volumen-y-bind-mount-www.jarroba.com_.png)

 

 

## Crear un volumen

 

Para **crear un Volumen** gestionado por Docker, **vamos al menú** de la izquierda del “Docker Desktop” y elegimos donde pone “**Volumes**”. Entonces, creamos un nuevo volumen pulsando en “**Create a volume**”.

 

[![Captura de la sección Volumes de Docker Desktop con el botón «Create a volume» resaltado](https://jarroba.com/wp-content/uploads/2024/03/Crear-volumen-www.jarroba.com_-1024x345.png)](https://jarroba.com/wp-content/uploads/2024/03/Crear-volumen-www.jarroba.com_.png)

 

Se nos abrirá una ventana que nos pedirá el **nombre del volumen**, que yo llamaré “**MiVolumenDocker**” (copia este nombre, ya que lo utilizaremos más adelante).

 

[![Captura de Docker Desktop con la ventana «New Volume» y el nombre MiVolumenDocker listo para crear](https://jarroba.com/wp-content/uploads/2024/03/Crear-volumen-2-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/Crear-volumen-2-www.jarroba.com_.png)

 

Al pulsar “**Create**”, inmediatamente veremos nuestro volumen creado en un listado (pues podremos tener cuántos volúmenes queramos).

 

[![Captura de Docker Desktop con el volumen MiVolumenDocker recién creado en la lista de volúmenes](https://jarroba.com/wp-content/uploads/2024/03/Crear-volumen-3-www.jarroba.com_-1024x257.png)](https://jarroba.com/wp-content/uploads/2024/03/Crear-volumen-3-www.jarroba.com_.png)

 

Regresamos a “Images” y, como vimos en pasos previos, creamos un nuevo contenedor con la siguiente configuración (que es muy parecida a la de “Bind mount”, pero más fácil):

 
- **Container name**: ejemplo “**miMySQL-container**”.
- **Volumes**: en el campo “**Host path**” pondremos en nombre que le pusimos antes al volumen que creamos, que en mi ejemplo fue “**MiVolumenDocker**” y en el campo **“Container path” apuntamos** a lo que queramos persistir que en mi caso es “**/var/lib/mysql**” (Docker diferencia dependiendo de lo que pongas en “Host path”, si es una ruta a un directorio, entonces Docker crea un “Bind mount”, como después veremos; pero si lo que pones es una palabra, entonces para Docker es un “Volume”).
- **Environment variable**: en el campo “**variable**” y “**value**” pondremos sin comillas respectivamente “**MYSQL_ALLOW_EMPTY_PASSWORD**” **y** “**yes**”.

 

[![Captura del diálogo para ejecutar un contenedor mysql con nombre, volumen MiVolumenDocker y variable de entorno](https://jarroba.com/wp-content/uploads/2024/03/Crear-volumen-4-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/Crear-volumen-4-www.jarroba.com_.png)

 

Pulsamos “**Run**” y se iniciará nuestro contenedor.

 

Dentro del contenedor, en la pestaña “Files” si vamos a la ruta “/var/lib/mysql” veremos que lo reconoce como “VOLUME” (si recuerdas, también aparecía “VOLUME” si no se definía ningún volumen, porque Docker creaba uno temporal que al eliminar el contenedor se borraba; ahora, la diferencia con el anterior es que este “VOLUME” es persistente, por tanto, si detenemos el contenedor y lo reiniciamos seguiremos manteniendo los datos).

 

[![Captura de la pestaña Files del contenedor MySQL con la carpeta /var/lib/mysql marcada como VOLUME](https://jarroba.com/wp-content/uploads/2024/03/Crear-volumen-5-www.jarroba.com_-1024x626.png)](https://jarroba.com/wp-content/uploads/2024/03/Crear-volumen-5-www.jarroba.com_.png)

 

Con esto, aunque detengamos el contenedor y lo reiniciemos, nuestros datos estarán persistidos en disco; cuando volvamos a iniciar el contenedor, los datos, por ejemplo las tablas e inserciones (“INSERT”) que hayamos hecho en la base de datos, seguirán ahí y no los habremos perdido.

 

 

## Crear un Bind mount

 

Para **montar una “bind mount”**, simplemente pensamos en una carpeta de nuestro ordenador que queramos vincular (y todo lo que pongamos en ella se verá desde dentro del contenedor) y **creamos un nuevo contenedor desde nuestra imagen**.

 

**Nota sobre la inseguridad de los “bind mount”**: es importante que entiendas los problemas de seguridad que indiqué antes, esta imagen de “MySQL” es oficial, por lo que deberíamos de poder confiar en ella, pero siempre bajo nuestra responsabilidad.

 

Para este ejemplo vamos a ver la utilidad del “Bind mount”, por lo que **utilizaremos la imagen de Apache HTTP Server** (también llamado “**httpd**”; más información en [Welcome! (The Apache HTTP Server Project)](https://httpd.apache.org/)) que es muy utilizada para crear páginas webs, para ello descargaremos la imagen como antes, pondremos en ejecución el contenedor que nos dejará dentro en ejecución servidor “httpd” y podremos trabajar en directo con ficheros HTTP, CSS y javascript, pudiendo ver los resultados en nuestro navegador tal y como si estuvieran subidos a un servidor empresarial de verdad.

 

Para ello, como vimos antes **descargaremos la imagen “httpd” con la versión 2.4**([httpd – Official Image (Docker Hub)](https://hub.docker.com/_/httpd)), aquí directamente crearemos el contenedor con “**Run**” para ahorrarnos pasos.

 

[![Captura de Docker Desktop buscando la imagen httpd, con la etiqueta 2.4 y el botón Run](https://jarroba.com/wp-content/uploads/2024/03/descargar-apache-server-httpd-www.jarroba.com_-1024x222.png)](https://jarroba.com/wp-content/uploads/2024/03/descargar-apache-server-httpd-www.jarroba.com_.png)

 

Se nos abrirá la ventana de Run que nos pedirá los parámetros que yo definiré:

 
- **Container name**: ejemplo “**MiServidorApache-container**”.
- **Ports**: fíjate que el puerto del interior del contenedor es el “80”, este puerto es tan utilizado que lo más seguro es que tengamos problemas para utilizarlo en nuestro ordenador; por lo que aquí, voy a mapearlo con un puerto que yo quiera que no se esté utilizando en nuestro ordenador, por ejemplo, el 8000 (es decir, que el puerto 80 de dentro del contenedor quedará expuesto a mi ordenador como 8000).
- **Volumes**: en el campo “**Host path**” (ruta de nuestro ordenador que es el host) clicaremos en los tres puntos y **elegiremos una carpeta** de nuestro ordenador (yo he decido crearme una carpeta en el escritorio de Windows (escoge un sitio adecuado) llamada “www” (este nombre es una convención para poner los recursos web, también se suele llamar “htdocs” o “public_html”, pero puedes llamarla como quieras); luego, en “**Container path**” pondremos la ruta de dentro del contenedor que necesitemos ¿Y cuál necesitamos? Pues mirando la documentación oficial [Configuration Sections (Apache HTTP Server Version 2.4)](https://httpd.apache.org/docs/2.4/sections.html) o más fácil en [httpd – Official Image (Docker Hub)](https://hub.docker.com/_/httpd) nos indica que el espacio de trabajo es “**/usr/local/apache2/htdocs/**”, por lo que será esta ruta la que queramos mapear y donde coloquemos los ficheros web (HTTP, CSS, JavaScript).

 

[![Captura del diálogo para ejecutar httpd con nombre, puerto 8000 y carpeta local enlazada a /usr/local/apache2/htdocs/](https://jarroba.com/wp-content/uploads/2024/03/Iniciar-contenedor-desde-la-imagen-apache-server-httpd-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/Iniciar-contenedor-desde-la-imagen-apache-server-httpd-www.jarroba.com_.png)

 

Cuando pulsemos “Run”, se nos creará el contenedor en ejecución y cuando termine de cargar (es muy rápido, segundos). Docker ya se encarga de exponernos en nuestro local (localhost) y con el mapeo de puerto que antes definimos (el 8000); por lo que, si has seguido este artículo bastará ir a tu navegador web favorito y escribir: [http://localhost:8000/](http://localhost:8000/)

 

[![Captura del navegador en localhost:8000 mostrando la página «Index of /» del servidor Apache](https://jarroba.com/wp-content/uploads/2024/03/localhost-8000-con-la-web-por-defecto-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/localhost-8000-con-la-web-por-defecto-www.jarroba.com_.png)

 

Si te fijas, en la web aparecerá “Index of/”, esto te lo genera el servidor Apache HTTP Server, que es la página por defecto si la carpeta de recursos web está vacía (el directorio “/usr/local/apache2/htdocs/”).

 

Dicho directorio, si recuerdas lo habíamos vinculado con “Bind mounts”, por lo que en la **pestaña “Bind mounts”** podremos ver la carpeta de nuestro ordenador en “Source (Host)” y en “Destination (Container)” veremos la ruta a la que apunta dentro del contenedor.

 

[![Captura de la pestaña Bind mounts del contenedor Apache con la carpeta local enlazada a /usr/local/apache2/htdocs](https://jarroba.com/wp-content/uploads/2024/03/bind-mount-en-el-contenedor-de-apache-server-httpd-www.jarroba.com_-1024x244.png)](https://jarroba.com/wp-content/uploads/2024/03/bind-mount-en-el-contenedor-de-apache-server-httpd-www.jarroba.com_.png)

 

En el contenedor, si vamos a la **pestaña “Files”** y vamos a “**/usr/local/apache2/htdocs/**”**,**veremos que aparece la **etiqueta “MOUNT”** que nos indica que esta carpeta no existe realmente dentro del contenedor, sino que está montada y vinculada (“bind mount”) a una carpeta de nuestro ordenador:

 

[![Captura de Docker Desktop, pestaña Files, con la carpeta htdocs de Apache marcada como MOUNT, vinculada a una carpeta del equipo](https://jarroba.com/wp-content/uploads/2024/03/files-con-la-imagen-montada-del-contenedor-de-apache-server-httpd-www.jarroba.com_-1024x682.png)](https://jarroba.com/wp-content/uploads/2024/03/files-con-la-imagen-montada-del-contenedor-de-apache-server-httpd-www.jarroba.com_.png)

 

Minimizamos Docker Desktop y **vamos a la carpeta que hemos creado y vinculado en nuestro ordenador**, que en mi caso está en el escritorio de Windows con el nombre “**www**”. Ahora, si creamos o modificamos ficheros dentro de esta carpeta, el contenedor de inmediato verá los cambios en tiempo real. Para hacer la prueba **crearemos un fichero llamado “index.html”** (es importante que la extensión sea “html” y el nombre “index” es para que se tome como página inicial) que editaremos con nuestro editor favorito (Vim, Sublime Text, el bloc de notas de Windows, etc.) y escribiremos código HTML, que para mí ejemplo escribiré (y guardaré los cambios, es importante guardar):

 

```xml
<!DOCTYPE html>
<html>
<head>
    <title>Mi Sitio Web</title>
</head>
<body>
<h1>Ejemplo de texto de www.jarroba.com</h1>
</body>
</html>
```

 

[![Carpeta www con el archivo index.html abierto en Sublime Text, con una página HTML de ejemplo con título y encabezado](https://jarroba.com/wp-content/uploads/2024/03/Anadir-ficheros-web-a-www-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/Anadir-ficheros-web-a-www-www.jarroba.com_.png)

 

Y si **volvemos al navegador y pulsamos en** **actualizar** (o tecla “F5”), veremos de inmediato como el servidor dentro del contenedor ha tomado los cambios de la carpeta y me permite ver la web que he creado:

 

[![Captura del navegador en localhost:8000 mostrando la página «Mi Sitio Web» servida desde el contenedor Apache](https://jarroba.com/wp-content/uploads/2024/03/Ejemplo-visualizacion-de-la-ejecucion-del-http-www.jarroba.com_.png)](https://jarroba.com/wp-content/uploads/2024/03/Ejemplo-visualizacion-de-la-ejecucion-del-http-www.jarroba.com_.png)

 

Por cierto, aunque detengamos el contenedor y lo reiniciemos, nuestros datos estarán persistidos en disco (en mi ejemplo, los de la carpeta “www”) y, encima, los tendremos accesibles desde nuestro ordenador host, aunque el contenedor no esté funcionando.

 

 

## Contenedores Docker vs Máquinas Virtuales (VM)

 

La gracia de un **contenedor Docker** es que **se ejecuta directamente en el núcleo** (kernel) del sistema operativo del ordenador sobre el que está instalado (host). Por el contrario, una **máquina virtual emula Hardware** sobre el que se ejecuta.

 

**Ventajas de ejecutar directamente en el núcleo**:

 
- **Reduce la complejidad**: facilita la programación y aumenta la velocidad de procesado (en comparación a emular Hardware).
- **Facilita crear y depurar controladores**: si desarrollas un controlador de un dispositivo físico te interesará probarlo directamente sobre el mismo, no sobre uno emulado.
- **Sin límites**: por defecto puede aprovechar todo el Hardware de la máquina. Por el contrario, una máquina virtual no podrá aprovechar todo el Hardware físico (principalmente porque tiene en ejecución dos sistemas operativos, el host y el virtual, ambos con sus espacios de usuario y de kernel, esto consume bastantes recursos físicos).

 

**Ventajas de emular Hardware**:

 
- **Aislamiento**: lo que se ejecuta dentro de una máquina virtual no interfiere con lo que se ejecuta en el Hardware del host.
- **Flexibilidad**: se pueden instalar y ejecutar varias aplicaciones en el mismo sistema operativo virtual (es como tener otro ordenador dentro del ordenador; por ejemplo, de host Windows con su escritorio y emulado un Ubuntu Linux con su escritorio).
- **Emulación de Hardware**: emular todo, desde la CPU, memoria, tarjeta de red, controladores USB, etc. Por ejemplo, tu ordenador tiene físicamente un disco duro de miles de Teras, pero podrías emular (simular) que tienes un disco duro muy pequeño (por ejemplo, para ver qué pasa si se le acaba la memoria al ordenador); o teniendo un procesador Intel, podrías emular que tienes un procesador AMD.

 

Un contenedor de **Docker tiene el código de la aplicación, su entorno, las bibliotecas, las herramientas del sistema y el tiempo de ejecución**. Por el contrario, una **máquina virtual es una virtualización de una máquina** completa, con sus ventajas: como ejecutar varias aplicaciones, compartir bibliotecas comunes entre diferentes aplicaciones (reduciendo el tamaño en disco), aunque con la desventaja de que pueden existir conflictos entre dependencias y versiones.

 

Un **contenedor Docker NO tiene sistema operativo con interfaz de usuario** (con escritorio, iconos, botones, puntero de ratón, etc.), solo se controla mediante comandos (“Docker Desktop”, Rancher [What is Rancher? (Rancher docs)](https://ranchermanager.docs.rancher.com/) o Portainer [Portainer — One platform, not twelve tools (Portainer)](https://www.portainer.io/) , no cuentan como interfaces de usuario, pues solo son para administrar contenedores, es decir, iniciarlos y pararlos, pero no tienes control dentro del contenedor con una interfaz). Por su parte, una **máquina virtual puede tener un sistema operativo con interfaz de usuario completa y sus aplicaciones con interfaz** (todo un Windows o un Ubuntu instalado, con su escritorio con iconos donde podemos usar con el ratón con aplicaciones como el reproductor de música, por ejemplo). Tener **interfaz de usuario facilita muchas tareas y proporciona más información de un solo vistazo**, pero tiene el inconveniente de ser muy pesado en disco y de consumir mucho tiempo de procesador; **no tener interfaz de usuario agiliza muchísimo** y por eso los contenedores Docker se levantan tan rápido. Cabe indicar que **existen “trucos”** muy usados **para tener interfaz de usuario en Docker**, como levantar un servidor que proporcione una interfaz web (que podemos ver lo que está ocurriendo en una interfaz usable en el navegador Chrome o Edge, por ejemplo).

 

**Docker es una plataforma de código abierto**. Pero la **tecnología de virtualización no tiene por qué serlo** (por ejemplo, VirtualBox [Oracle VirtualBox](https://www.virtualbox.org/) es de código libre vs VMware [Cloud Computing for the Enterprise (VMware by Broadcom)](https://www.vmware.com/) que no lo es).

## Serie: Docker

1. [Docker básico: Docker Desktop y objetos Docker](https://jarroba.com/docker-basico-docker-desktop-y-objetos-docker.md)
2. [Docker Compose](https://jarroba.com/docker-compose.md)
3. [Docker compose en un proyecto](https://jarroba.com/docker-compose-en-un-proyecto.md)
4. [Imágenes Docker](https://jarroba.com/imagenes-docker.md)
5. [Dockerfile: Directivas y Dockerizar proyectos](https://jarroba.com/dockerfile-directivas-y-dockerizar-proyectos.md)
6. [Dockerfile avanzado: multietapa, repositorio y trucos](https://jarroba.com/dockerfile-avanzado-multietapa-repositorio-y-trucos.md)

