La portabilidad es la principal ventaja de los contenedores Docker. Un servicio completo con todas sus dependencias puede empaquetarse en un único contenedor independiente del kernel Linux, distribución o modelo de despliegue. Este contenedor puede transferirse a cualquier host con Docker sin problemas de compatibilidad. Este enfoque simplifica la gestión comparado con arquitecturas de microservicios donde cada componente requiere contenedores separados.
Creamos un directorio para la aplicación:
mkdir app_tornado
Implementamos un servicio web usando el framework asíncrono Tornado 6.2 en servidor.py:
import tornado.ioloop
import tornado.web
puerto = 8000
class PrincipalHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hola, Tornado")
def crear_app():
return tornado.web.Application([
(r"/", PrincipalHandler),
])
if __name__ == "__main__":
app = crear_app()
app.listen(puerto)
tornado.ioloop.IOLoop.current().start()
Archivo de dependencias requisitos.txt:
tornado==6.2
Configuración de Nginx (config_nginx.conf) con balanceo de carga:
upstream cluster_tornado {
server localhost:8000;
server localhost:8001;
}
server {
listen 80;
location / {
proxy_pass http://cluster_tornado;
proxy_set_header Host $host;
}
}
Opciones de balanceo alternativas:
# Ponderación
upstream cluster {
server 192.168.1.10 peso=3;
server 192.168.1.11 peso=7;
}
# Persistencia IP
upstream cluster {
ip_hash;
server 192.168.1.10:8000;
}
Configuración de Supervisor (supervisor.conf):
[supervisord]
nodaemon=true
[program:nginx]
command=/usr/sbin/nginx
[group:servidores]
programs=tornado_puerto8000,tornado_puerto8001
[program:tornado_puerto8000]
command=python3 /app_tornado/servidor.py
directory=/app_tornado
autorestart=true
stdout=/var/log/tornado8000.log
[program:tornado_puerto8001]
command=python3 /app_tornado/servidor.py
directory=/app_tornado
autorestart=true
stdout=/var/log/tornado8001.log
Dockerfile para la construcción:
FROM python:3.8-slim
RUN apt update && apt install -y nginx supervisor
RUN mkdir /app_tornado
WORKDIR /app_tornado
COPY servidor.py requisitos.txt ./
RUN pip install -r requisitos.txt
COPY config_nginx.conf /etc/nginx/conf.d/
RUN rm /etc/nginx/sites-enabled/default
RUN mkdir /var/log/supervisor
COPY supervisor.conf /etc/supervisor/conf.d/
CMD ["/usr/bin/supervisord"]
Construir la imagen:
docker build -t app_tornado .
Ejecutar el contenedor:
docker run -d -p 80:80 app_tornado
Verificar procesos con Supervisor:
supervisorctl status
Gestión de procesos:
supervisorctl stop servidores:tornado_puerto8001
supervisorctl start servidores:tornado_puerto8001
Supervisor reinicia automáticamente los procesos terminados:
# Eliminar proceso manualmente
kill -9 [id_proceso]
# Supervisor crea nuevo proceso
supervisorctl status