Dockerfile con Ubuntu: Guía completa de principiante a avanzado para crear imágenes Docker

目次

1. Introducción

¿Qué son Docker y los Dockerfiles?

En los últimos años, Docker ha ganado rápidamente popularidad como una forma eficiente de simplificar los entornos de desarrollo y el despliegue de aplicaciones. Docker empaqueta aplicaciones y sus dependencias en una única unidad llamada “contenedor”, lo que permite que se ejecuten de forma consistente en diferentes entornos.

Para construir estos contenedores Docker, se necesita un plano llamado Dockerfile. Un Dockerfile es un archivo de texto que define la imagen del sistema operativo base, el software instalado, variables de entorno y otros detalles de configuración. Los desarrolladores pueden usarlo para crear automáticamente entornos personalizados.

¿Por qué usar Ubuntu como imagen base?

Al crear un Dockerfile, el primer paso es seleccionar una imagen de sistema operativo base. Entre las muchas opciones disponibles, Ubuntu es una de las más populares. Ubuntu es una distribución Linux basada en Debian conocida por su facilidad de uso y la configuración flexible del entorno, respaldada por un amplio ecosistema de paquetes.

Los Dockerfiles basados en Ubuntu ofrecen varias ventajas:

  • Documentación oficial y comunitaria extensa, lo que resulta en una curva de aprendizaje baja
  • Instalación sencilla de paquetes y herramientas mediante APT
  • Imágenes oficiales ligeras y mínimas (como ubuntu:20.04 y ubuntu:24.04 )

Propósito de este artículo y público objetivo

Este artículo se centra en la palabra clave “Dockerfile Ubuntu” y explica cómo crear Dockerfiles basados en Ubuntu de una manera fácil de entender para principiantes.

Cubre todo, desde la estructura básica de un Dockerfile hasta instrucciones paso a paso para construir un entorno Ubuntu, ejemplos de configuración de entornos de aplicaciones como Python y errores comunes con sus soluciones.

Este artículo está recomendado para:

  • Aquellos que desean crear entornos usando Dockerfiles por primera vez
  • Desarrolladores que quieren crear entornos de desarrollo reproducibles en Ubuntu
  • Cualquier persona que quiera profundizar su comprensión, incluidas técnicas de solución de problemas

2. Estructura básica de un Dockerfile

¿Qué es un Dockerfile y cuál es su función?

Un Dockerfile es como una receta para crear imágenes Docker. Define qué sistema operativo base usar, qué software instalar y cómo configurar el entorno.

Al ejecutar el comando docker build basado en este archivo, puedes crear fácilmente entornos de desarrollo y ejecución altamente reproducibles.

Beneficios de usar Dockerfiles:

  • Configuración automática del entorno (sin necesidad de repetición manual)
  • Elimina inconsistencias de entorno en el desarrollo en equipo
  • Fácil integración en pipelines CI/CD

Instrucciones de Dockerfile más usadas

Un Dockerfile está compuesto por múltiples instrucciones (directivas). A continuación se presentan algunas de las más usadas. Al combinarlas adecuadamente, puedes crear un Dockerfile basado en Ubuntu.

InstructionDescription
FROMSpecifies the base Docker image (e.g., FROM ubuntu:24.04)
RUNExecutes shell commands, typically for installing packages
COPYCopies local files into the image
ADDSimilar to COPY, but also supports URLs and archive extraction
WORKDIRSets the working directory
ENVDefines environment variables
CMDDefines the default command executed at container startup (can be overridden)
ENTRYPOINTDefines a command that is always executed at container startup

Ejemplo mínimo de Dockerfile basado en Ubuntu

A continuación se muestra un ejemplo muy básico de un Dockerfile que usa Ubuntu como imagen base.

FROM ubuntu:24.04

RUN apt-get update && apt-get install -y \
    curl \
    vim

CMD ["/bin/bash"]

Este Dockerfile usa Ubuntu 24.04 como imagen base, instala las utilidades curl y vim, y lanza una shell Bash cuando el contenedor se inicia.

Selección de la etiqueta Ubuntu adecuada

Las imágenes de Ubuntu Docker se publican en el repositorio oficial de Docker Hub. Aunque especificar ubuntu:latest usará la versión más reciente, se recomienda fijar explícitamente una versión.

Por ejemplo:

  • ubuntu:22.04 (LTS: Soporte a largo plazo, centrado en la estabilidad)
  • ubuntu:24.04 (Último LTS, centrado en nuevas funcionalidades)

Elige la versión según si tu prioridad es la estabilidad o las nuevas funcionalidades.

3. Práctico: Creando un Dockerfile basado en Ubuntu

Instalación de paquetes requeridos en un entorno Ubuntu

.Al crear un entorno Ubuntu mediante un Dockerfile, a menudo es necesario instalar paquetes adicionales. Por ejemplo, las siguientes utilidades se usan con frecuencia al configurar un entorno de desarrollo:

  • curl : Para descargar archivos y probar APIs
  • vim : Un editor de texto ligero
  • git : Sistema de control de versiones
  • build-essential : Herramientas esenciales para compilar programas en C/C++

Para instalar estos paquetes en un Dockerfile, utilice la instrucción RUN.

FROM ubuntu:24.04

RUN apt-get update && apt-get install -y \
    curl \
    vim \
    git \
    build-essential

Al ejecutar primero apt-get update, se asegura de que se obtengan las listas de paquetes más recientes antes de la instalación.

Configuración de la instalación no interactiva

En Ubuntu, apt-get install a veces puede requerir la intervención del usuario. Sin embargo, las operaciones interactivas no son posibles durante la construcción de imágenes Docker. Para evitarlo, se recomienda establecer una variable de entorno y habilitar el modo no interactivo.

ENV DEBIAN_FRONTEND=noninteractive

Esto suprime indicaciones como la selección de zona horaria o de locale y permite que las instalaciones se realicen sin problemas.

Reducción del tamaño de la imagen eliminando la caché innecesaria

Al usar APT, los archivos temporales descargados (caché) pueden quedar en la imagen, aumentando su tamaño final. Puede reducir el tamaño de la imagen eliminando la caché como se muestra a continuación:

RUN apt-get update && apt-get install -y \
    curl \
    vim \
    && rm -rf /var/lib/apt/lists/*

Combinar varios comandos en una única instrucción RUN también ayuda a evitar aumentos innecesarios en las capas de la imagen.

Buenas prácticas para escribir Dockerfiles

En entornos de desarrollo reales, se recomiendan ampliamente las siguientes buenas prácticas para Dockerfiles:

  • Combine instrucciones RUN siempre que sea posible para reducir el número de capas.
  • Defina explícitamente versiones y configuraciones mediante ENV.
  • Use comentarios para describir claramente el propósito de cada paso.
  • Evite dejar archivos innecesarios usando rm y --no-install-recommends.

Ejemplo:

RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    git \
    && rm -rf /var/lib/apt/lists/*

Este enfoque produce un Dockerfile más ligero y fácil de mantener.

4. Construcción y verificación de imágenes Docker

Construir una imagen Docker a partir de un Dockerfile

Una vez que su Dockerfile esté listo, el siguiente paso es construir una imagen Docker. Esto se hace con el comando docker build. Ejecute el siguiente comando en el directorio que contiene su Dockerfile:

docker build -t my-ubuntu-image .
  • La opción -t asigna un nombre (etiqueta) a la imagen. En este ejemplo, la imagen se llama my-ubuntu-image.
  • El punto (.) se refiere al directorio actual que contiene el Dockerfile.

Docker leerá las instrucciones del Dockerfile secuencialmente y construirá la imagen en consecuencia.

Verificar la imagen Docker construida

Después de que la imagen se haya construido correctamente, puede verificarla con el siguiente comando:

docker images

Esto muestra una lista de imágenes Docker almacenadas localmente, incluyendo la siguiente información:

  • REPOSITORY (nombre de la imagen)
  • TAG
  • IMAGE ID (identificador único)
  • CREATED (fecha de creación)
  • SIZE

Ejemplo:

REPOSITORY        TAG       IMAGE ID       CREATED          SIZE
my-ubuntu-image   latest    abcd1234abcd   5 minutes ago    189MB

Esto confirma que la imagen se ha registrado correctamente.

Ejecutar un contenedor Docker para la verificación

Para comprobar que la imagen creada funciona como se espera, inicie un contenedor Docker con el siguiente comando:

docker run -it my-ubuntu-image
  • La opción -it abre una sesión de terminal interactiva.
  • Si todo funciona, aparecerá un prompt de Bash, indicando que está dentro del contenedor Ubuntu.

Dentro del contenedor, puede verificar las herramientas instaladas con comandos como:

curl --version
vim --version

Si estos comandos funcionan correctamente, tu Dockerfile está configurado correctamente.

Limpieza de Imágenes y Contenedores No Utilizados

Las compilaciones repetidas y los experimentos pueden dejar imágenes y contenedores de Docker no utilizados en tu sistema. Se recomienda limpiarlos periódicamente usando los siguientes comandos:

  • Eliminar contenedores detenidos:
    docker container prune
    
  • Eliminar imágenes no utilizadas:
    docker image prune
    
  • Eliminar todos los datos no utilizados (usar con precaución):
    docker system prune
    

Estas operaciones ayudan a ahorrar espacio en disco y prevenir problemas potenciales.

5. Avanzado: Construyendo un Entorno de Python

Habilitando Python en un Dockerfile Basado en Ubuntu

Al construir un entorno de Ubuntu usando un Dockerfile, agregar un entorno de ejecución de Python habilita una amplia gama de casos de uso, incluyendo desarrollo, pruebas y aprendizaje automático. Aunque Python puede estar ya instalado en Ubuntu por defecto, es una práctica común configurarlo explícitamente para un mejor manejo de versiones y paquetes.

Instalando Python Usando APT

El enfoque más simple es instalar Python usando paquetes APT. A continuación, un ejemplo:

FROM ubuntu:24.04

RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip \
    && rm -rf /var/lib/apt/lists/*

Este método proporciona una versión estable de Python del sistema (como Python 3.10 o 3.12, dependiendo de la versión de Ubuntu). También puedes instalar paquetes adicionales de Python usando el comando pip.

Gestionando Versiones de Python con pyenv

Si necesitas una versión específica de Python o quieres cambiar entre múltiples versiones, usar pyenv es altamente recomendable.

El siguiente ejemplo muestra cómo instalar Python 3.11.6 usando pyenv en un Dockerfile:

FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
    git \
    curl \
    make \
    build-essential \
    libssl-dev \
    zlib1g-dev \
    libbz2-dev \
    libreadline-dev \
    libsqlite3-dev \
    wget \
    llvm \
    libncurses5-dev \
    libncursesw5-dev \
    xz-utils \
    tk-dev \
    libffi-dev \
    liblzma-dev \
    && rm -rf /var/lib/apt/lists/*

# Install pyenv
RUN git clone https://github.com/pyenv/pyenv.git ~/.pyenv

ENV PYENV_ROOT="$HOME/.pyenv"
ENV PATH="$PYENV_ROOT/bin:$PATH"

RUN echo 'eval "$(pyenv init --path)"' >> ~/.bashrc

# Install a specific Python version
RUN pyenv install 3.11.6 && pyenv global 3.11.6

Esta configuración proporciona un entorno de Python flexible y bien controlado.

Gestionando Paquetes con requirements.txt

La mayoría de los proyectos del mundo real requieren múltiples bibliotecas de Python. Estas dependencias se gestionan comúnmente usando un archivo requirements.txt.

Primero, crea un archivo requirements.txt en la raíz de tu proyecto:

flask==2.3.2
requests>=2.25.1
pandas

Luego, haz referencia a él en tu Dockerfile de la siguiente manera:

COPY requirements.txt /app/requirements.txt
WORKDIR /app

RUN pip install --no-cache-dir -r requirements.txt

Esto permite que todas las bibliotecas requeridas se instalen de una vez y mejora significativamente la reproducibilidad del entorno.

Mejores Prácticas

  • Al usar Python, crear un entorno virtual con virtualenv o venv ayuda a prevenir conflictos de dependencias.
  • Usar opciones de supresión de caché como --no-cache-dir reduce el tamaño de la imagen de Docker.
  • Ejecutar pip install --upgrade pip antes de instalar paquetes puede ayudar a evitar errores de instalación.

6. Problemas Comunes y Solución de Problemas

Errores de Permisos

Ejemplo:

Permission denied

Este error ocurre cuando los archivos copiados carecen de permisos de ejecución o cuando la propiedad de archivos y los usuarios de ejecución están mal configurados.

Solución:

  • Hacer el archivo ejecutable:
    RUN chmod +x script.sh
    
  • Cambiar la propiedad del archivo si es necesario:
    RUN chown root:root /path/to/file
    

Paquete No Encontrado o Fallo en la Instalación

Ejemplo:

E: Unable to locate package xxx

Este error suele ocurrir cuando no se ha ejecutado apt-get update o cuando el nombre del paquete es incorrecto.

Solución:

  • Siempre ejecute apt-get update antes de instalar paquetes:
    RUN apt-get update && apt-get install -y curl
    
  • Verifique los nombres de los paquetes y compruebe que no haya errores tipográficos

Errores Relacionados con la Red

Ejemplo:

Temporary failure resolving 'deb.debian.org'

Este error indica un problema de resolución DNS durante el proceso de compilación.

Solución:

  • Reiniciar el daemon de Docker puede resolver el problema:
    sudo systemctl restart docker
    
  • Revise la configuración DNS de Docker añadiendo servidores DNS en /etc/docker/daemon.json :
    {
      "dns": ["8.8.8.8", "8.8.4.4"]
    }
    

Compilación con Caché Obsoleta

Docker utiliza caché basada en capas para acelerar las compilaciones. Como resultado, los cambios en un Dockerfile pueden no reflejarse inmediatamente.

Solución:

  • Reconstruya sin caché:
    docker build --no-cache -t my-image .
    

El Contenedor Sale Inmediatamente o el Comando de Inicio No Se Ejecuta

Causas:

  • El comando especificado en CMD o ENTRYPOINT contiene un error
  • Usar CMD ["/bin/bash"] sin modo interactivo provoca una salida inmediata

Solución:

  • Inicie el contenedor en modo de depuración:
    docker run -it my-image /bin/bash
    
  • Comprenda las diferencias entre CMD y ENTRYPOINT y utilícelas adecuadamente

Al encontrarse y resolver estos problemas, sus habilidades de diseño de Dockerfiles mejorarán de forma constante. Cuando ocurran errores, lea detenidamente los mensajes y identifique qué instrucción y capa provocaron el problema.

7. Resumen

Puntos Clave para Crear Dockerfiles Basados en Ubuntu

Este artículo ofreció una explicación paso a paso de cómo construir entornos Ubuntu usando Dockerfiles, abarcando tanto temas fundamentales como avanzados. Repasemos los puntos principales:

  • Entender los fundamentos de Dockerfile es el primer paso. Instrucciones como FROM, RUN, CMD y ENV permiten crear entornos automatizados.
  • Ubuntu es una imagen base estable y flexible. Su amplio ecosistema de paquetes, gran comunidad de usuarios y versiones LTS la hacen ideal para entornos de desarrollo.
  • La gestión práctica de paquetes permite instalar las herramientas y bibliotecas necesarias. El uso correcto de apt-get, la limpieza de la caché y la instalación no interactiva son esenciales.
  • Construir entornos prácticos como Python está totalmente soportado por Dockerfiles. Herramientas como pyenv, pip y requirements.txt garantizan configuraciones reproducibles.
  • Las habilidades de solución de problemas impactan directamente en la estabilidad. Comprender permisos, redes y el comportamiento de la caché de compilación mejora significativamente la productividad.

Próximos Pasos en el Aprendizaje de Dockerfile

Una vez que se sienta cómodo usando Dockerfiles, puede ampliar sus habilidades más allá del desarrollo, hacia pruebas y despliegues en producción. Considere explorar los siguientes temas:

  • Gestionar configuraciones multi‑contenedor con Docker Compose
  • Integrarse con herramientas de CI/CD como GitHub Actions y GitLab CI
  • Trabajar con plataformas de orquestación de contenedores como Kubernetes

Documentación Oficial y Enlaces de Referencia

8. FAQ (Preguntas Frecuentes)

Q1. ¿Qué versión de Ubuntu debo elegir en un Dockerfile?

A1. En la mayoría de los casos, se recomienda elegir una versión LTS (Long Term Support) para obtener estabilidad y mantenimiento a largo plazo. Versiones como ubuntu:22.04 y ubuntu:20.04 son ampliamente usadas y cuentan con soporte durante cinco años.

Si necesita los paquetes más recientes o versiones de lenguajes más nuevas, puede optar por una versión más reciente como ubuntu:24.04, pero se recomienda realizar pruebas exhaustivas.

Q2. ¿Por qué apt-get install muestra “paquete no encontrado”?

.A2. La razón más común es no ejecutar apt-get update antes. Sin actualizar la lista de paquetes, APT no puede localizar los paquetes solicitados.

Ejemplo correcto:

RUN apt-get update && apt-get install -y curl

También asegúrese de que los nombres de los paquetes sean correctos y no estén obsoletos (por ejemplo, use python3 en lugar de python).

Q3. ¿Cómo establecer variables de entorno en un Dockerfile?

A3. Use la instrucción ENV para definir variables de entorno que estén disponibles tanto durante la construcción como en tiempo de ejecución del contenedor.

Ejemplo:

ENV DEBIAN_FRONTEND=noninteractive

Esto se usa comúnmente para suprimir los mensajes interactivos durante instalaciones de APT. Las variables de entorno también son útiles para la configuración de aplicaciones y claves API.

Q4. ¿Cuál es la diferencia entre CMD y ENTRYPOINT?

A4. Ambos especifican comandos que se ejecutan al iniciar un contenedor, pero su comportamiento difiere.

ItemCMDENTRYPOINT
OverridableCan be overridden by docker runGenerally not overridden (treated as fixed command)
Use CaseDefine a default commandDefine a command that must always run

Ejemplo:

CMD ["python3", "app.py"]
# vs
ENTRYPOINT ["python3"]
CMD ["app.py"]

En este último caso, puede pasar argumentos usando docker run my-image another_script.py.

Q5. ¿Por qué no se reflejan los cambios en mi Dockerfile?

A5. Docker utiliza la caché de compilación, lo que puede hacer que capas sin cambios se reutilicen incluso después de editar el Dockerfile.

Solución:

docker build --no-cache -t my-image .

Esto fuerza una recompilación completa y asegura que todos los cambios se apliquen.