Optimizar Dockerfile con comandos RUN y scripts

Clase 21 de 34Curso de Docker Avanzado

Resumen

Domina la configuración de contenedores en Ubuntu con Dockerfile, scripts y docker exec. Aquí verás cómo instalar paquetes con RUN, modularizar con un script bash y mantener vivo un contenedor con docker run, optimizando tiempos con el cache de imagen y evitando sorpresas al ejecutar.

¿Cómo preparar un contenedor con Dockerfile y comandos run?

Configurar dependencias antes de desplegar es clave. En el Dockerfile se define la imagen base y se encadenan pasos con la palabra reservada RUN. Se actualizan paquetes y se instalan utilidades como curl, vim y git usando el operador de doble ampersand (&&) para optimizar capas y fallar rápido si algo sale mal. Al construir la imagen, se observó un tiempo total cercano a 133 segundos, con 117 segundos dedicados a la instalación de paquetes, lo que muestra el costo de este paso.

  • Imagen base: ubuntu:latest para avanzar rápido.
  • Comandos encadenados: operador && para actualizar e instalar en una sola capa.
  • Mensajes de estado: echo para confirmar instalación completada.
  • Capas: cada RUN agrega una capa nueva.
FROM ubuntu:latest

# Actualizar e instalar utilidades en una sola capa
RUN apt-get update \
    && apt-get install -y curl vim git \
    && echo "instalación completada"

# Mensajes de control en otra capa
RUN echo "Inicio de script" \
    && echo "Paso 1" \
    && echo "Paso 2" \
    && echo "Paso 3"

¿Cuándo mover la configuración a un script externo?

Cuando el Dockerfile empieza a volverse difícil de leer, conviene extraer la lógica a un script externo. Así mejoras legibilidad, puedes editar la configuración sin tocar el Dockerfile y mantienes un historial claro de cambios. El flujo: copiar el archivo al contenedor, dar permisos y ejecutarlo con RUN. Gracias al cache de la imagen, la segunda construcción bajó a unos 34 segundos con pasos reutilizados.

  • Legibilidad: separar la configuración en script.sh.
  • Reutilización: actualizar el script sin tocar el Dockerfile.
  • Capas explícitas: COPY, permisos y ejecución.
# script.sh
#!/bin/bash

echo "iniciando script"
apt-get update
apt-get install -y curl vim git
echo "instalación completada"
FROM ubuntu:latest

# Copiar el script de configuración
COPY script.sh /usr/local/bin/script.sh

# Dar permisos de ejecución y correr el script
RUN chmod +x /usr/local/bin/script.sh
RUN /usr/local/bin/script.sh

¿Cómo ejecutar y mantener vivo un contenedor con docker run y docker exec?

Un contenedor de Ubuntu se detiene si no hay un proceso en primer plano. A diferencia de NGINX, que espera solicitudes HTTP, aquí no existe un servicio que lo mantenga activo. Por eso, al ejecutar se puede usar el modo desacoplado y un comando que permanezca a la espera para evitar que el contenedor finalice.

  • Construcción con tag: docker build -t scripts .
  • Ejecución simple: puede salir de inmediato si no hay proceso activo.
  • Mantener con vida: usar -d, asignar nombre y dejar un proceso en espera con tail -f.
  • Ejecución remota: docker exec para correr comandos dentro del contenedor.
# Construir la imagen
docker build -t scripts .

# Ejecutar y mantener vivo el contenedor en segundo plano
docker run -d --name scripts scripts tail -f

# Ejecutar una secuencia de comandos dentro del contenedor
docker exec -it scripts bash -c "echo 'Ejecutando script en el contenedor'; \
  apt-get update; apt-get install -y curl vim git; \
  echo 'Instalación completada'"

Habilidades y decisiones clave: - Optimizar RUN: agrupar pasos con && para menos capas y más claridad. - Modularizar con script: mejor mantenimiento y escalabilidad del flujo. - Usar cache: aprovechar reconstrucciones más rápidas cuando no cambian capas base. - Elegir el modo de configuración: Dockerfile o script para reutilizar; docker exec para tareas únicas no escalables.

¿Tienes otra técnica para mantener procesos en primer plano o modularizar Dockerfile? Comparte tu experiencia y dudas en los comentarios.