Mini aplicación web en Python + Streamlit creada para aprender Docker paso a paso.
Con este proyecto aprenderás a:
- ✅ Ejecutar una aplicación web en Python en local
- ✅ Crear tu propio Dockerfile
- ✅ Construir una imagen Docker
- ✅ Ejecutar un contenedor
- ✅ Etiquetar tu imagen para Docker Hub
- ✅ Subir tu imagen a Docker Hub
- ✅ Ejecutar la app desde Docker Hub
Este repositorio contiene dos ramas con objetivos distintos:
- Es la rama que deben clonar para realizar el ejercicio
- Contiene la aplicación en Python + Streamlit
- Presentación Docker en PDF
- NO incluye Dockerfile
- El objetivo es que el alumno:
- cree su propio Dockerfile
- construya la imagen Docker
- ejecute el contenedor
- trabaje con volúmenes
- suba su imagen a Docker Hub
👉 Esta es la rama que se debe usar para realizar el ejercicio.
- Contiene el proyecto completamente terminado
- Incluye:
- Dockerfile
- proyecto listo para ejecutarse
- guía de instalación de Docker Desktop
- Pensada como referencia o solución final
👉 Para acceder a esta rama:
git checkout docker_solution
hello_docker/
│
├── app.py # Aplicación Streamlit
├── requirements.txt # Dependencias Python
├── Dockerfile # Instrucciones para Docker
└── README.md # Este archivo
Antes de dockerizar, vamos a probar que todo funciona correctamente.
python -m venv venvWindows:
venv\Scripts\activateMac / Linux:
source venv/bin/activatepip install -r requirements.txtstreamlit run app.py🎉 La aplicación debería abrirse automáticamente en http://localhost:8501
Ahora vamos a crear un contenedor Docker para que la aplicación pueda ejecutarse en cualquier lugar.
Crea un archivo llamado Dockerfile (sin extensión) en la raíz del proyecto y añade el siguiente contenido:
# Imagen base de Python
FROM python:3.11-slim
# Establecer directorio de trabajo dentro del contenedor
WORKDIR /app
# Copiar el archivo de dependencias
COPY requirements.txt .
# Instalar las dependencias
RUN pip install --no-cache-dir -r requirements.txt
# Copiar el código de la aplicación
COPY app.py .
# Exponer el puerto 8501 (puerto por defecto de Streamlit)
EXPOSE 8501
# Comando para ejecutar la aplicación
CMD ["streamlit", "run", "app.py", "--server.address=0.0.0.0"]FROM python:3.11-slim→ Usa una imagen ligera de Python 3.11WORKDIR /app→ Crea y establece/appcomo directorio de trabajoCOPY requirements.txt .→ Copia el archivo de dependencias al contenedorRUN pip install...→ Instala las dependencias de PythonCOPY app.py .→ Copia el código de la aplicaciónEXPOSE 8501→ Indica que el contenedor escucha en el puerto 8501CMD [...]→ Comando que se ejecuta al iniciar el contenedor
Abre una terminal en la carpeta del proyecto y ejecuta:
docker build -t hello_docker .docker build→ Construye una imagen Docker-t hello_docker→ Asigna un nombre (tag) a la imagen.→ Indica que el Dockerfile está en el directorio actual
Una vez construida la imagen, ejecuta:
docker run -p 8501:8501 hello_dockerdocker run→ Ejecuta un contenedor desde una imagen-p 8501:8501→ Mapea el puerto 8501 del contenedor al puerto 8501 de tu máquinahello_docker→ Nombre de la imagen a ejecutar
🎉 Abre tu navegador en http://localhost:8501 y verás tu aplicación corriendo en Docker.
Nuestra aplicación guarda los nombres introducidos por el usuario en un archivo:
data/nombres.txt
Este archivo se crea automáticamente cuando ejecutas la app por primera vez.
Ejecuta el contenedor de forma normal:
docker run -p 8501:8501 hello_docker- Escribe varios nombres en la aplicación
- Verás que aparecen en la tabla
- Detén y elimina el contenedor:
docker ps
docker rm -f - Vuelve a ejecutar el contenedor:
docker run -p 8501:8501 hello_docker❌ Resultado: Los nombres se han perdido.
🧠 ¿Por qué? Los datos estaban dentro del contenedor, y los contenedores son temporales.
Ahora ejecuta el contenedor usando un volumen Docker:
docker run -p 8501:8501 -v datos_app:/app/data hello_docker-v datos_app:/app/data→ Crea un volumen llamadodatos_appy lo monta en/app/datadel contenedor
Prueba:
- Escribe varios nombres en la aplicación
- Verás que aparecen en la tabla
- Detén y elimina el contenedor:
docker ps
docker rm -f - Vuelve a ejecutar el contenedor con el mismo comando:
docker run -p 8501:8501 -v datos_app:/app/data hello_docker✅ Resultado: Los nombres siguen apareciendo.
🧠 Explicación: El volumen datos_app guarda los datos fuera del contenedor, por eso no se pierden.
# Ver todos los volúmenes
docker volume ls
# Ver detalles de un volumen específico
docker volume inspect datos_app
# Eliminar un volumen (CUIDADO: borra todos los datos)
docker volume rm datos_app
# Eliminar todos los volúmenes no usados
docker volume prune💡 Importante: Si eliminas el volumen con
docker volume rm datos_app, perderás todos los datos guardados.
Para compartir tu imagen con otros o ejecutarla en cualquier máquina, necesitas subirla a Docker Hub.
- Ve a hub.docker.com
- Crea una cuenta gratuita
- Anota tu nombre de usuario (lo necesitarás en los siguientes pasos)
docker loginIntroduce tu usuario y contraseña de Docker Hub.
Antes de subir la imagen, necesitas etiquetarla con tu nombre de usuario de Docker Hub y una versión:
docker tag hello_docker TU_USUARIO/hello_docker:v1.0
docker tag hello_docker TU_USUARIO/hello_docker:latestEjemplos:
- Si tu usuario es
gema:
docker tag hello_docker gema/hello_docker:v1.0
docker tag hello_docker gema/hello_docker:latest- Si tu usuario es
juan123:
docker tag hello_docker juan123/hello_docker:v1.0
docker tag hello_docker juan123/hello_docker:latest- Usuario: Docker Hub organiza las imágenes por usuario (como GitHub con los repositorios). El formato es:
usuario/nombre-imagen:version - Versión (
v1.0): Identifica versiones específicas de tu aplicación. Útil para mantener diferentes releases. - Tag
latest: Apunta siempre a la versión más reciente. Es la que se descarga por defecto si no especificas versión.
💡 Buena práctica: Siempre etiqueta con una versión específica (
v1.0,v2.0) Y conlatest. Así los usuarios pueden elegir una versión concreta o usar siempre la última.
docker push TU_USUARIO/hello_docker:v1.0
docker push TU_USUARIO/hello_docker:latestEjemplo:
docker push gema/hello_docker:v1.0
docker push gema/hello_docker:latest✅ Tu imagen ya está disponible públicamente en Docker Hub con ambas etiquetas.
Cualquier persona puede ejecutar tu aplicación de estas formas:
Usando la versión específica:
docker run -p 8501:8501 -v datos_app:/app/data TU_USUARIO/hello_docker:v1.0Usando la última versión (latest):
docker run -p 8501:8501 -v datos_app:/app/data TU_USUARIO/hello_docker:latestSin especificar versión (descarga latest por defecto):
docker run -p 8501:8501 -v datos_app:/app/data TU_USUARIO/hello_dockerEjemplo:
docker run -p 8501:8501 -v datos_app:/app/data gema/hello_docker:v1.0Docker descargará automáticamente la imagen desde Docker Hub y la ejecutará.
💡 Tip: Si haces cambios en tu app y quieres subir una nueva versión, cambia el número de versión (ej:
v2.0) y repite los pasos de etiquetado y push.
# Ver imágenes locales
docker images
# Ver contenedores en ejecución
docker ps
# Ver todos los contenedores (incluyendo detenidos)
docker ps -a
# Detener un contenedor
docker stop <container_id>
# Eliminar un contenedor
docker rm <container_id>
# Eliminar una imagen
docker rmi <image_name>
# Ver logs de un contenedor
docker logs <container_id>
# Ejecutar contenedor en segundo plano (detached mode)
docker run -d -p 8501:8501 hello_docker1. Crear Dockerfile
↓
2. docker build -t hello_docker .
↓
3. docker run -p 8501:8501 -v datos_app:/app/data hello_docker
↓
4. docker login
↓
5. docker tag hello_docker TU_USUARIO/hello_docker:v1.0
docker tag hello_docker TU_USUARIO/hello_docker:latest
↓
6. docker push TU_USUARIO/hello_docker:v1.0
docker push TU_USUARIO/hello_docker:latest
↓
7. Cualquiera puede ejecutar:
docker run -p 8501:8501 -v datos_app:/app/data TU_USUARIO/hello_docker:v1.0
o
docker run -p 8501:8501 -v datos_app:/app/data TU_USUARIO/hello_docker
Docker es una plataforma que permite empaquetar aplicaciones y sus dependencias en contenedores, asegurando que funcionen igual en cualquier entorno.
Es una plantilla de solo lectura que contiene todo lo necesario para ejecutar una aplicación (código, dependencias, configuración).
Es una instancia en ejecución de una imagen Docker. Es ligero, aislado y portable.
Docker Hub organiza las imágenes por usuario. Al etiquetar con usuario/nombre, Docker sabe a qué cuenta pertenece la imagen.
Sí, puedes usar tags adicionales:
docker tag hello_docker gema/hello_docker:v1.0
docker tag hello_docker gema/hello_docker:latest- ✅ Mismo entorno en desarrollo, testing y producción
- ✅ Fácil distribución de aplicaciones
- ✅ Aislamiento entre aplicaciones
- ✅ Escalabilidad y eficiencia
- ¿Error al construir? → Asegúrate de estar en la carpeta correcta (donde está el Dockerfile)
- ¿Puerto ocupado? → Cambia el puerto:
docker run -p 8502:8501 hello_docker - ¿Cambios no se reflejan? → Reconstruye la imagen:
docker build -t hello_docker . - ¿Contenedor no se detiene? → Usa
Ctrl+Codocker stop <container_id> - ¿Olvidaste tu container_id? → Usa
docker pspara verlo
Si has llegado hasta aquí, ya sabes cómo dockerizar una aplicación Python. Este conocimiento es fundamental en el desarrollo de software moderno.
