Contenido

Tutorial de Docker para ejecutar tu primer contenedor: aprende a usar docker run

En esta sección ejecutarás un servidor web nginx y aprenderás a consultar, acceder, detener y eliminar contenedores. Cada paso incluye el resultado real de su ejecución.

Inicia nginx

docker run -d -p 8080:80 --name web nginx:1.30
$ docker run -d -p 8080:80 --name web nginx:1.30
Unable to find image 'nginx:1.30' locally
1.30: Pulling from library/nginx
ecc510c1e359: Pull complete
f4616bb1be1c: Pull complete
f1a6a629b824: Pull complete
3d774efa34e3: Pull complete
cb44c3fe542b: Pull complete
121907e00c1c: Pull complete
220a6ac36368: Pull complete
Digest: sha256:9bf97bd7714f5e24c1ccd545ecb9eb5435cb6d109c97cebb15e7e455e0239edb
Status: Downloaded newer image for nginx:1.30
b470f4d4563701824e59040cdfcd2154b4bbcca581e6d2d75cae5f2c23dbcfda

Esto es lo que ocurre, paso a paso:

  1. No tienes la imagen nginx:1.30 en tu equipo (Unable to find image ... locally), así que Docker la descarga de Docker Hub.
  2. La imagen está compuesta por varias capas. Cada línea Pull complete indica que se ha descargado una capa.
  3. Cuando termina la descarga, Docker usa la imagen para crear un contenedor nuevo llamado web.
  4. -d ejecuta el contenedor en segundo plano, por lo que el comando termina enseguida e imprime solo el ID del contenedor (una larga cadena de caracteres hexadecimales).

Explicación de los parámetros

ParámetroSignificado
-ddetached: ejecuta en segundo plano
-p 8080:80Asigna el puerto 8080 del host al puerto 80 del contenedor
--name webAsigna el nombre web al contenedor para poder administrarlo después con ese nombre
nginx:1.30Nombre y versión (tag) de la imagen

Ábrelo en el navegador

Abre el navegador e introduce http://localhost:8080:

Página de bienvenida predeterminada de nginx
Abre http://localhost:8080 en el navegador para ver la página de bienvenida de nginx

El tráfico sigue esta ruta: navegador → puerto 8080 del host → Docker lo reenvía al puerto 80 del contenedor → nginx dentro del contenedor.

También puedes probarlo desde la terminal con curl:

$ curl -s http://localhost:8080 | head -n 4
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

Consulta los contenedores en ejecución: docker ps

$ docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS         PORTS                                     NAMES
b470f4d45637   nginx:1.30   "/docker-entrypoint.…"   7 seconds ago   Up 7 seconds   0.0.0.0:8080->80/tcp, [::]:8080->80/tcp   web
CampoSignificado
CONTAINER IDLos primeros 12 caracteres del ID del contenedor; puedes usarlo en los comandos en lugar del nombre
IMAGEImagen utilizada
COMMANDComando que se ejecuta al iniciar el contenedor
CREATED / STATUSHora de creación y estado actual (Up indica que está en ejecución)
PORTSAsignación de puertos; 0.0.0.0:8080->80/tcp corresponde a -p 8080:80, que acabas de usar
NAMESNombre del contenedor

Consulta los registros: docker logs

nginx registra cada solicitud en los registros. Hace un momento te conectaste una vez desde el navegador y otra con curl:

$ docker logs web
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2026/10/12 14:38:25 [notice] 1#1: using the "epoll" event method
2026/10/12 14:38:25 [notice] 1#1: nginx/1.30.5
2026/10/12 14:38:25 [notice] 1#1: built by gcc 14.2.0 (Debian 14.2.0-19)
2026/10/12 14:38:25 [notice] 1#1: OS: Linux 5.4.0-216-generic
2026/10/12 14:38:25 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2026/10/12 14:38:25 [notice] 1#1: start worker processes
2026/10/12 14:38:25 [notice] 1#1: start worker process 28
172.17.0.1 - - [12/Oct/2026:14:38:29 +0000] "GET / HTTP/1.1" 200 896 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/130.0.6723.31 Safari/537.36" "-"
172.18.0.1 - - [12/Oct/2026:14:38:31 +0000] "GET / HTTP/1.1" 200 896 "-" "curl/8.22.0" "-"

Las primeras líneas son mensajes de inicio de nginx; puedes ver que la versión es nginx/1.30.5. Las dos últimas son los registros de las solicitudes que acabas de hacer: una proviene del navegador (el User-Agent es el del navegador) y la otra de curl. Añade -f para seguir los nuevos registros en tiempo real (pulsa Ctrl + C para salir):

docker logs -f web

Entrar en un contenedor: docker exec

docker exec ejecuta comandos dentro de un contenedor en ejecución:

$ docker exec web nginx -v
nginx version: nginx/1.30.5

$ docker exec web ls /usr/share/nginx/html
50x.html
index.html

Añade -it para abrir una shell interactiva y explorar el contenedor:

$ docker exec -it web bash
root@b470f4d45637:/# cat /etc/os-release | head -n 2
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
NAME="Debian GNU/Linux"
root@b470f4d45637:/# ls /etc/nginx
conf.d
fastcgi_params
mime.types
modules
nginx.conf
scgi_params
uwsgi_params
root@b470f4d45637:/# ps aux
bash: line 1: ps: command not found
root@b470f4d45637:/# exit
exit

La salida permite ver varias cosas:

  • La imagen oficial de nginx se basa en Debian 13 (trixie).
  • b470f4d45637, que aparece en el prompt, es el nombre de host del contenedor; de forma predeterminada, es el ID del contenedor.
  • El contenedor no incluye el comando ps. La imagen oficial solo contiene lo necesario para ejecutar nginx, y se han eliminado muchas herramientas habituales. Es normal. Si necesitas herramientas de depuración, puedes instalarlas temporalmente (apt-get update && apt-get install -y procps) o usar docker top para consultar el contenedor desde fuera.

Escribe exit para salir; el contenedor seguirá ejecutándose.

Modificar el contenido de la página web

Cambia la página de inicio dentro del contenedor y vuelve a cargar el navegador:

$ docker exec web sh -c 'echo "<h1>Hello from my first container</h1>" > /usr/share/nginx/html/index.html'

$ curl -s http://localhost:8080
<h1>Hello from my first container</h1>
Página de inicio de nginx después de modificarla
Después de modificar index.html en el contenedor, el navegador muestra el nuevo contenido al instante

Modificar directamente los archivos dentro de un contenedor solo es útil para pruebas temporales. Al eliminar el contenedor, los cambios desaparecen. La forma correcta es montar los archivos de la página web en el contenedor (consulta Volume) o incluirlos en un Dockerfile.

Detener, iniciar y eliminar

$ docker stop web
web

$ docker ps -a
CONTAINER ID   IMAGE         COMMAND                  CREATED              STATUS                              PORTS     NAMES
b470f4d45637   nginx:1.30    "/docker-entrypoint.…"   12 seconds ago       Exited (0) Less than a second ago             web
786dd898c04b   hello-world   "/hello"                 About a minute ago   Exited (0) About a minute ago                 frosty_shirley

$ docker start web
web

$ curl -s http://localhost:8080
<h1>Hello from my first container</h1>

$ docker rm web
Error response from daemon: cannot remove container "web": container is running: stop the container before removing or force remove

$ docker rm -f web
web

$ docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED              STATUS                          PORTS     NAMES
786dd898c04b   hello-world   "/hello"   About a minute ago   Exited (0) About a minute ago             frosty_shirley
  • docker stop: detiene el contenedor, pero este sigue existiendo. Puedes verlo con docker ps -a y su estado es Exited.
  • docker start: vuelve a iniciar un contenedor existente; la página de inicio que modificaste también sigue ahí.
  • docker rm: elimina un contenedor detenido. Si lo usas con un contenedor en ejecución, aparecerá el error container is running de arriba. Primero ejecuta docker stop o añade -f para forzar su eliminación.

En la lista de docker ps -a también aparece el contenedor hello-world que ejecutaste en la sección anterior: terminó de ejecutarse (Exited (0)), pero no se eliminó. Los contenedores a los que no asignas un nombre con --name reciben uno aleatorio, como frosty_shirley.

Al eliminar el contenedor, también desaparece la página de inicio que modificaste. Si inicias un contenedor nuevo con la misma imagen, verás la página de bienvenida original de nginx.

Ejecutar un comando puntual

No todos los contenedores tienen que ejecutarse de forma continua. Este contenedor ejecuta un solo comando y termina; --rm hace que se elimine automáticamente al terminar:

$ docker run --rm ubuntu:26.04 cat /etc/os-release
Unable to find image 'ubuntu:26.04' locally
26.04: Pulling from library/ubuntu
06ad70e463aa: Pull complete
4e07a0f12b2c: Pull complete
Digest: sha256:f144425ff09be612d6d9ad965196e9cdc23dae1f42110a8a11a3e9a8198759f7
Status: Downloaded newer image for ubuntu:26.04
PRETTY_NAME="Ubuntu 26.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="26.04"
VERSION="26.04.1 LTS (Resolute Raccoon)"
VERSION_CODENAME=resolute
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=resolute
LOGO=ubuntu-logo

Este contenedor Ubuntu solo incluye los archivos del espacio de usuario de Ubuntu; no tiene proceso de arranque ni escritorio, y tarda un instante en iniciarse y terminar.

Usar la interfaz gráfica de Docker Desktop

En Windows y macOS, también puedes realizar con el ratón en Docker Desktop todos los pasos anteriores.

Buscar y descargar una imagen

Escribe el nombre de la imagen en el cuadro de búsqueda de la parte superior, elige la versión que quieras (Tag) y pulsa Pull para descargarla o directamente Run:

Buscar imágenes en Docker Desktop
Busca una imagen en Docker Desktop; a la derecha puedes elegir el Tag y pulsar Pull o Run. Imagen: documentación oficial de Docker (Apache-2.0)

Configurar y ejecutar un contenedor

Después de pulsar Run, despliega Optional settings para configurar el nombre del contenedor, los puertos, Volume y las variables de entorno. Estas opciones corresponden a --name, -p, -v y -e de docker run:

Ventana de configuración para ejecutar un contenedor nuevo en Docker Desktop
Escribe 8080 en Host port; equivale a docker run -p 8080:80. Imagen: documentación oficial de Docker (Apache-2.0)

Ver y administrar contenedores

El menú de la izquierda, Containers, muestra todos los contenedores, igual que docker ps -a. Haz clic en el enlace de la columna Port(s) para abrirlo directamente en el navegador. Los botones de la derecha permiten detener, reiniciar y eliminar contenedores:

Lista de contenedores de Docker Desktop
Pantalla Containers: estado, puertos y botones de acción. Imagen: documentación oficial de Docker (Apache-2.0)

Al entrar en un contenedor, puedes ver pestañas como Logs (equivalente a docker logs), Exec (equivalente a docker exec) y Files (para explorar los archivos del contenedor):

Pestaña Files de un contenedor en Docker Desktop
La pestaña Files permite explorar y editar directamente los archivos del contenedor. Imagen: documentación oficial de Docker (Apache-2.0)

La interfaz gráfica facilita consultar el estado, pero en la práctica se suelen usar comandos: puedes incluirlos en documentos y scripts, y en los servidores Linux solo puedes operar mediante comandos.

Usuarios de Windows: diferencias en la sintaxis de los comandos

Los comandos de este tutorial usan bash de Linux/macOS. En Windows, los comandos de Docker son exactamente iguales, pero la sintaxis del terminal (shell) es distinta:

SintaxisLinux / macOS (bash)Windows PowerShellWindows CMD
Carpeta actual$(pwd)${PWD}%cd%
Continuación de línea\ al final de la línea` al final de la línea^ al final de la línea
Variable de entorno$HOME$env:USERPROFILE%USERPROFILE%
Entrada desde un archivo <SíNo compatibleSí

Los comandos de este tutorial que requieren una sintaxis distinta incluyen pestañas para Linux / macOS, Windows PowerShell y Windows CMD. Al seleccionar una, toda la página cambia a esa misma sintaxis. Por ejemplo, para montar la carpeta site actual en nginx:

docker run -d -p 8080:80 -v "$(pwd)/site:/usr/share/nginx/html:ro" nginx:1.30
docker run -d -p 8080:80 -v "${PWD}/site:/usr/share/nginx/html:ro" nginx:1.30
docker run -d -p 8080:80 -v "%cd%/site:/usr/share/nginx/html:ro" nginx:1.30

Algunos errores frecuentes (consulta los mensajes de error reales en Mensajes de error frecuentes):

  • En PowerShell, escribir "$PWD:/app" provoca un error; debes escribir "${PWD}:/app".
  • PowerShell no admite <; para restaurar una base de datos, usa docker cp. Los capítulos sobre bases de datos incluyen las instrucciones.
  • Si un script de shell editado en Windows usa saltos de línea CRLF, al ejecutarlo en un contenedor aparecerá no such file or directory.

También puedes usar Docker Desktop desde el terminal de WSL (por ejemplo, Ubuntu); en ese caso, puedes usar directamente la sintaxis de Linux de este tutorial.

Resumen

  • docker run -d -p puerto_host:puerto_contenedor --name nombre imagen inicia un contenedor en segundo plano y asigna puertos.
  • docker ps muestra los contenedores en ejecución; -a también incluye los que están detenidos.
  • docker logs muestra la salida; docker exec -it contenedor sh abre una sesión dentro del contenedor.
  • docker stop / start / rm -f permiten controlar y eliminar contenedores; cambiar directamente los archivos dentro de un contenedor solo es adecuado para pruebas temporales.

Ejercicios

  1. Inicia otro nginx y asigna el puerto 8081 del host: docker run -d -p 8081:80 --name web2 nginx:1.30. Abre http://localhost:8081 para comprobarlo.
  2. Usa docker ps para confirmar que ambos contenedores se están ejecutando a la vez y que cada uno tiene asignado un puerto distinto del host.
  3. Elimina ambos contenedores: docker rm -f web web2.

En la siguiente sección veremos las imágenes con más detalle: las reglas de nombres y etiquetas, cómo descargarlas, consultarlas y eliminarlas.

Preguntas frecuentes

¿No se abre http://localhost:8080?

Primero, usa docker ps para confirmar que el contenedor está en ejecución y que la columna PORTS muestra 0.0.0.0:8080->80/tcp. Si otro programa está usando el puerto 8080, docker run mostrará port is already allocated; cambia a -p 8081:80.

¿Por qué no hay comandos como ps o vim en el contenedor?

Las imágenes oficiales solo incluyen lo necesario para ejecutar el servicio, así ocupan menos y tienen menos vulnerabilidades. Para depurar, puedes usar docker exec para ejecutar las herramientas disponibles en la imagen, o iniciar otro contenedor que incluya herramientas.

¿Se pueden usar indistintamente el ID y el nombre del contenedor?

Sí. En los comandos puedes usar el nombre o los primeros caracteres del ID, siempre que no coincidan con los de otro contenedor.

Actualizado 14 de octubre de 2026