Dockerfile: qué es y cómo crear una imagen

Autor: Publicado

En resumen: Dockerfile es un archivo de texto con instrucciones que Docker utiliza para construir una imagen de la aplicación: un paquete que contiene su código, las herramientas necesarias y su configuración. A partir de esa imagen se pueden ejecutar contenedores, es decir, procesos aislados con un entorno preparado. Por tanto, Dockerfile describe cómo preparar la aplicación para ejecutarla, pero no es en sí un contenedor en ejecución.

Dockerfile, imagen y contenedor: tres cosas distintas

Un Dockerfile se puede comparar con una receta; la imagen, con el conjunto preparado siguiendo esa receta; y el contenedor, con una instancia de ese conjunto en ejecución. Una sola imagen puede servir para crear varios contenedores, por ejemplo, varias instancias de la misma aplicación.

En Dockerfile defines, entre otras cosas, el entorno base, los archivos que se copiarán, las dependencias que se instalarán y el comando de inicio predeterminado. Así no hace falta preparar manualmente cada servidor siguiendo instrucciones por separado. Cuando cambias el código o las dependencias, lo habitual es construir una nueva imagen.

Un contenedor no es una máquina virtual completa: utiliza el núcleo del sistema del entorno en el que funciona el motor de contenedores. La imagen ayuda a uniformar el entorno de la aplicación, pero no elimina todas las diferencias entre equipos. Siguen siendo importantes, por ejemplo, la arquitectura del procesador, la configuración de red y el acceso a los archivos.

¿Qué instrucciones contiene Dockerfile?

El archivo suele llamarse Dockerfile, sin extensión. Cada instrucción describe un paso concreto de la construcción o un ajuste de la imagen. Las más habituales son:

Es fundamental distinguir entre RUN y CMD. El comando RUN se ejecuta al crear la imagen, mientras que CMD solo se ejecuta al iniciar el contenedor. La instalación de dependencias suele corresponder a RUN, y el inicio del servidor, a CMD.

También existe ENTRYPOINT, que define el programa principal del contenedor. Se puede combinar con CMD para pasarle argumentos predeterminados a ese programa. Para un primer ejemplo sencillo basta con CMD.

Ejemplo sencillo: una página HTML en un contenedor

Supongamos que quieres ejecutar una página sencilla en local sin instalar Python en tu equipo. Necesitas tener Docker funcionando y un directorio con dos archivos: index.html y Dockerfile.

En el archivo index.html, introduce:

<!doctype html>
<html lang="es">
<meta charset="utf-8">
<title>Ejemplo de Docker</title>
<h1>La página funciona en un contenedor</h1>
</html>

El archivo Dockerfile puede tener este contenido:

FROM python:3.13-slim
WORKDIR /app
COPY index.html .
EXPOSE 8000
CMD ["python", "-m", "http.server", "8000", "--bind", "0.0.0.0"]

Docker utilizará una imagen que contiene Python, establecerá el directorio /app y copiará la página en él. Al iniciar el contenedor, ejecutará un servidor HTTP sencillo. La dirección 0.0.0.0 indica que el servidor escucha en todas las interfaces de red del contenedor, lo que permite acceder a él a través del puerto publicado.

En la terminal, dentro del directorio que contiene estos archivos, ejecuta:

docker build -t mi-pagina .
docker run --rm -p 127.0.0.1:8080:8000 mi-pagina

El primer comando construye la imagen y le asigna el nombre mi-pagina. El punto indica que el directorio actual es el contexto de construcción, es decir, el conjunto de archivos disponibles para el proceso de construcción. El segundo comando inicia el contenedor y conecta el puerto local 8080 con el puerto 8000 del contenedor.

Abre http://localhost:8080 en el navegador. Vincular el puerto a 127.0.0.1 limita el acceso al equipo local. Puedes detener el servidor con Ctrl+C, y la opción --rm eliminará el contenedor cuando termine. Es un ejemplo para aprender, no una configuración de servidor para producción.

¿Qué influye en la velocidad y la seguridad de la construcción?

Docker puede reutilizar los resultados de pasos anteriores gracias a la memoria caché. Cambiar los archivos utilizados por una instrucción puede obligar a repetir ese paso y los pasos posteriores que dependan de él. Por eso, en una aplicación con bibliotecas, a menudo se copia primero el archivo de dependencias y se instalan los paquetes; después se copia el código, que cambia con más frecuencia.

El archivo .dockerignore excluye del contexto de construcción los archivos innecesarios. Habitualmente se excluyen el directorio .git, los entornos locales, los registros y los archivos que contienen secretos. Esto reduce la cantidad de datos transferidos y el riesgo de incluir accidentalmente material confidencial.

No guardes contraseñas ni tokens en Dockerfile ni los copies a la imagen. Eliminar un secreto en un paso posterior no garantiza que desaparezca de las capas anteriores de la imagen. Proporciona los secretos necesarios durante la construcción mediante los mecanismos de secretos de BuildKit, y los datos que necesita la aplicación en ejecución mediante la configuración adecuada del entorno de ejecución.

En producción, considera ejecutar la aplicación con un usuario sin permisos de administrador. Controla también la versión de la imagen base: una etiqueta puede acabar apuntando a una imagen modificada, mientras que un digest identifica un contenido concreto. Consulta las versiones disponibles y el procedimiento de actualización en la documentación oficial de la imagen elegida.

¿Cuándo necesitas Dockerfile y cuándo Compose?

Dockerfile responde a la pregunta: «¿Cómo se construye la imagen?». Docker Compose sirve para describir y ejecutar un conjunto de servicios, por ejemplo, una aplicación, una base de datos y una caché, junto con sus redes, puertos y volúmenes. Un volumen es un mecanismo que permite almacenar datos con independencia del ciclo de vida de un contenedor individual.

Estas herramientas pueden trabajar juntas: Compose puede construir una imagen siguiendo un Dockerfile y después ejecutarla junto a una imagen de base de datos ya preparada. Si solo utilizas imágenes ya preparadas, no siempre necesitas tu propio Dockerfile.

Empieza por construir y ejecutar una imagen sencilla. Después, sustituye la página de ejemplo por tu propia aplicación, define explícitamente sus dependencias y comprueba qué archivos deben incluirse realmente en la imagen.

Consulta también: ¿Qué es una API?

Lee también

Descubre cómo PHP-FPM atiende peticiones PHP, en qué se diferencia de un servidor web y cómo ajustar sus procesos al tráfico y los recursos.
Conoce BIND, el software abierto de servidor DNS: sus funciones, cómo gestiona dominios y cuándo conviene instalarlo por tu cuenta.
Descubre qué son el registro REGON de Polonia y su número, en qué se diferencian de NIP y KRS y cómo verificar los datos de una empresa.