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.
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 imagendocker build -t scripts .# Ejecutar y mantener vivo el contenedor en segundo planodocker run -d --name scripts scripts tail -f
# Ejecutar una secuencia de comandos dentro del contenedordockerexec -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.
Yo no concuerdo con el profesor en este punto, entiendo la legibilidad, pero cuando se tienen personas nuevas que no entienden Docker a veces tener todo por separado se puede volver un tanto complicado de entender. Yo personalmente si dejo las instrucciones de mi Dockerfile completas ahí mismo.
Entiendo tu punto. Sin embargo, separar la configuración en un .sh tiene ventajas. Docker crea una capa por cada instrucción, así que ejecutar varios comandos desde un script reduce capas y mejora la eficiencia del build.
Además, mantener la lógica fuera del Dockerfile lo hace más limpio y fácil de mantener, solo actualizas el script sin tocar la base.
Esto aplica buenas prácticas de DevOps, enfocadas en la automatización y la consistencia entre entornos. Aprender a estructurar así los contenedores es parte de dominar Docker, no solo de usarlo.
Como punto importante, si se hace con docker exec... las instrucciones que se ejecutan solo se mantendran mientras el contenedor este en estado running, cuando se termine de ejecutar el contenedor se tendría que volver a agregar estas lineas en caso de que sean muy necesarias para el uso del contenedor. Considero que lo mejor es ejecutarlas desde la creación de la imagen, pero ya dependera que tan indispensables son.
Interesante, pero en este caso y siguiendo recomendaciones de clases anteriores la unica manera de hacer el exec es cuando el user tiene privilegios para los casos que se necesita, si hago update e install siguiendo los pasos como crear un usuario y evitar que sea root quien ejecute entonces la mejor opcion es crear el archivo y que este se ejecute al inicio. Algunas opciones son buenas pero siguiendo recomendaciones dada aqui no van todas de la mano pero todas son usables muy buen aporte.
El echo sirve de algo ahí? o sea, normalmente al ejecutar un pipeline o el build mismo eso se muestra literal el echo "mensaje" y no el mensaje sin más, o ese se ve en otro lugar en algún log o algo?
A parte del beneficio de estructura y legibilidad, se tiene algún otro beneficio separar estas configuraciones del dockerfile?
Sí, se reduce dramáticamente el espacio de compilación y la imagen resultante queda muy optimizada de tamaño, teniendo estrictamente lo necesario para el proyecto.