Skip to content

Commit c4741c1

Browse files
committed
Add Confetti Party web application with Flask and Docker support
1 parent d3ad99d commit c4741c1

File tree

4 files changed

+123
-0
lines changed

4 files changed

+123
-0
lines changed

01-contenedores/contenedores-iii/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,10 +881,28 @@ En este módulo hemos cubierto los aspectos fundamentales de la contenerización
881881

882882
## 🎓 Ejercicios propuestos
883883

884+
### 🐍 Aplicación de ejemplo: Confetti Party Web
884885

886+
Tu misión será contenerizar una aplicación web simple en Python que se encuentra en el directorio `confetti-web`.
885887

888+
Como ya te comenté al inicio de esta clase, siempre es recomendable ejecutar la aplicación localmente antes de contenerizarla para asegurarte de que funciona correctamente.
886889

890+
```bash
891+
# Instalar dependencias
892+
pip install -r requirements.txt
893+
894+
# Ejecutar la aplicación
895+
python app.py
896+
```
897+
898+
Haz clic en la URL local que te muestra la aplicación para verificar que la aplicación funciona correctamente.
899+
900+
901+
## 🌍 Ejercicio 2: Distribución multi-arquitectura y publicación
902+
903+
### 📋 Objetivo
887904

905+
Crear y publicar una imagen multi-arquitectura, de la aplicación anterior, en Docker Hub con al menos soporte para `linux/amd64` y `linux/arm64`. Implementar una estrategia de tagging efectiva y utilizar Docker Build Checks para asegurar la calidad de la imagen. Además, crear una configuración de Docker Bake para facilitar futuras construcciones.
888906

889907

890908
> [!SUCCESS]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from flask import Flask, render_template
2+
3+
app = Flask(__name__)
4+
5+
@app.route('/')
6+
def home():
7+
return render_template('index.html')
8+
9+
@app.route('/health')
10+
def health():
11+
return {'status': 'healthy', 'message': '🎉 Confetti app is running!'}, 200
12+
13+
if __name__ == '__main__':
14+
app.run(host='0.0.0.0', port=3000, debug=True)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Flask==2.3.3
2+
gunicorn==21.2.0
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<!DOCTYPE html>
2+
<html lang="es">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>🎉 Confetti Party!</title>
7+
<style>
8+
body {
9+
margin: 0;
10+
padding: 0;
11+
height: 100vh;
12+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
13+
display: flex;
14+
justify-content: center;
15+
align-items: center;
16+
font-family: 'Arial', sans-serif;
17+
overflow: hidden;
18+
}
19+
.container {
20+
text-align: center;
21+
color: white;
22+
z-index: 10;
23+
}
24+
h1 {
25+
font-size: 4rem;
26+
margin-bottom: 1rem;
27+
animation: bounce 2s infinite;
28+
}
29+
.subtitle {
30+
font-size: 1.5rem;
31+
opacity: 0.9;
32+
}
33+
.confetti {
34+
position: absolute;
35+
width: 10px;
36+
height: 10px;
37+
background: #ff6b6b;
38+
animation: confetti-fall 3s linear infinite;
39+
}
40+
.confetti:nth-child(2n) { background: #4ecdc4; }
41+
.confetti:nth-child(3n) { background: #45b7d1; }
42+
.confetti:nth-child(4n) { background: #f9ca24; }
43+
.confetti:nth-child(5n) { background: #f0932b; }
44+
.confetti:nth-child(6n) { background: #eb4d4b; }
45+
.confetti:nth-child(7n) { background: #6c5ce7; }
46+
47+
@keyframes confetti-fall {
48+
0% { transform: translateY(-100vh) rotate(0deg); }
49+
100% { transform: translateY(100vh) rotate(720deg); }
50+
}
51+
52+
@keyframes bounce {
53+
0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
54+
40% { transform: translateY(-20px); }
55+
60% { transform: translateY(-10px); }
56+
}
57+
</style>
58+
</head>
59+
<body>
60+
<div class="container">
61+
<h1>🎉 ¡Confetti Party! 🎉</h1>
62+
<p class="subtitle">¡Tu aplicación Python está funcionando perfectamente!</p>
63+
<p class="subtitle">🐳 Contenerizada con Docker</p>
64+
</div>
65+
66+
<script>
67+
// Generar confetti
68+
function createConfetti() {
69+
for (let i = 0; i < 50; i++) {
70+
const confetti = document.createElement('div');
71+
confetti.className = 'confetti';
72+
confetti.style.left = Math.random() * 100 + 'vw';
73+
confetti.style.animationDelay = Math.random() * 3 + 's';
74+
confetti.style.animationDuration = (Math.random() * 3 + 2) + 's';
75+
document.body.appendChild(confetti);
76+
77+
// Remover confetti después de la animación
78+
setTimeout(() => {
79+
confetti.remove();
80+
}, 5000);
81+
}
82+
}
83+
84+
// Crear confetti cada 2 segundos
85+
setInterval(createConfetti, 2000);
86+
createConfetti(); // Crear confetti inicial
87+
</script>
88+
</body>
89+
</html>

0 commit comments

Comments
 (0)