Tutorial

Corre un bot 24/7 en un VPS de Vultr con systemd (Ubuntu 24.04)

Un VPS te da un servidor Linux completo por un precio mensual fijo. A cambio, las actualizaciones de seguridad y los respaldos son tu responsabilidad.

Tutorial3 min de lecturaActualizado

Tu laptopssh -i keySSH :22Vultr VPS (Ubuntu 24.04)ufwsolo permite 22 (polling)systemd: mybot.serviceusuario bot, Restart=on-failureHTTPSTelegramBot API1con long polling no hace falta abrir puertos de entrada2journalctl -u mybot -f para ver los logs
Figura 1. El bot corre como servicio de systemd sin privilegios; el firewall solo permite SSH.
  1. Crea la instancia

    En Vultr crea una instancia Cloud Compute con Ubuntu 24.04 LTS, la región más cercana a tus usuarios (Vultr tiene Ciudad de México, varias ciudades de EE. UU., São Paulo, Europa y Asia) y tu llave pública SSH. El 2026-10-19 la página de precios mostraba un plan Regular Performance de 1 vCPU / 1 GB a $5.00 USD al mes, suficiente para la mayoría de los bots pequeños. Hay un plan de $2.50 USD, pero solo con IPv6; úsalo únicamente si todas las APIs que llama tu bot soportan IPv6.

  2. Primer acceso: usuario, SSH y firewall

    ssh root@YOUR_SERVER_IP
    adduser --disabled-password --gecos "" admin
    usermod -aG sudo admin
    mkdir -p /home/admin/.ssh && cp ~/.ssh/authorized_keys /home/admin/.ssh/
    chown -R admin:admin /home/admin/.ssh
    passwd admin   # needed for sudo
    # disable password and root login over SSH
    printf 'PasswordAuthentication no\nPermitRootLogin no\n' > /etc/ssh/sshd_config.d/10-hardening.conf
    systemctl reload ssh
    ufw allow OpenSSH && ufw --force enable
    apt update && apt -y upgrade && apt -y install unattended-upgrades unzip

    Abre una segunda terminal y confirma que ssh admin@YOUR_SERVER_IP funciona antes de cerrar la sesión de root.

  3. Instala Node.js 22

    curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh
    less nodesource_setup.sh   # read before running
    sudo bash nodesource_setup.sh
    sudo apt -y install nodejs
    node --version
  4. Instala el bot con un usuario sin privilegios

    sudo useradd --system --home /opt/mybot --shell /usr/sbin/nologin bot
    sudo mkdir -p /opt/mybot/data
    cd /tmp && curl -LO https://botnetwork.tech/downloads/telegram-grammy.zip
    sudo unzip -o telegram-grammy.zip -d /opt/mybot
    cd /opt/mybot && sudo npm install --omit=dev
    sudo install -m 600 /dev/null /opt/mybot/.env
    sudo nano /opt/mybot/.env      # BOT_TOKEN=...  MODE=polling
    sudo chown -R bot:bot /opt/mybot

    El archivo con el token solo lo puede leer el usuario bot.

  5. Crea el servicio de systemd

    /etc/systemd/system/mybot.service

    [Unit]
    Description=mybot chat bot
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=simple
    User=bot
    WorkingDirectory=/opt/mybot
    EnvironmentFile=/opt/mybot/.env
    ExecStart=/usr/bin/node src/index.js
    Restart=on-failure
    RestartSec=5
    MemoryMax=256M
    NoNewPrivileges=true
    ProtectSystem=strict
    ProtectHome=true
    PrivateTmp=true
    ReadWritePaths=/opt/mybot/data
    
    [Install]
    WantedBy=multi-user.target
    sudo systemctl daemon-reload
    sudo systemctl enable --now mybot
    sudo systemctl status mybot
    bot@vps$ sudo systemctl status mybot● mybot.service - mybot chat bot Active: active (running) since Mon 2026-10-19 20:12:03 UTC Main PID: 2141 (node) Memory: 58.3M (max: 256.0M)$ journalctl -u mybot -n 2mybot[2141]: @mi_primer_demo_bot running with long polling1en ejecución2MemoryMax funciona
    Figura 2. Un servicio sano (ilustración).

    Restart=on-failure levanta el bot después de un fallo; enable lo inicia al arrancar. Las líneas Protect* limitan lo que podría tocar un bot comprometido. Genera una unidad para tu caso con el generador de configuración de hosting.

  6. Logs, actualizaciones y respaldos

    journalctl -u mybot -f                 # follow logs
    sudo systemctl restart mybot           # after changing code or .env
    sudo unattended-upgrade --dry-run       # security updates run daily

    La página de precios de Vultr (verificada el 2026-10-19) indica que los respaldos automáticos suman un 20% al precio de la instancia. También puedes copiar la carpeta de datos del bot fuera del servidor con una tarea cron. vultr.com/pricing

Solución de problemas

  • status=203/EXEC: la ruta de ExecStart es incorrecta. Ejecuta which node y corrígela.
  • EACCES / read-only file system: ProtectSystem=strict bloquea escrituras fuera de ReadWritePaths. Guarda archivos en /opt/mybot/data.
  • Modo webhook: entonces necesitas un dominio, TLS y un proxy inverso (Caddy o nginx) en el 443, y ufw allow 443. El long polling evita todo eso.