Ejecución del bot en segundo plano¶
En este artículo
Para que un bot de Python (o cualquier otro) se ejecute de forma continua, se reinicie automáticamente tras un fallo y se inicie después de un reinicio del servidor, el simple hecho de ejecutar python main.py no es suficiente. Necesitas un servicio de fondo completo.
A continuación, se presentan tres métodos probados: desde el sencillo screen hasta el de nivel industrial systemd. Elige según tus necesidades.
Preparación del entorno¶
-
Coloca el código del bot, por ejemplo, en
/home/user/bot: -
Crea y activa un entorno virtual para aislar las dependencias:
-
Instala las dependencias:
-
Prueba el lanzamiento manual:
Nota
No ejecutes el bot como root a menos que sea necesario. Es mejor crear un usuario dedicado:
Método 1. screen - lanzamiento rápido (para pruebas y desarrollo)¶
Pros: lo más fácil para empezar.
Cons: no se reinicia tras un error o reinicio — no es apto para producción.
Instalación:
Lanzamiento:
Gestión:
| Acción | Comando |
|---|---|
| Desconectarse de la sesión (dejar en segundo plano) | Ctrl + A, luego D |
| Ver lista de sesiones | screen -ls |
| Volver a la sesión | screen -r bot |
| Terminar la sesión desde dentro | Ctrl + A, luego K > Y |
Información
Tras un reinicio del servidor o un error del script, el bot permanecerá detenido. Úsalo solo para tareas temporales.
Método 2. systemd - estándar de Linux para servicios (recomendado)¶
Pros: autoinicio, reinicio ante errores, registro (logging), integración con el sistema.
Cons: requiere escribir un archivo de configuración.
-
Crea un archivo de unidad:
-
Pega la configuración (¡adapta las rutas y el usuario!):
[Unit] Description=Telegram Bot Service After=network.target StartLimitIntervalSec=30 StartLimitBurst=5 [Service] Type=simple User=botuser # ← ¡se recomienda que no sea root! Group=botuser WorkingDirectory=/home/user/bot ExecStart=/home/user/bot/venv/bin/python /home/user/bot/main.py Restart=always RestartSec=10 Environment="PYTHONUNBUFFERED=1" # para que los logs no se queden en el búfer # Seguridad (opcional, pero recomendado) NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ReadWritePaths=/home/user/bot/data/ # si el bot necesita acceso a datos [Install] WantedBy=multi-user.target -
Habilita el servicio:
-
Comprueba el estado y los logs:
Consejos de seguridad
Restringe el acceso del servicio a partes innecesarias del sistema (mediante ProtectSystem, ReadOnlyPaths); Si el bot solo necesita internet, añade RestrictNetwork=true y configura IPAddressAllow=...; Usa RuntimeDirectory= para archivos temporales.
Método 3. PM2 - gestor de procesos (para Node.js, pero admite Python)¶
Pros: simplicidad, logs integrados, monitorización, interfaz web.
Cons: requiere Node.js, es excesivo para bots de Python sencillos.
Instalación:
# Instalar Node.js y npm (si no están instalados)
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs
# Instalar PM2 de forma global
sudo npm install -g pm2
Inicia el bot de Python:
Comandos útiles:
| Comando | Propósito |
|---|---|
pm2 list | Lista de procesos |
pm2 logs my-bot | Ver logs |
pm2 monit | Monitorización en tiempo real |
pm2 startup | Configurar autoinicio tras el reinicio |
pm2 save | Guardar procesos actuales |
Información
Después de pm2 startup, sigue las instrucciones de la terminal; PM2 generará una unidad de systemd para el autoinicio.
Comparación de métodos¶
| Criterio | screen | systemd | PM2 |
|---|---|---|---|
| Autoinicio tras reinicio | No | Sí | Sí (requiere pm2 startup) |
| Reinicio ante error | No | Sí | Sí |
| Registro (Logging) | Solo en la sesión | journalctl | Logs integrados |
| Seguridad | Baja | Alta (ajustes de aislamiento) | Media |
| Complejidad de configuración | Baja | Media | Baja (pero requiere Node.js) |
| Apto para producción | No | Recomendado | Sí (si ya usas Node.js) |
Adicional
Configura alertas cuando el bot se detenga (por ejemplo, mediante systemd + healthchecks.io);
Actualiza regularmente las dependencias con pip list --outdated;
Usa archivos .env y python-dotenv para almacenar tokens (¡y exclúyelos de Git!).