Docker se ha convertido en una de las herramientas más utilizadas para desplegar aplicaciones en servidores Linux. Gracias a los contenedores podemos ejecutar aplicaciones y todos sus componentes de forma aislada, reproducible y sencilla de administrar.

En esta guía aprenderás a instalar Docker Engine y Docker Compose en Ubuntu y Debian utilizando el repositorio oficial de Docker.

El procedimiento está pensado para servidores VPS y puede utilizarse con diferentes versiones compatibles de Ubuntu y Debian sin depender de una versión concreta en los comandos.

Actualmente Docker ofrece soporte oficial, entre otras versiones, para Debian 11, Debian 12 y Debian 13.

Al terminar tendremos Docker funcionando, Docker Compose instalado y ejecutaremos nuestros primeros contenedores.


¿Qué es Docker?

Docker es una plataforma que permite ejecutar aplicaciones dentro de contenedores.

Un contenedor incluye la aplicación junto con las dependencias que necesita para funcionar, permitiendo mantener un entorno consistente independientemente del servidor donde lo ejecutemos.

Esto facilita tareas como:

  • Desplegar aplicaciones web.
  • Ejecutar bases de datos.
  • Alojar APIs.
  • Crear entornos de desarrollo.
  • Ejecutar varios servicios en una misma VPS.
  • Migrar aplicaciones entre servidores.
  • Automatizar despliegues.
  • Separar diferentes aplicaciones entre sí.

Por ejemplo, podemos ejecutar Nginx dentro de un contenedor sin instalar Nginx directamente en nuestro sistema operativo.


¿Qué es Docker Compose?

Docker Compose permite definir y administrar varios contenedores mediante un único archivo de configuración.

Normalmente utilizaremos un archivo llamado:

compose.yaml

o:

docker-compose.yml

Por ejemplo, una aplicación podría necesitar:

  • Un contenedor con Nginx.
  • Otro contenedor con PHP.
  • Otro con MariaDB.
  • Otro con Redis.

En lugar de iniciar manualmente cada servicio, Docker Compose permite levantar toda la infraestructura con:

docker compose up -d

En las versiones actuales debemos utilizar:

docker compose

en lugar del antiguo:

docker-compose

Docker considera actualmente la instalación independiente de docker-compose como un método legacy destinado principalmente a compatibilidad con instalaciones antiguas.


Requisitos previos

Antes de comenzar necesitaremos:

  • Un servidor Ubuntu o Debian.
  • Acceso mediante SSH.
  • Usuario root o permisos sudo.
  • Conexión a Internet.
  • Al menos 1 GB de RAM recomendado para realizar pruebas cómodamente.
  • Espacio disponible en disco.

Puedes comprobar qué sistema operativo utilizas con:

cat /etc/os-release

También puedes consultar la arquitectura:

dpkg --print-architecture

Normalmente veremos:

amd64

en servidores con procesadores x86-64.


1. Actualizar Ubuntu o Debian

Antes de instalar Docker es recomendable actualizar la información de los repositorios:

sudo apt update

Opcionalmente podemos actualizar los paquetes instalados:

sudo apt upgrade -y

2. Eliminar instalaciones antiguas de Docker

Si estamos trabajando con una VPS nueva probablemente podemos saltarnos este apartado.

Sin embargo, si anteriormente instalamos Docker desde los repositorios de Ubuntu o Debian, pueden existir paquetes que entren en conflicto con los paquetes oficiales.

Podemos comprobar si tenemos alguno instalado con:

dpkg -l | grep -E 'docker|containerd|runc'

Algunos paquetes antiguos o alternativos pueden llamarse:

docker.io
docker-compose
docker-compose-v2
docker-doc
podman-docker
containerd
runc

Si tienes una instalación existente en producción, no elimines paquetes sin comprobar primero qué contenedores y datos tienes almacenados.

En una instalación nueva podemos continuar directamente con el siguiente paso.


3. Instalar las dependencias necesarias

Docker utiliza una clave de firma para verificar los paquetes descargados desde su repositorio oficial.

Instalamos las herramientas necesarias:

sudo apt install ca-certificates curl -y

Ahora creamos el directorio donde almacenaremos las claves:

sudo install -m 0755 -d /etc/apt/keyrings

4. Añadir el repositorio oficial de Docker

Aquí debemos utilizar el comando correspondiente a nuestro sistema operativo.

Ubuntu

Si nuestro servidor utiliza Ubuntu, descargamos la clave oficial:

sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc

Permitimos su lectura:

sudo chmod a+r /etc/apt/keyrings/docker.asc

Ahora añadimos el repositorio:

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

Debian

Si utilizamos Debian:

sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc

Permitimos la lectura de la clave:

sudo chmod a+r /etc/apt/keyrings/docker.asc

Añadimos el repositorio oficial:

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

Estos comandos detectan automáticamente la arquitectura y el nombre en clave de la distribución, por lo que no necesitamos escribir manualmente valores como bookworm, trixie o noble.


5. Actualizar los repositorios

Después de añadir Docker ejecutamos:

sudo apt update

Si todo está correctamente configurado debería aparecer el repositorio de Docker entre los repositorios consultados.

Podemos comprobarlo también con:

apt-cache policy docker-ce

Si aparecen versiones disponibles de docker-ce, el repositorio está funcionando.


6. Instalar Docker Engine y Docker Compose

Ahora instalamos Docker junto con sus componentes principales:

sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

Con este único comando instalamos:

  • Docker Engine.
  • Docker CLI.
  • containerd.
  • Docker Buildx.
  • Docker Compose.

Este es el conjunto de paquetes utilizado actualmente en las instrucciones oficiales para Ubuntu y Debian.


7. Comprobar que Docker está funcionando

Podemos consultar el estado del servicio:

sudo systemctl status docker

Deberíamos encontrar algo similar a:

Active: active (running)

Si Docker no estuviera iniciado podemos arrancarlo manualmente:

sudo systemctl start docker

8. Hacer que Docker arranque automáticamente

En Ubuntu y Debian normalmente Docker queda configurado para iniciarse automáticamente.

Podemos asegurarnos ejecutando:

sudo systemctl enable docker

Y también podemos habilitar containerd:

sudo systemctl enable containerd

Una alternativa es ejecutar:

sudo systemctl enable --now docker

La opción --now habilita el servicio y lo inicia inmediatamente.


9. Comprobar la versión de Docker

Ejecutamos:

docker --version

También podemos obtener información más completa mediante:

docker version

Y consultar toda la información del servidor Docker:

docker info

10. Comprobar Docker Compose

Como hemos instalado el plugin oficial de Compose podemos ejecutar:

docker compose version

Deberíamos obtener una respuesta mostrando la versión instalada.

No debemos confundirlo con:

docker-compose

El comando moderno utiliza un espacio:

docker compose

Docker distribuye actualmente Compose para Linux mediante el paquete:

docker-compose-plugin

11. Ejecutar nuestro primer contenedor

Docker proporciona una imagen muy sencilla llamada hello-world para verificar que todo funciona.

Ejecutamos:

sudo docker run hello-world

Docker realizará varias acciones automáticamente:

  1. Buscará la imagen hello-world localmente.
  2. Al no encontrarla, la descargará.
  3. Creará un contenedor.
  4. Ejecutará el contenedor.
  5. Mostrará un mensaje indicando que Docker funciona correctamente.

La propia documentación oficial utiliza este contenedor para verificar una instalación correcta.


12. Ejecutar Docker sin sudo

Si intentamos ejecutar:

docker ps

es posible que recibamos un error de permisos.

Por defecto, podemos utilizar Docker mediante:

sudo docker ps

Si queremos ejecutar Docker sin escribir sudo constantemente, podemos añadir nuestro usuario al grupo docker.

sudo usermod -aG docker $USER

Después debemos cerrar nuestra sesión SSH y volver a conectarnos.

También podemos aplicar temporalmente el nuevo grupo mediante:

newgrp docker

Ahora probamos:

docker ps

Y:

docker run hello-world

Importante: pertenecer al grupo docker concede privilegios equivalentes a un nivel muy elevado sobre el servidor. Solo debemos añadir usuarios de confianza. Docker advierte expresamente de que los miembros de este grupo reciben privilegios de nivel root.


13. Ejecutar nuestro primer servidor Nginx con Docker

Ahora que Docker funciona podemos realizar una prueba más interesante.

Ejecutamos:

docker run -d \
  --name nginx-demo \
  -p 8080:80 \
  nginx

¿Qué significa cada parámetro?

-d

Ejecuta el contenedor en segundo plano.

--name nginx-demo

Asigna el nombre nginx-demo al contenedor.

-p 8080:80

Conecta el puerto 8080 de nuestro servidor con el puerto 80 del contenedor.

Finalmente:

nginx

es la imagen que queremos ejecutar.


14. Comprobar el contenedor

Podemos comprobar los contenedores activos con:

docker ps

Deberíamos encontrar nuestro contenedor:

nginx-demo

Ahora podemos acceder desde nuestro navegador mediante:

http://IP_DEL_SERVIDOR:8080

Si todo funciona aparecerá la página predeterminada de Nginx.


15. Ver todos los contenedores

El comando:

docker ps

muestra únicamente los contenedores actualmente activos.

Para mostrar también los contenedores detenidos:

docker ps -a

16. Detener un contenedor

Podemos detener nuestro Nginx ejecutando:

docker stop nginx-demo

Para volver a iniciarlo:

docker start nginx-demo

Para reiniciarlo:

docker restart nginx-demo

17. Eliminar un contenedor

Primero lo detenemos:

docker stop nginx-demo

Después podemos eliminarlo:

docker rm nginx-demo

También podemos detenerlo y eliminarlo directamente:

docker rm -f nginx-demo

18. Ver imágenes descargadas

Podemos consultar las imágenes almacenadas en nuestro servidor con:

docker images

Después de ejecutar el ejemplo anterior deberíamos ver:

nginx
hello-world

Para eliminar una imagen:

docker rmi nginx

Docker no permitirá eliminar una imagen mientras existan determinados contenedores que todavía dependan de ella.


19. Crear nuestro primer proyecto con Docker Compose

Vamos a crear un pequeño proyecto utilizando Docker Compose.

Creamos un directorio:

mkdir ~/docker-nginx

Entramos:

cd ~/docker-nginx

Creamos el archivo:

nano compose.yaml

Añadimos:

services:
  web:
    image: nginx:latest
    container_name: nginx-compose
    restart: unless-stopped
    ports:
      - "8080:80"

Guardamos el archivo.


20. Iniciar el proyecto con Docker Compose

Dentro del directorio ejecutamos:

docker compose up -d

La opción:

-d

hace que los contenedores se ejecuten en segundo plano.

Podemos comprobar su estado:

docker compose ps

También podemos comprobarlo mediante:

docker ps

21. Consultar los logs con Docker Compose

Para ver los registros:

docker compose logs

Para seguirlos en tiempo real:

docker compose logs -f

Podemos salir de la visualización con:

Ctrl + C

El contenedor continuará funcionando.


22. Reiniciar los contenedores de Docker Compose

Podemos reiniciar todos los servicios del proyecto con:

docker compose restart

Para detenerlos:

docker compose stop

Y volver a iniciarlos:

docker compose start

23. Detener y eliminar el proyecto

Para detener los servicios y eliminar los contenedores asociados:

docker compose down

Esto no elimina automáticamente las imágenes descargadas.

Si nuestro proyecto utiliza volúmenes y queremos eliminarlos también:

docker compose down -v

Ten cuidado con este último comando en producción, ya que un volumen puede contener datos importantes, como los archivos de una base de datos.


24. Actualizar una aplicación Docker

Una operación habitual consiste en descargar una versión más reciente de una imagen.

Por ejemplo:

docker compose pull

Después podemos recrear los contenedores:

docker compose up -d

Docker utilizará las imágenes actualizadas definidas en nuestro archivo Compose.


25. Actualizar Docker

Al haber instalado Docker mediante su repositorio APT oficial, las actualizaciones se administran mediante el gestor de paquetes.

Primero:

sudo apt update

Después podemos actualizar Docker mediante:

sudo apt upgrade

O actualizar específicamente sus paquetes:

sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Una de las ventajas de instalar Docker mediante el repositorio oficial en lugar de descargar binarios manualmente es precisamente poder administrar las actualizaciones mediante APT.


26. Comandos Docker más utilizados

Mostrar contenedores activos

docker ps

Mostrar todos los contenedores

docker ps -a

Mostrar imágenes

docker images

Descargar una imagen

docker pull nginx

Iniciar un contenedor

docker start nombre-contenedor

Detener un contenedor

docker stop nombre-contenedor

Reiniciar un contenedor

docker restart nombre-contenedor

Eliminar un contenedor

docker rm nombre-contenedor

Ver logs

docker logs nombre-contenedor

Seguir los logs en tiempo real

docker logs -f nombre-contenedor

Ver el consumo de recursos

docker stats

Ver información completa de Docker

docker info

27. Comandos Docker Compose más utilizados

Iniciar servicios

docker compose up -d

Ver servicios

docker compose ps

Ver logs

docker compose logs -f

Reiniciar

docker compose restart

Detener

docker compose stop

Detener y eliminar contenedores

docker compose down

Descargar imágenes nuevas

docker compose pull

Descargar imágenes y recrear servicios

docker compose pull
docker compose up -d

28. ¿Dónde guarda Docker sus datos?

Por defecto Docker almacena gran parte de sus datos en:

/var/lib/docker/

Containerd utiliza normalmente:

/var/lib/containerd/

En estas ubicaciones pueden almacenarse:

  • Imágenes.
  • Capas.
  • Contenedores.
  • Metadatos.
  • Volúmenes.
  • Datos internos de Docker.

No debemos eliminar manualmente estas carpetas mientras Docker esté funcionando.


29. Ver cuánto espacio utiliza Docker

Con el tiempo, las imágenes y contenedores antiguos pueden consumir una cantidad considerable de almacenamiento.

Podemos comprobar el uso mediante:

docker system df

Obtendremos información sobre:

  • Imágenes.
  • Contenedores.
  • Volúmenes.
  • Build cache.

30. Limpiar recursos de Docker

Podemos eliminar recursos que ya no estén siendo utilizados con:

docker system prune

Docker pedirá confirmación antes de realizar la limpieza.

Para incluir imágenes no utilizadas:

docker system prune -a

Hay que utilizar estos comandos con cuidado en servidores de producción.

Para consultar antes qué está consumiendo espacio:

docker system df

31. Consultar los logs del servicio Docker

Si Docker no inicia correctamente podemos consultar los registros de systemd.

sudo journalctl -u docker

Para mostrar únicamente las últimas líneas:

sudo journalctl -u docker -n 100 --no-pager

También podemos comprobar el servicio:

sudo systemctl status docker

32. Reiniciar Docker

Si necesitamos reiniciar completamente el daemon:

sudo systemctl restart docker

Podemos comprobar después:

sudo systemctl status docker

Ten en cuenta que reiniciar Docker puede afectar a los contenedores que estén ejecutándose.


33. Hacer que un contenedor vuelva a iniciarse automáticamente

En servidores VPS normalmente queremos que determinados servicios vuelvan a arrancar después de reiniciar la máquina.

Al ejecutar un contenedor podemos utilizar:

docker run -d \
  --restart unless-stopped \
  --name mi-nginx \
  -p 8080:80 \
  nginx

En Docker Compose podemos hacer lo mismo mediante:

services:
  web:
    image: nginx:latest
    restart: unless-stopped

De esta forma Docker intentará iniciar nuevamente el contenedor después de reiniciar el servidor, salvo que lo hayamos detenido expresamente.


34. Atención con Docker, UFW y los puertos públicos

Este apartado es especialmente importante si utilizamos Docker en un VPS público.

Al publicar un puerto de esta manera:

docker run -p 8080:80 nginx

estamos exponiendo ese puerto a través de Docker.

No debemos asumir que bloquear el puerto únicamente mediante determinadas reglas de UFW hará que deje de ser accesible.

Docker advierte que los puertos publicados mediante Docker pueden saltarse determinadas reglas gestionadas mediante UFW o firewalld.

Por ese motivo debemos revisar cuidadosamente qué puertos publicamos.

Por ejemplo:

ports:
  - "3306:3306"

podría hacer accesible una base de datos desde Internet si no existen restricciones adicionales.

Si únicamente necesitamos que otro contenedor acceda a MariaDB, normalmente no es necesario publicar el puerto 3306 públicamente.


35. Publicar un puerto únicamente en localhost

Si queremos que un servicio solo sea accesible desde el propio servidor podemos vincularlo a:

127.0.0.1

Por ejemplo:

docker run -d \
  --name nginx-local \
  -p 127.0.0.1:8080:80 \
  nginx

Ahora el servicio escucha únicamente a través de:

127.0.0.1:8080

En Docker Compose:

services:
  web:
    image: nginx:latest
    ports:
      - "127.0.0.1:8080:80"

Esta configuración resulta especialmente útil cuando utilizamos un reverse proxy delante de nuestros contenedores.


36. Error: permission denied al ejecutar Docker

Si obtenemos un error parecido a:

permission denied while trying to connect to the Docker daemon socket

podemos utilizar temporalmente:

sudo docker ps

O añadir nuestro usuario al grupo Docker:

sudo usermod -aG docker $USER

Después:

newgrp docker

Y probamos:

docker ps

Recuerda que añadir un usuario al grupo Docker implica concederle permisos muy elevados sobre el sistema.


37. Error: Cannot connect to the Docker daemon

Si recibimos:

Cannot connect to the Docker daemon

comprobamos primero:

sudo systemctl status docker

Si está detenido:

sudo systemctl start docker

Si sigue fallando podemos revisar:

sudo journalctl -u docker -n 100 --no-pager

38. Error: port is already allocated

Si Docker muestra:

port is already allocated

significa que el puerto que intentamos utilizar ya está ocupado.

Podemos comprobarlo con:

sudo ss -tulpn

Por ejemplo, para el puerto 80:

sudo ss -tulpn | grep :80

Podemos elegir otro puerto:

docker run -d -p 8081:80 nginx

39. Desinstalar Docker

Si queremos eliminar Docker Engine:

sudo apt purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras

Esto elimina los paquetes, pero Docker no elimina automáticamente todos los datos almacenados.

Si queremos borrar completamente imágenes, contenedores y volúmenes podemos eliminar:

sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

Advertencia: estos comandos eliminan permanentemente los datos de Docker. No los ejecutes en un servidor con información que quieras conservar.

También podemos eliminar el repositorio:

sudo rm -f /etc/apt/sources.list.d/docker.sources

Y su clave:

sudo rm -f /etc/apt/keyrings/docker.asc

¿Docker o una instalación tradicional?

Docker no sustituye necesariamente a las instalaciones tradicionales.

Para una página sencilla podemos instalar directamente:

Nginx + PHP + MariaDB

Pero Docker resulta especialmente cómodo cuando tenemos:

  • Varias aplicaciones.
  • Diferentes versiones de software.
  • Microservicios.
  • Entornos de desarrollo.
  • Aplicaciones que necesitamos migrar.
  • Servicios que dependen unos de otros.
  • Despliegues automatizados.
  • Aplicaciones distribuidas mediante imágenes Docker.

Por eso herramientas como paneles, gestores de aplicaciones, bases de datos y plataformas de desarrollo utilizan cada vez más contenedores.


¿Qué recursos necesita Docker?

Docker Engine en sí no necesita una VPS especialmente potente.

Lo que realmente determinará los recursos necesarios serán los contenedores que ejecutemos.

Por ejemplo, no consume lo mismo ejecutar únicamente:

Nginx

que ejecutar simultáneamente:

Nginx
Aplicación Node.js
MariaDB
Redis
Panel administrativo
Workers

Antes de elegir una VPS debemos tener en cuenta principalmente:

  • CPU.
  • Memoria RAM.
  • Almacenamiento.
  • Transferencia de datos.
  • Número de aplicaciones.
  • Bases de datos utilizadas.

Instalar Docker en una VPS

Docker es especialmente útil en servidores VPS porque disponemos de acceso completo al sistema y podemos administrar nuestros propios contenedores.

Con una VPS podemos utilizar Docker para desplegar aplicaciones como:

  • Nginx.
  • WordPress.
  • Nextcloud.
  • Gitea.
  • GitLab.
  • Redis.
  • MariaDB.
  • PostgreSQL.
  • Node.js.
  • Coolify.
  • Portainer.
  • Aplicaciones propias.

Si necesitas un servidor para tus proyectos Docker, puedes utilizar una VPS de ColdHosting con acceso root e instalar Ubuntu o Debian para seguir directamente esta guía.


Conclusión

Docker nos permite desplegar aplicaciones de una forma rápida, organizada y reproducible utilizando contenedores.

Para instalar Docker y Docker Compose en Ubuntu o Debian, el proceso fundamental consiste en:

  1. Actualizar el servidor.
  2. Instalar curl y los certificados necesarios.
  3. Añadir la clave oficial de Docker.
  4. Configurar el repositorio oficial.
  5. Instalar Docker Engine.
  6. Instalar Docker Compose mediante su plugin oficial.
  7. Ejecutar hello-world para comprobar la instalación.

Una vez instalado podremos administrar nuestros contenedores mediante comandos como:

docker ps
docker images
docker logs
docker stats

Y nuestros proyectos completos mediante:

docker compose up -d
docker compose ps
docker compose logs -f
docker compose pull
docker compose down

Con esto ya tenemos nuestro servidor Ubuntu o Debian preparado para desplegar aplicaciones utilizando Docker y Docker Compose.