Files
hechakuaa_bot/DEPLOY.md
markosbenitez 6487a7857c Add DEPLOY.md — guía completa de despliegue en VPS Ubuntu
Paso a paso para delegar el deploy a equipo técnico:
usuario dedicado, uv, .env seguro, cifrado de credenciales,
systemd service, firewall UFW, monitoreo con journalctl,
procedimiento de actualización y troubleshooting.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 11:20:48 -03:00

14 KiB
Raw Permalink Blame History

Guía de despliegue — Pedrito Hechakuaa en VPS Ubuntu

Destinatario: equipo técnico de InQuality
Entorno objetivo: VPS Ubuntu en Hostinger — pre-producción estable
Tiempo estimado: 3045 minutos
Acceso requerido: SSH root a la VPS + datos de configuración provistos por Marcos


Índice

  1. Antes de empezar — datos que necesitás de Marcos
  2. Conectarse a la VPS
  3. Crear usuario dedicado
  4. Instalar dependencias del sistema
  5. Clonar el repositorio
  6. Instalar dependencias del proyecto
  7. Configurar el archivo .env
  8. Cifrar las credenciales del PJ
  9. Verificar que el bot arranca
  10. Crear el servicio systemd
  11. Configurar el firewall
  12. Verificación final
  13. Monitoreo y logs
  14. Cómo actualizar el bot
  15. Troubleshooting

1. Antes de empezar

Antes de tocar la VPS, pedile a Marcos que te provea estos datos. Sin ellos no podés completar el deploy.

Dato Dónde conseguirlo Dónde va
FERNET_KEY Marcos la genera o te la pasa .env
TELEGRAM_BOT_TOKEN Token del bot de Telegram (de @BotFather) .env
TELEGRAM_CHAT_ID Chat ID de Telegram de Marcos (de @userinfobot) .env
Cédula de identidad del PJ Marcos Script de cifrado (paso 8)
Contraseña del sistema del PJ Marcos Script de cifrado (paso 8)
IP de la VPS Panel de Hostinger SSH

⚠️ Seguridad: No guardes la contraseña del PJ en ningún archivo, chat ni nota. El script de cifrado (paso 8) la pide interactivamente y la descarta de memoria al terminar. Solo persiste cifrada en .env.


2. Conectarse a la VPS

ssh root@<IP_DE_LA_VPS>

Si usás clave SSH (recomendado):

ssh -i ~/.ssh/id_rsa root@<IP_DE_LA_VPS>

Verificar que el sistema está actualizado:

apt update && apt upgrade -y

3. Crear usuario dedicado

El bot no debe correr como root. Creamos un usuario propio llamado pedrito.

# Crear usuario sin contraseña de login (solo acceso SSH)
adduser pedrito --disabled-password --gecos ""

# Verificar que se creó correctamente
id pedrito
# Salida esperada: uid=1001(pedrito) gid=1001(pedrito) groups=1001(pedrito)

Configurar acceso SSH para el usuario pedrito

# Crear directorio SSH para el usuario
mkdir -p /home/pedrito/.ssh

# Copiar las claves autorizadas de root (si ya tenés acceso por clave SSH como root)
cp /root/.ssh/authorized_keys /home/pedrito/.ssh/

# Dar los permisos correctos (obligatorio para que SSH funcione)
chown -R pedrito:pedrito /home/pedrito/.ssh
chmod 700 /home/pedrito/.ssh
chmod 600 /home/pedrito/.ssh/authorized_keys

Podés verificar el acceso abriendo una segunda terminal:

ssh pedrito@<IP_DE_LA_VPS>

Si entra sin pedir contraseña, todo está bien.


4. Instalar dependencias del sistema

# Aún como root
apt install -y git curl

Verificar Python 3.12+:

python3 --version

Si la versión es menor a 3.12:

apt install -y software-properties-common
add-apt-repository ppa:deadsnakes/ppa -y
apt update
apt install -y python3.12 python3.12-venv

5. Clonar el repositorio

A partir de acá trabajamos como el usuario pedrito:

# Cambiar al usuario pedrito
su - pedrito

# Verificar que estamos en el home correcto
pwd
# /home/pedrito

# Clonar el repo
git clone https://github.com/InqGit/hechakuaa_bot.git
cd hechakuaa_bot

# Verificar que los archivos están
ls -la
# Deberías ver: main.py, config.py, telegram_bot.py, poller.py, etc.

6. Instalar dependencias del proyecto

El proyecto usa uv como gestor de dependencias (más rápido que pip).

# Instalar uv (como usuario pedrito)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Cargar uv en el shell actual (sin necesidad de cerrar sesión)
source $HOME/.local/bin/env

# Verificar instalación
uv --version
# Salida esperada: uv 0.x.x

# Instalar todas las dependencias del proyecto en un entorno virtual
uv sync

# Verificar que el entorno virtual se creó
ls .venv/bin/python
# Salida esperada: .venv/bin/python

7. Configurar el archivo .env

⚠️ Importante: El .env se crea directamente en la VPS. Nunca se copia desde tu máquina ni se sube al repositorio. Tiene permisos 600 (solo lo puede leer pedrito).

# Estamos en /home/pedrito/hechakuaa_bot/
# Copiar el template
cp .env.example .env

# Editar el archivo
nano .env

Completar los siguientes campos (los demás se pueden dejar con sus valores por defecto):

FERNET_KEY=<clave que te pasó Marcos>
TELEGRAM_BOT_TOKEN=<token del bot de @BotFather>
TELEGRAM_CHAT_ID=<chat_id de Marcos>

Guardar y salir de nano: Ctrl+O, Enter, Ctrl+X.

Restringir permisos (obligatorio):

chmod 600 .env

# Verificar
ls -la .env
# Salida esperada: -rw------- 1 pedrito pedrito ... .env

Si la FERNET_KEY todavía no existe, generala así y anotala en un gestor de contraseñas:

uv run python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Copiá la salida (una cadena larga de letras y números) y pegala en .env como valor de FERNET_KEY.


8. Cifrar las credenciales del PJ

El bot nunca guarda la cédula ni la contraseña del PJ en texto plano. Este script las cifra con la FERNET_KEY y guarda el resultado cifrado en .env.

uv run python scripts/cifrar_credenciales.py

El script te va a pedir:

  1. Cédula de identidad — el usuario con el que Marcos entra a apps.csj.gov.py
  2. Contraseña — se escribe pero no se muestra en pantalla

Salida esperada al terminar:

✅ Credenciales cifradas y guardadas en .env
   PJ_USUARIO_ENC y PJ_PASSWORD_ENC actualizadas.

Verificar que se guardaron en .env:

grep "PJ_USUARIO_ENC" .env
# Debe mostrar una línea con un valor cifrado largo (no la cédula en texto plano)

9. Verificar que el bot arranca

Antes de configurar el servicio, probamos que todo funciona:

uv run python main.py

Salida esperada (en formato JSON, primeras líneas):

{"event": "pedrito_hechakuaa_iniciando", "level": "info", ...}
{"event": "database_iniciada", "level": "info", ...}
{"event": "bot_telegram_iniciado", "level": "info", ...}
{"event": "pedrito_hechakuaa_corriendo", "level": "info", ...}
{"event": "poller_iniciado", "level": "info", ...}
{"event": "login_exitoso", "level": "info", ...}

Si aparece "login_exitoso" el bot se conectó al PJ correctamente.

Detener el bot: Ctrl+C

Errores comunes en este paso

Mensaje de error Causa Solución
FERNET_KEY inválida La clave en .env es incorrecta o tiene espacios Verificar que no tiene espacios ni comillas en .env
Credenciales incorrectas (401) Cédula o contraseña del PJ incorrecta Repetir paso 8 con los datos correctos
telegram.error.InvalidToken TELEGRAM_BOT_TOKEN mal copiado Verificar el token en .env
ModuleNotFoundError uv sync no se ejecutó o falló Correr uv sync de nuevo

10. Crear el servicio systemd

El servicio systemd mantiene el bot corriendo en background, lo reinicia si cae, y lo levanta automáticamente al reiniciar la VPS.

Volver a root para crear el archivo de servicio:

exit   # salir del usuario pedrito, volver a root

Crear el archivo de servicio:

nano /etc/systemd/system/pedrito.service

Pegar exactamente este contenido:

[Unit]
Description=Pedrito Hechakuaa — Monitor judicial PY
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=pedrito
WorkingDirectory=/home/pedrito/hechakuaa_bot

# Usar el Python del entorno virtual directamente (no depende del PATH)
ExecStart=/home/pedrito/hechakuaa_bot/.venv/bin/python main.py

# Reiniciar automáticamente si el proceso cae
Restart=on-failure
RestartSec=15

# Seguridad: el proceso no puede escalar privilegios
NoNewPrivileges=true
PrivateTmp=true

# Logs a journald
StandardOutput=journal
StandardError=journal
SyslogIdentifier=pedrito

[Install]
WantedBy=multi-user.target

Guardar: Ctrl+O, Enter, Ctrl+X.

Activar e iniciar el servicio:

# Recargar la configuración de systemd para que detecte el nuevo servicio
systemctl daemon-reload

# Habilitar para que arranque en cada reboot
systemctl enable pedrito

# Iniciar el servicio ahora
systemctl start pedrito

# Verificar que está corriendo
systemctl status pedrito

Salida esperada de systemctl status pedrito:

● pedrito.service - Pedrito Hechakuaa — Monitor judicial PY
     Loaded: loaded (/etc/systemd/system/pedrito.service; enabled; ...)
     Active: active (running) since ...

El campo clave es Active: active (running). Si dice failed o inactive, ver la sección de Troubleshooting.


11. Configurar el firewall

El bot de Telegram usa polling saliente — no necesita puertos abiertos para funcionar. Solo habilitamos SSH para no quedarnos sin acceso.

# Como root
ufw allow OpenSSH
ufw --force enable
ufw status

Salida esperada:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere

Si en la VPS ya tenés otros servicios corriendo (nginx, etc.), agregá sus puertos antes de hacer ufw enable para no cortarlos:

ufw allow 80/tcp    # HTTP
ufw allow 443/tcp   # HTTPS

12. Verificación final

Revisar que todo quedó en orden:

# 1. El servicio está corriendo
systemctl status pedrito
# Esperado: active (running)

# 2. El bot se loguea al PJ y al bot de Telegram
journalctl -u pedrito -n 30
# Buscar: "login_exitoso" y "bot_telegram_iniciado"

# 3. El proceso existe
ps aux | grep "python main.py" | grep -v grep
# Debe mostrar el proceso del usuario pedrito

# 4. El .env tiene los permisos correctos
su - pedrito -c "ls -la /home/pedrito/hechakuaa_bot/.env"
# Debe mostrar: -rw------- 1 pedrito pedrito

# 5. El servicio se recupera de reinicios
# Opcional: reiniciar la VPS y verificar que el bot vuelve solo
reboot
# Esperar 1-2 minutos, reconectarse y correr:
systemctl status pedrito

Si todos los puntos pasan, el deploy está completo.
Avisarle a Marcos para que pruebe mandándole /start al bot en Telegram.


13. Monitoreo y logs

Ver logs en tiempo real

journalctl -u pedrito -f

Detener con Ctrl+C.

Ver los últimos N registros

journalctl -u pedrito -n 50

Ver logs de la última hora

journalctl -u pedrito --since "1 hour ago"

Ver logs de un día específico

journalctl -u pedrito --since "2026-05-25 00:00:00" --until "2026-05-25 23:59:59"

Buscar errores

journalctl -u pedrito -p err

Eventos útiles que buscar en los logs

Evento en el log Qué significa
login_exitoso Se conectó al PJ correctamente
polling_tenant_ok Revisión de notificaciones completada
polling_tenant_error Error en la revisión (ver tipo en el detalle)
pj_error_conexion El PJ no respondió (puede ser transitorio)
bot_notificacion_enviada Se envió una notificación a Telegram
onboarding_completado Un usuario completó el registro

14. Cómo actualizar el bot

Cuando hay cambios en el código (nuevo commit en el repo):

# Como pedrito (o desde root: su - pedrito)
cd /home/pedrito/hechakuaa_bot

# Traer los cambios
git pull

# Reinstalar dependencias si hubo cambios en pyproject.toml
uv sync

# Reiniciar el servicio para aplicar los cambios
# (hacerlo como root o con sudo)
exit   # si estabas como pedrito
systemctl restart pedrito

# Verificar que levantó bien
systemctl status pedrito
journalctl -u pedrito -n 20

Nota: El archivo .env y el directorio data/ no se tocan con git pull — están en .gitignore. Las credenciales y el historial de notificaciones persisten entre actualizaciones.


15. Troubleshooting

El servicio no arranca (failed)

# Ver el error específico
journalctl -u pedrito -n 50
systemctl status pedrito

ModuleNotFoundError: No module named 'X'

su - pedrito
cd hechakuaa_bot
uv sync
exit
systemctl restart pedrito

.venv/bin/python: No such file or directory

su - pedrito
cd hechakuaa_bot
uv sync   # esto crea el .venv
exit
systemctl restart pedrito

DB no inicializada El data/ no existe todavía. El bot lo crea solo al arrancar. Si persiste:

su - pedrito
mkdir -p /home/pedrito/hechakuaa_bot/data
exit
systemctl restart pedrito

El bot arranca pero no responde en Telegram

  1. Verificar que TELEGRAM_BOT_TOKEN en .env es correcto
  2. Verificar que TELEGRAM_CHAT_ID es el chat_id correcto de Marcos
  3. Revisar logs: journalctl -u pedrito -n 30
  4. Desde otro cliente probar que el bot existe: buscar @pedrito_hechakuaabot en Telegram

Error de credenciales del PJ (Credenciales incorrectas)

su - pedrito
cd hechakuaa_bot

# Repetir el cifrado de credenciales
uv run python scripts/cifrar_credenciales.py

exit
systemctl restart pedrito

La VPS se reinició y el bot no volvió

systemctl status pedrito
# Si dice "disabled":
systemctl enable pedrito
systemctl start pedrito

Ver si hay dos instancias corriendo (causa conflictos)

ps aux | grep "python main.py" | grep -v grep

Si hay más de una línea, matar todas y reiniciar el servicio:

pkill -f "python main.py"
systemctl start pedrito

Referencia rápida de comandos

# Estado del servicio
systemctl status pedrito

# Iniciar / detener / reiniciar
systemctl start pedrito
systemctl stop pedrito
systemctl restart pedrito

# Logs en tiempo real
journalctl -u pedrito -f

# Actualizar el bot
su - pedrito -c "cd hechakuaa_bot && git pull && uv sync"
systemctl restart pedrito

Repositorio: https://github.com/InqGit/hechakuaa_bot
Ante dudas, contactar a Marcos Benítez.