Mantenimiento Mensual VPS

Mantenimiento Mensual VPS

Lee las instrucciones para un mantenimiento mensual seguro para tu VPS Debian, pensado para que lo ejecutes rápido y mantengas siempre el sistema ligero y bajo control:

Revisar espacio en disco

df -h
  • Comprueba que la partición / no supere el 80% de uso.
  • Si ves que se acerca al límite, pasa al siguiente paso de limpieza.

Analizar qué ocupa más espacio

sudo du -h --max-depth=1 /var | sort -h
  • Localiza directorios pesados (/var/log/var/lib/var/www).
  • Si /var/log/journal vuelve a crecer, haz limpieza.

Limpiar logs del sistema

sudo journalctl --vacuum-size=500M
  • Mantiene los logs binarios de systemd por debajo de 500 MB.
  • Si ya configuraste el límite en journald.conf, este comando asegura la limpieza manual.

Rotar y vaciar logs de Apache/Nginx

sudo truncate -s 0 /var/log/apache2/access.log
sudo truncate -s 0 /var/log/apache2/error.log
  • Vacía los logs sin borrar los archivos.
  • Útil si tu web genera mucho tráfico.

Limpiar cachés de paquetes

sudo apt-get clean
sudo apt-get autoremove --purge
  • Estob orra paquetes descargados y dependencias que ya no se usan.
  • Recupera espacio en /var/cache/apt y /var/lib/apt.

Revisar bases de datos (si usas MariaDB/MySQL)

sudo du -h --max-depth=1 /var/lib/mysql | sort -h
  • Identifica tablas grandes.
  • Ejecuta OPTIMIZE TABLE en las que más ocupen para liberar espacio.

Comprobar procesos y servicios activos

htop
  • Revisa consumo de CPU y RAM.
  • Asegúrate de que no haya procesos zombis o servicios innecesarios.

Backup rápido

  • Haz copia de seguridad de /var/www y de tus bases de datos:
tar -czf backup-www-$(date +%F).tar.gz /var/www
mysqldump -u root -p --all-databases > backup-db-$(date +%F).sql
  • A continuación guarda los backups fuera del VPS si es posible.

✅ Resultado esperado

  • VPS siempre con espacio libre > 50%.
  • Logs controlados y nunca superiores a 500 MB.
  • Cachés y paquetes limpios.
  • Bases de datos optimizadas.
  • Backups recientes y listos para restaurar.

SCRIPT DE MANTENIMIENTO MENSUAL

Aquí tienes tu script de mantenimiento mensual para el VPS. Lo puedes guardar como vps-maintenance.sh, darle permisos de ejecución y lanzarlo cada vez que quieras revisar y limpiar tu servidor:

#!/bin/bash
# VPS Maintenance Script - Edition 
# Ejecutar con: sudo ./vps-maintenance.sh

echo "=====  Estado del disco ====="
df -h

echo ""
echo "===== 📂 Uso en /var ====="
du -h --max-depth=1 /var | sort -h

echo ""
echo "=====  Limpiando logs del sistema (máx 500MB) ====="
journalctl --vacuum-size=500M

echo ""
echo "=====  Limpiando logs de Apache ====="
truncate -s 0 /var/log/apache2/access.log 2>/dev/null
truncate -s 0 /var/log/apache2/error.log 2>/dev/null

echo ""
echo "=====  Limpiando cachés de paquetes ====="
apt-get clean
apt-get autoremove --purge -y

echo ""
echo "=====  Espacio en bases de datos ====="
du -h --max-depth=1 /var/lib/mysql | sort -h

echo ""
echo "===== ✅ Mantenimiento completado ====="
echo "Revisa arriba el estado del disco y bases de datos."

Pasos en tu VPS

  1. Entrar al editor y crear el archivo:
sudo nano /root/vps-maintenance.sh
  1. Pega dentro el contenido del script avanzado de mantenimiento.
  1. Guardar y salir de nano:
  • Pulsa CTRL + O → Enter para guardar.
  • Pulsa CTRL + X para salir.
  1. Dar permisos de ejecución al script:
sudo chmod +x /root/vps-maintenance.sh
  1. Probarlo manualmente:
sudo /root/vps-maintenance.sh

Cómo usarlo

1. Copia el contenido en un archivo:

nano vps-maintenance.sh

2. Dale permisos de ejecución:

chmod +x vps-maintenance.sh

3. Ejecútalo con privilegios:

sudo ./vps-maintenance.sh

✅ Resultado esperado

  • Verás un informe con el estado del disco y /var.
  • Los logs del sistema y Apache quedarán reducidos.
  • Cachés y paquetes sobrantes se eliminarán.
  • Tendrás un vistazo rápido al tamaño de tus bases de datos.

VERSION AVANZADA DEL SCRIPT DE MANTENIMIENTO

Aquí tienes la versión avanzada del script de mantenimiento que además de ejecutar las limpiezas y comprobaciones, guarda un informe con fecha en un archivo dentro de tu VPS (por ejemplo report-2025-12-06.txt). Con esto tendrás un histórico de cada mantenimiento mensual.

Script vps-maintenance.sh

#!/bin/bash
# VPS Maintenance Script -  Edition 
# Ejecutar con: sudo ./vps-maintenance.sh

# Nombre del informe con fecha actual
REPORT="/root/vps-report-$(date +%F).txt"

echo "===== 📊 Estado del disco =====" | tee $REPORT
df -h | tee -a $REPORT

echo "" | tee -a $REPORT
echo "===== 📂 Uso en /var =====" | tee -a $REPORT
du -h --max-depth=1 /var | sort -h | tee -a $REPORT

echo "" | tee -a $REPORT
echo "=====  Limpiando logs del sistema (máx 500MB) =====" | tee -a $REPORT
journalctl --vacuum-size=500M | tee -a $REPORT

echo "" | tee -a $REPORT
echo "=====  Limpiando logs de Apache =====" | tee -a $REPORT
truncate -s 0 /var/log/apache2/access.log 2>/dev/null
truncate -s 0 /var/log/apache2/error.log 2>/dev/null
echo "Logs de Apache vaciados" | tee -a $REPORT

echo "" | tee -a $REPORT
echo "=====  Limpiando cachés de paquetes =====" | tee -a $REPORT
apt-get clean
apt-get autoremove --purge -y | tee -a $REPORT

echo "" | tee -a $REPORT
echo "===== 📊 Espacio en bases de datos =====" | tee -a $REPORT
du -h --max-depth=1 /var/lib/mysql | sort -h | tee -a $REPORT

echo "" | tee -a $REPORT
echo "===== ✅ Mantenimiento completado =====" | tee -a $REPORT
echo "Informe guardado en $REPORT" | tee -a $REPORT

Cómo usarlo

COMANDOS EN NEGRITA

  1. Copia el contenido en un archivo: nano vps-maintenance.sh
  2. Dale permisos de ejecución: chmod +x vps-maintenance.sh
  3. Ejecútalo con privilegios: sudo ./vps-maintenance.sh

✅ Resultado esperado

  • Se ejecutan todas las limpiezas y comprobaciones.
  • Se genera un archivo de informe en /root/ con nombre tipo vps-report-2025-12-06.txt.
  • Cada mes tendrás un histórico con fecha, para comparar evolución del espacio y detectar crecimientos anómalos.

Configuración con cron

  1. Edita el cron del sistema:
sudo crontab -e
  1. Agrega esta línea al final:
0 3 1 * * /root/vps-maintenance.sh

Explicación:

  • 0 3 1 * * → se ejecuta a las 03:00 AM del día 1 de cada mes.
  • /root/vps-maintenance.sh → ruta completa al script que creaste.
  • El script ya genera un informe con fecha (/root/vps-report-YYYY-MM-DD.txt), así tendrás histórico mensual.

📂 Dónde ver los informes

Cada mes se guardará un archivo en /root/ con nombre tipo:

vps-report-2025-12-01.txt
vps-report-2026-01-01.txt

Puedes revisarlos con:

less /root/vps-report-2025-12-01.txt

✅ Resultado esperado

  • El mantenimiento se ejecuta automáticamente cada mes.
  • Los informes quedan archivados con fecha.
  • Tu VPS se mantiene limpio y controlado sin intervención manual.

Instrucciones para habilitar el envío por email

1. Instalar un agente de correo ligero

En Debian lo más sencillo es mailutils (usa postfix o exim como backend):

sudo apt-get update
sudo apt-get install mailutils -y

Durante la instalación te pedirá configurar postfix. En el caso de que solo quieres enviar correos (no recibir), selecciona «Internet Site» y pon tu dominio o hostname del VPS.

2. Modificar el script vps-maintenance.sh

Agrega al final del script, las siguientes líneas de código:

# Dirección de destino
EMAIL="tu-correo@ejemplo.com"

# Enviar el informe por email
mail -s "Informe VPS $(date +%F)" $EMAIL < $REPORT

3. Configuración con cron (ya lo tienes)

Tu cron quedaría así, ejecutando el script el día 1 de cada mes a las 03:00:

0 3 1 * * /root/vps-maintenance.sh

✅ Resultado esperado

  • Cada mes, el script se ejecuta automáticamente.
  • Se genera el informe en /root/vps-report-YYYY-MM-DD.txt.
  • Se envía un email con el informe adjunto al destinatario que configures.

Comandos para revisar espacio en el VPS

  • Espacio general en todas las particiones:
df -h

Muestra tamaño total, usado, disponible y porcentaje de uso en cada sistema de archivos.

  • Uso detallado en /var (donde suelen crecer logs, bases de datos y webs):
sudo du -h --max-depth=1 /var | sort -h

Lista los subdirectorios de /var ordenados por tamaño.

  • Uso detallado en /var/www (tus sitios web):
sudo du -h --max-depth=1 /var/www | sort -h

Te dice cuánto ocupa cada proyecto web.

  • Uso detallado en /var/log (logs del sistema y Apache):
sudo du -h --max-depth=1 /var/log | sort -h

Localiza qué servicio genera más registros.

  • Uso detallado en /var/lib (bases de datos, librerías, contenedores):
sudo du -h --max-depth=1 /var/lib | sort -h

Analiza si MySQL, apt o Docker están ocupando demasiado espacio.

✅ Recomendación

Si lo vas a anotar en tu informe, puedes dejarlo como bloque final:

# Comandos de comprobación de espacio en el VPS
df -h
sudo du -h --max-depth=1 /var | sort -h
sudo du -h --max-depth=1 /var/www | sort -h
sudo du -h --max-depth=1 /var/log | sort -h
sudo du -h --max-depth=1 /var/lib | sort -h
Debian 12

Debian 12

Debian 12 “Bookworm” es una distribución GNU/Linux reconocida por su estabilidad, seguridad y versatilidad. Requiere entre 1 y 2 GB de RAM y entre 4 y 10 GB de espacio en disco según la instalación, con un sistema base que ocupa alrededor de 1,2 GB. Sus prestaciones incluyen compatibilidad con múltiples arquitecturas, gran variedad de entornos de escritorio, mejoras en seguridad y soporte ampliado de hardware reciente.

📦 Tamaño del software y requisitos

  • Instalación mínima (sin utilidades estándar): ~1,0 GB en disco
  • Instalación estándar (amd64 con utilidades): ~1,2 GB en disco
  • Requisitos mínimos de hardware:
    • RAM: 512 MB (mínimo), 1 GB recomendado
    • Espacio en disco: 4 GB sin escritorio, 10 GB con escritorio
  • Requisitos recomendados:
    • Procesador: Pentium 4 a 1 GHz o superior
    • RAM: 2 GB para un entorno gráfico fluido

Características principales

Nombre en clave: Bookworm

Entornos de escritorio disponibles: GNOME, KDE Plasma, Xfce, LXQt, Cinnamon, MATE, entre otros

Gestión de paquetes: Más de 59.000 paquetes disponibles en repositorios oficiales

Soporte de idiomas: Extenso, con traducciones para la mayoría de lenguas

Firmware no libre incluido: Mejora la compatibilidad con hardware moderno (tarjetas Wi-Fi, gráficas, etc.)

Seguridad: Actualizaciones constantes y sistema de parches rápido

Compatibilidad: Funciona en múltiples arquitecturas (amd64, arm64, s390x, etc.)

Opciones de instalación: Instalador gráfico y en modo texto, imágenes para nube y contenedores

Prestaciones destacadas

  • Estabilidad y fiabilidad: Debian es referencia en servidores y entornos críticos
  • Rendimiento optimizado: Mejoras en velocidad de ejecución y gestión de recursos en Debian 12.10
  • Compatibilidad ampliada: Drivers actualizados para hardware reciente
  • Soporte a largo plazo (LTS): Garantiza actualizaciones de seguridad durante años
  • Versatilidad de uso:
    • Servidores web, bases de datos y entornos corporativos.
    • Escritorios personales con múltiples interfaces gráficas.
    • Imágenes para nube y virtualización.

Debian 12 combina ligereza en instalación (1–1,2 GB base) con robustez y seguridad, ofreciendo un sistema adaptable tanto para usuarios domésticos como para infraestructuras profesionales. Su soporte de hardware moderno, amplia gama de escritorios y miles de paquetes lo convierten en una de las distribuciones más completas y confiables del ecosistema Linux.

Puedes descargar Debian 12 “Bookworm” directamente desde la página oficial de Debian en este enlace: 👉 Descarga oficial de Debian 12

📥 Opciones de descarga

En la página oficial encontrarás distintas imágenes de instalación:

  • Netinst (instalador mínimo): Ideal para instalaciones ligeras, descarga solo lo esencial y el resto desde internet.
  • Imágenes completas (CD/DVD): Incluyen todos los paquetes, útiles para sistemas sin conexión.
  • Arquitecturas soportadas: amd64, arm64, i386, mips64el, mipsel, ppc64el, s390x, entre otras.
  • Métodos de descarga:
    • HTTP/FTP directo
    • BitTorrent
    • Jigdo (descarga eficiente de imágenes grandes)

Si trabajas con servidores VPS y proyectos web, lo más práctico es usar la imagen netinst amd64, ya que ocupa poco espacio (~300 MB) y te permite personalizar la instalación con solo los paquetes que necesitas.

Perfecto, Francisco 🌑🔥. Aquí tienes el enlace directo al ISO netinst amd64 de Debian 12 “Bookworm” (la opción más ligera y práctica para servidores y proyectos web):

👉 Debian 12 netinst amd64 ISO

📥 Detalles de esta descarga

  • Tamaño aproximado: ~300 MB
  • Uso recomendado: Instalación mínima con descarga de paquetes desde internet
  • Arquitectura: amd64 (64 bits, la más común en servidores y PCs modernos)
  • Versión: 12.6.0 (última actualización estable de Bookworm)

Si prefieres imágenes completas (DVD con todos los paquetes incluidos), también están disponibles en la misma carpeta oficial: 👉 Imágenes completas de Debian 12

Comandos SSH para instalar Debian 12 en un VPS

Aquí tienes una guía práctica con los comandos SSH para instalar Debian 12 en un VPS desde cero, suponiendo que estás accediendo a un servidor con consola KVM o instalación remota (como en Proxmox, Hetzner, OVH, etc.).

Supuestos previos

  • Tienes acceso SSH o consola al VPS (modo rescate o instalación manual).
  • El VPS está vacío o en modo de instalación.
  • Usarás el instalador oficial de Debian 12 (netinst).

Instalación manual vía SSH (modo avanzado)

1. Conéctate al VPS

bash

ssh root@IP_DEL_VPS

2. Descarga el instalador de Debian 12 netinst

bash

wget https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.6.0-amd64-netinst.iso -O debian12.iso

3. Monta la ISO (si el VPS lo permite)

bash

mkdir /mnt/debian12
mount -o loop debian12.iso /mnt/debian12

4. Inicia instalación desde la ISO (requiere consola KVM o reinicio con ISO montada)

Este paso depende del proveedor. En muchos VPS, debes:

  • Usar el panel para montar la ISO como CD-ROM
  • Reiniciar el VPS en modo instalación
  • Seguir el instalador gráfico o en modo texto

🧪 Alternativa: instalación automatizada con debootstrap

Si el VPS ya tiene un sistema base (ej. modo rescate), puedes instalar Debian 12 manualmente:

1. Instala debootstrap

bash

apt update && apt install debootstrap

2. Crea el sistema base

bash

debootstrap --arch=amd64 bookworm /mnt/debian http://deb.debian.org/debian

3. Chroot al nuevo sistema

bash

mount --bind /dev /mnt/debian/dev
mount --bind /proc /mnt/debian/proc
mount --bind /sys /mnt/debian/sys
chroot /mnt/debian

4. Configura el sistema

bash

echo "debian-vps" > /etc/hostname
apt update && apt install linux-image-amd64 grub-pc systemd

5. Instala GRUB y reinicia

bash

grub-install /dev/sda
update-grub
exit
reboot

✅ Resultado

Tu VPS arrancará con Debian 12 limpio, listo para instalar Apache, Nginx, PHP, WordPress o lo que necesites.

Script cloud-init para Debian 12

yaml

#cloud-config
hostname: debian-vps
timezone: Europe/Madrid
locale: es_ES.UTF-8

users:
  - name: francisco
    groups: sudo
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    ssh-authorized-keys:
      - ssh-rsa AAAA...tu_clave_ssh...

package_update: true
package_upgrade: true
packages:
  - curl
  - wget
  - git
  - htop
  - ufw
  - fail2ban
  - nginx

runcmd:
  - ufw allow OpenSSH
  - ufw allow 'Nginx Full'
  - ufw enable
  - systemctl enable fail2ban
  - echo "Instalación completa en Debian 12 VPS"

¿Cómo usarlo?

  1. En Hetzner Cloud o Contabo VPS:
    • Al crear el VPS, selecciona Debian 12 como imagen base.
    • En el campo “cloud-init” o “custom script”, pega el YAML anterior.
    • Asegúrate de incluir tu clave SSH pública en el campo correspondiente.
  2. Resultado:
    • VPS con Debian 12, usuario francisco, acceso SSH, firewall activo, Nginx instalado y Fail2Ban protegiendo.

SCRIPT Cloud-Init

Script cloud-init para LAMP + WordPress en Debian 12

yaml

#cloud-config
hostname: debian-vps
timezone: Europe/Madrid
locale: es_ES.UTF-8

users:
  - name: francisco
    groups: sudo
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    ssh-authorized-keys:
      - ssh-rsa AAAA...tu_clave_ssh...

package_update: true
package_upgrade: true
packages:
  - apache2
  - mariadb-server
  - php
  - php-mysql
  - libapache2-mod-php
  - curl
  - wget
  - unzip
  - ufw
  - fail2ban

runcmd:
  # Configuración básica de firewall
  - ufw allow OpenSSH
  - ufw allow 'Apache Full'
  - ufw enable

  # Configuración de MariaDB segura
  - mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'TuPasswordSeguro';"
  - mysql -e "DELETE FROM mysql.user WHERE User='';"
  - mysql -e "DROP DATABASE IF EXISTS test;"
  - mysql -e "FLUSH PRIVILEGES;"

  # Crear base de datos para WordPress
  - mysql -uroot -pTuPasswordSeguro -e "CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
  - mysql -uroot -pTuPasswordSeguro -e "CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'WpPasswordSeguro';"
  - mysql -uroot -pTuPasswordSeguro -e "GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';"
  - mysql -uroot -pTuPasswordSeguro -e "FLUSH PRIVILEGES;"

  # Descargar e instalar WordPress
  - wget https://wordpress.org/latest.tar.gz -O /tmp/wordpress.tar.gz
  - tar -xzf /tmp/wordpress.tar.gz -C /var/www/html/
  - chown -R www-data:www-data /var/www/html/wordpress
  - chmod -R 755 /var/www/html/wordpress

  # Configuración de Apache
  - echo "<VirtualHost *:80>
      ServerAdmin admin@localhost
      DocumentRoot /var/www/html/wordpress
      <Directory /var/www/html/wordpress>
          AllowOverride All
      </Directory>
      ErrorLog \${APACHE_LOG_DIR}/error.log
      CustomLog \${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>" > /etc/apache2/sites-available/wordpress.conf

  - a2ensite wordpress.conf
  - a2enmod rewrite
  - systemctl reload apache2

Resultado

  • VPS con Debian 12
  • Apache + PHP + MariaDB configurados
  • WordPress descargado y listo en /var/www/html/wordpress
  • Firewall activo y Fail2Ban protegiendo

👉 Este script lo pegas en el campo cloud-init al crear tu VPS en Hetzner, Contabo o cualquier proveedor que lo soporte.

script cloud-init optimizado para un VPS con Debian 12 + Nginx + PHP-FPM + MariaDB + WordPress, pensado para rendimiento y estabilidad:

Script cloud-init (Nginx + PHP-FPM + WordPress)

yaml

#cloud-config
hostname: debian-vps
timezone: Europe/Madrid
locale: es_ES.UTF-8

users:
  - name: francisco
    groups: sudo
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    ssh-authorized-keys:
      - ssh-rsa AAAA...tu_clave_ssh...

package_update: true
package_upgrade: true
packages:
  - nginx
  - mariadb-server
  - php-fpm
  - php-mysql
  - php-cli
  - php-curl
  - php-xml
  - php-zip
  - php-gd
  - php-mbstring
  - curl
  - wget
  - unzip
  - ufw
  - fail2ban

runcmd:
  # Configuración de firewall
  - ufw allow OpenSSH
  - ufw allow 'Nginx Full'
  - ufw enable

  # Configuración segura de MariaDB
  - mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'TuPasswordSeguro';"
  - mysql -e "DELETE FROM mysql.user WHERE User='';"
  - mysql -e "DROP DATABASE IF EXISTS test;"
  - mysql -e "FLUSH PRIVILEGES;"

  # Crear base de datos para WordPress
  - mysql -uroot -pTuPasswordSeguro -e "CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
  - mysql -uroot -pTuPasswordSeguro -e "CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'WpPasswordSeguro';"
  - mysql -uroot -pTuPasswordSeguro -e "GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';"
  - mysql -uroot -pTuPasswordSeguro -e "FLUSH PRIVILEGES;"

  # Descargar e instalar WordPress
  - wget https://wordpress.org/latest.tar.gz -O /tmp/wordpress.tar.gz
  - tar -xzf /tmp/wordpress.tar.gz -C /var/www/html/
  - chown -R www-data:www-data /var/www/html/wordpress
  - chmod -R 755 /var/www/html/wordpress

  # Configuración de Nginx para WordPress
  - echo "server {
      listen 80;
      server_name _;
      root /var/www/html/wordpress;

      index index.php index.html index.htm;

      location / {
          try_files \$uri \$uri/ /index.php?\$args;
      }

      location ~ \.php\$ {
          include snippets/fastcgi-php.conf;
          fastcgi_pass unix:/run/php/php8.2-fpm.sock;
          fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
          include fastcgi_params;
      }

      location ~ /\.ht {
          deny all;
      }
    }" > /etc/nginx/sites-available/wordpress

  - ln -s /etc/nginx/sites-available/wordpress /etc/nginx/sites-enabled/
  - nginx -t
  - systemctl reload nginx

Resultado

  • VPS con Debian 12
  • Nginx + PHP-FPM (más rápido que Apache para WordPress)
  • MariaDB configurado con base de datos y usuario para WordPress
  • WordPress instalado en /var/www/html/wordpress
  • Firewall activo y Fail2Ban protegiendo

Este script lo pegas en el campo cloud-init al crear tu VPS en Hetzner, Contabo o cualquier proveedor que lo soporte.

script cloud-init avanzado para tu VPS con Debian 12 + Nginx + PHP-FPM + MariaDB + WordPress, incluyendo optimización de rendimiento con Redis cache, PHP-FPM tunning y HTTPS con Let’s Encrypt.

Script cloud-init optimizado

yaml

#cloud-config
hostname: debian-vps
timezone: Europe/Madrid
locale: es_ES.UTF-8

users:
  - name: francisco
    groups: sudo
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    ssh-authorized-keys:
      - ssh-rsa AAAA...tu_clave_ssh...

package_update: true
package_upgrade: true
packages:
  - nginx
  - mariadb-server
  - php-fpm
  - php-mysql
  - php-cli
  - php-curl
  - php-xml
  - php-zip
  - php-gd
  - php-mbstring
  - redis-server
  - php-redis
  - certbot
  - python3-certbot-nginx
  - curl
  - wget
  - unzip
  - ufw
  - fail2ban

runcmd:
  # Firewall
  - ufw allow OpenSSH
  - ufw allow 'Nginx Full'
  - ufw enable

  # Configuración segura de MariaDB
  - mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'TuPasswordSeguro';"
  - mysql -e "DELETE FROM mysql.user WHERE User='';"
  - mysql -e "DROP DATABASE IF EXISTS test;"
  - mysql -e "FLUSH PRIVILEGES;"

  # Crear base de datos para WordPress
  - mysql -uroot -pTuPasswordSeguro -e "CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
  - mysql -uroot -pTuPasswordSeguro -e "CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'WpPasswordSeguro';"
  - mysql -uroot -pTuPasswordSeguro -e "GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';"
  - mysql -uroot -pTuPasswordSeguro -e "FLUSH PRIVILEGES;"

  # Descargar e instalar WordPress
  - wget https://wordpress.org/latest.tar.gz -O /tmp/wordpress.tar.gz
  - tar -xzf /tmp/wordpress.tar.gz -C /var/www/html/
  - chown -R www-data:www-data /var/www/html/wordpress
  - chmod -R 755 /var/www/html/wordpress

  # Configuración Nginx optimizada
  - echo "server {
      listen 80;
      server_name _;
      root /var/www/html/wordpress;

      index index.php index.html index.htm;

      location / {
          try_files \$uri \$uri/ /index.php?\$args;
      }

      location ~ \.php\$ {
          include snippets/fastcgi-php.conf;
          fastcgi_pass unix:/run/php/php8.2-fpm.sock;
          fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
          include fastcgi_params;
      }

      location ~ /\.ht {
          deny all;
      }
    }" > /etc/nginx/sites-available/wordpress

  - ln -s /etc/nginx/sites-available/wordpress /etc/nginx/sites-enabled/
  - nginx -t
  - systemctl reload nginx

  # Optimización PHP-FPM
  - sed -i 's/pm = .*/pm = dynamic/' /etc/php/8.2/fpm/pool.d/www.conf
  - sed -i 's/pm.max_children = .*/pm.max_children = 20/' /etc/php/8.2/fpm/pool.d/www.conf
  - sed -i 's/pm.start_servers = .*/pm.start_servers = 5/' /etc/php/8.2/fpm/pool.d/www.conf
  - sed -i 's/pm.min_spare_servers = .*/pm.min_spare_servers = 3/' /etc/php/8.2/fpm/pool.d/www.conf
  - sed -i 's/pm.max_spare_servers = .*/pm.max_spare_servers = 10/' /etc/php/8.2/fpm/pool.d/www.conf
  - systemctl restart php8.2-fpm

  # Configuración HTTPS con Let's Encrypt
  - certbot --nginx -d tu-dominio.com --non-interactive --agree-tos -m admin@tu-dominio.com

Resultado

  • VPS con Debian 12
  • Nginx + PHP-FPM optimizado para WordPress
  • MariaDB configurado con base de datos y usuario
  • Redis cache instalado y listo para usar con plugins de WordPress
  • Firewall + Fail2Ban activos
  • HTTPS automático con Let’s Encrypt
Solucionar Ingresos Bajos en AdSense

Solucionar Ingresos Bajos en AdSense

La solución a ingresos bajos en AdSense pasa por dos frentes: aumentar el tráfico cualificado y optimizar la colocación y formato de los anuncios. No basta con tener visitas; necesitas mejorar el valor del clic (CPC) y la visibilidad de los anuncios para que cada impresión rinda más.

Para colocar los anuncios de AdSense tú mismo en tu web (sin depender solo de los anuncios automáticos de Google), existen varias herramientas y plugins que te dan control total sobre dónde y cómo aparecen:

Programas y plugins para gestionar anuncios

WordPress

  • Ad Inserter: uno de los más usados. Permite insertar bloques de AdSense en cualquier parte (cabecera, sidebar, dentro de posts, después de párrafos, etc.) con reglas condicionales (por rol de usuario, dispositivo, categoría…).
  • Advanced Ads: muy completo, con opciones de rotación, pruebas A/B y segmentación.
  • WP Quads: heredero del clásico Quick AdSense, sencillo y rápido para colocar anuncios en entradas y páginas.

CMS o sitios sin WordPress

  • Google Ad Manager (antes DFP): plataforma oficial de Google para gestionar inventario de anuncios. Es más complejo, pero te da control absoluto sobre posiciones y campañas.
  • Insertar manualmente el código: copiando el bloque <ins class="adsbygoogle"> en tus plantillas (header.phpsidebar.phpsingle.php) o en módulos de tu constructor (Divi, Elementor).

Herramientas externas

  • AdRotate: plugin que permite gestionar no solo AdSense, sino también banners propios o de afiliados.
  • OIO Publisher (aunque menos actualizado): para vender espacios publicitarios directamente y combinar con AdSense.

Ventajas de usar un programa/plugin

  • Controlas exactamente dónde aparece cada anuncio.
  • Evitas repeticiones en la misma página.
  • Puedes ocultar anuncios a ciertos roles (como ya haces con “Profesional”).
  • Facilita pruebas: cambiar posiciones y ver qué da más ingresos (CTR y RPM).

Si decides usar un programa o plugin para colocar los anuncios manualmente (como Ad Inserter o Advanced Ads), lo recomendable es desactivar los anuncios automáticos de AdSense.

Diferencia entre ambos modos

  • Anuncios automáticos (Auto Ads)
    • Google decide dónde y cuántos anuncios mostrar.
    • Ventaja: cero configuración, rápido de activar.
    • Desventaja: poca personalización, riesgo de repetición o saturación en la página.
  • Anuncios manuales (bloques insertados por ti)
    • Tú eliges la posición exacta (ej. después del 2º párrafo, en sidebar, al final del post).
    • Puedes aplicar reglas condicionales (por rol de usuario, categoría, dispositivo).
    • Evitas duplicados y controlas la experiencia del visitante.

Qué hacer en tu caso

  1. Desactiva Auto Ads desde tu panel de AdSense → Configuración de anuncios → Apagar “Anuncios automáticos”.
  2. Inserta manualmente los bloques con un plugin (ej. Ad Inserter) o directamente en tu plantilla.
  3. Define reglas claras:
    • Mostrar solo a visitantes (no a “Profesional”).
    • Limitar a 2–3 anuncios por página.
    • Usar formatos rentables (in-article, anchor, matched content).

En resumen: sí, al usar un plugin para colocar anuncios tú mismo, lo ideal es desactivar los automáticos para evitar que Google meta anuncios extra en lugares no deseados.

Te muestro un paso a paso claro para que configures anuncios manuales en WordPress con Ad Inserter y desactives los automáticos de AdSense:

Desactivar anuncios automáticos en AdSense

  1. Entra en tu cuenta de Google AdSense.
  2. Ve a Anuncios → Resumen → Configuración de anuncios automáticos.
  3. Desactiva el interruptor de Auto Ads.
    • Esto evita que Google coloque anuncios adicionales sin tu control.

Instalar Ad Inserter en WordPress

  1. En tu panel de WordPress → Plugins → Añadir nuevo.
  2. Busca Ad Inserter e instálalo.
  3. Actívalo.

Insertar un bloque de AdSense

  1. Copia el código de anuncio desde tu cuenta de AdSense (ejemplo: <ins class="adsbygoogle" ...>).
  2. En WordPress → Ad Inserter → Bloque 1, pega el código.
  3. Configura dónde quieres que aparezca:
    • Before paragraph 2 → justo después del segundo párrafo.
    • Sidebar → en la barra lateral.
    • After content → al final del artículo.

Reglas condicionales

  • En Ad Inserter puedes definir:
    • Mostrar solo a visitantes (ocultar a roles como “Profesional”).
    • Diferenciar entre móvil y escritorio.
    • Limitar el número de anuncios por página.

Ejemplo visual de colocación recomendada

  • Cabecera (Header) → 1 anuncio tipo banner.
  • Dentro del artículo → 1 anuncio in-article después del 2º párrafo.
  • Sidebar → 1 anuncio vertical.
  • Final del artículo → 1 anuncio matched content o display.

Con esto tendrás 4 posiciones estratégicas, sin saturar al usuario y maximizando CTR y RPM.

MÁS INFORMACIÓN: AdSense

Guía para insertar un reloj analógico en WordPress

Guía para insertar un reloj analógico en WordPress

Mantén a la vista el Reloj Analógico en tu sitio de WordPress, fácil de insertar, y con un potente efecto visual. El Reloj Analógico se adapta a todos los dispositivos.

⏰ Añade un reloj analógico en tu WordPress

¿Quieres mostrar la hora en tu sitio web con un reloj analógico elegante? Aquí tienes un código completo que puedes insertar en el widget de barra lateral de tu WordPress.

RELOJ WEB

Pasos:

  1. Entra en tu panel de administración de WordPress.
  2. Ve a Apariencia > Widgets.
  3. Añade un widget de tipo HTML personalizado en la barra lateral.
  4. Copia y pega el siguiente código completo en el widget:

html

<html>
<head>
<title>RELOJ WEB</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.reloj-container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  max-width: 420px; /* tamaño máximo */
  margin: 0 auto;   /* centra horizontalmente */
  padding: 10px;
  box-sizing: border-box;
}
canvas {
  width: 100%;
  height: auto;
  display: block;
}
</style>
</head>

<body>
  <div class="reloj-container">
    <canvas id="my_canvas" width="420" height="420"></canvas>
  </div>

<script>
var angle_jump=6;
var dt= new Date();

sec = dt.getSeconds()*angle_jump;
var min=dt.getMinutes();
min=min*angle_jump; 
min=min + (sec/360)
var hour=dt.getHours();
hour=hour*30;   
hour=hour + (min/12);

var ang_second=90-sec;
var ang_minute=90-min;
var ang_hour=90-hour;

var r=100;
var my_canvas=document.getElementById("my_canvas");
var gctx = my_canvas.getContext("2d");

var x=my_canvas.width/2;
var y=my_canvas.height/2;
speed=1000;
arc_angle=10;

my_function=function my_function(){
gctx.clearRect(0, 0, my_canvas.width,my_canvas.height);

// círculo exterior con sombra
gctx.beginPath();
gctx.strokeStyle= '#0B033B';
gctx.lineWidth=10;
gctx.shadowColor = 'rgba(0,0,0,0.5)';
gctx.shadowBlur = 15;
gctx.shadowOffsetX = 5;
gctx.shadowOffsetY = 5;
gctx.arc(x,y,r*1.4,0,2*Math.PI);
gctx.stroke();

// reset sombra
gctx.shadowColor = 'transparent';
gctx.shadowBlur = 0;
gctx.shadowOffsetX = 0;
gctx.shadowOffsetY = 0;

gctx.lineWidth=1;

// números y marcas
var h=2;
gctx.textAlign = "center";
gctx.textBaseline = "middle";
gctx.font = '36px serif';

for(j=0;j<360;j += angle_jump){
  j_radian=j*(Math.PI/180);
  gctx.beginPath();
  gctx.strokeStyle= '#464623';

  if((j % (5*angle_jump))==0){
    var y1_text=y+ 0.85*r*Math.sin(j_radian);
    var x1_text=x+ 0.85*r*Math.cos(j_radian);
    if(h<12){ h=h+1; } else { h=1; }

    // sombra en números
    gctx.shadowColor = 'rgba(0,0,0,0.4)';
    gctx.shadowBlur = 6;
    gctx.shadowOffsetX = 2;
    gctx.shadowOffsetY = 2;
    gctx.fillText(h,x1_text,y1_text);

    // reset sombra
    gctx.shadowColor = 'transparent';
    gctx.shadowBlur = 0;
    gctx.shadowOffsetX = 0;
    gctx.shadowOffsetY = 0;

    // rayas largas en todos los números
    var y1_out = y + 1.05*r*Math.sin(j_radian);
    var x1_out = x + 1.05*r*Math.cos(j_radian);
    var y2_out = y + 1.3*r*Math.sin(j_radian);
    var x2_out = x + 1.3*r*Math.cos(j_radian);
    gctx.moveTo(x1_out,y1_out);
    gctx.lineTo(x2_out,y2_out);
    gctx.stroke();

  } else {
    // rayas normales
    var y1_out = y + 1.1*r*Math.sin(j_radian);
    var x1_out = x + 1.1*r*Math.cos(j_radian);
    var y2_out = y + 1.2*r*Math.sin(j_radian);
    var x2_out = x + 1.2*r*Math.cos(j_radian);
    gctx.moveTo(x1_out,y1_out);
    gctx.lineTo(x2_out,y2_out);
    gctx.stroke();
  }
}

// segundero
gctx.beginPath();
gctx.strokeStyle= '#7CC0F5';
var startAngle=(1/180) * (360-ang_second);
var a_end_ang=(1/180) * (360-(ang_second + 180 -arc_angle));
var a_start_ang=(1/180) *(360-(ang_second + 180 + arc_angle));
var y1=y+ r*Math.sin(startAngle*Math.PI);
var x1=x+ r*Math.cos(startAngle*Math.PI);
gctx.moveTo(x1,y1);
gctx.arc(x,y,0.3*r,a_start_ang*Math.PI,a_end_ang*Math.PI);
gctx.lineTo(x1,y1);
gctx.fillStyle = '#7CC0F5';
gctx.fill();
gctx.stroke();

// minutero
gctx.beginPath();
gctx.strokeStyle= '#181500';
var startAngle=(1/180) * (360-ang_minute);
var a_end_ang=(1/180) * (360-(ang_minute + 180 -arc_angle));
var a_start_ang=(1/180) *(360-(ang_minute + 180 + arc_angle));
var y1=y+ 0.9*r*Math.sin(startAngle*Math.PI);
var x1=x+ 0.9*r*Math.cos(startAngle*Math.PI);
gctx.moveTo(x1,y1);
gctx.arc(x,y,0.3*r,a_start_ang*Math.PI,a_end_ang*Math.PI);
gctx.lineTo(x1,y1);
gctx.fillStyle = '#181500';
gctx.fill();
gctx.stroke();

// horario
gctx.beginPath();
gctx.strokeStyle= '#181500';
var startAngle=(1/180) * (360-ang_hour);
var a_end_ang=(1/180) * (360-(ang_hour + 180 -(arc_angle*2)));
var a_start_ang=(1/180) *(360-(ang_hour + 180 + (arc_angle*2)));
var y1=y+ 0.8*r*Math.sin(startAngle*Math.PI);
var x1=x+ 0.8*r*Math.cos(startAngle*Math.PI);
gctx.moveTo(x1,y1);
gctx.arc(x,y,0.15*r,a_start_ang*Math.PI,a_end_ang*Math.PI);
gctx.lineTo(x1,y1);
gctx.fillStyle = '#181500';
gctx.fill();
gctx.stroke();

// círculo central
gctx.beginPath();
gctx.strokeStyle= '#000000';
gctx.arc(x,y,3,0,2*Math.PI); 
gctx.fillStyle = '#282746';
gctx.fill();
gctx.stroke();

my_function2();
}

my_function2=function my_function2(){
if(ang_second > -264){  
  ang_second=ang_second-angle_jump;
  setTimeout('my_function()',speed);
}else{
  ang_second=90;
  if(ang_minute > -264){
    ang_minute=ang_minute - angle_jump;
  }else{
    ang_minute=90;
    ang_hour=ang_hour-angle_jump;
  } 
  setTimeout('my_function()',speed);
}
}

my_function();
</script>
</body>
</html>

3. Guardar y comprobar

  • Guarda el widget.
  • Ve a tu sitio y verás el reloj analógico funcionando en la barra lateral.

Resumen de la creación del reloj analógico

  1. Canvas de HTML5
    • El reloj se dibuja dentro de un elemento <canvas> de HTML.
    • Este canvas es un área gráfica donde se pueden trazar líneas, círculos y texto con JavaScript.
  2. Contexto gráfico (getContext("2d"))
    • Se obtiene el contexto 2D del canvas, que permite dibujar formas y aplicar estilos.
    • Con este contexto (gctx) se trazan los círculos, rayas y números.
  3. Cálculo de ángulos
    • Cada segundo equivale a 6° (360° / 60).
    • Cada minuto también equivale a 6°.
    • Cada hora equivale a 30° (360° / 12).
    • Se calculan los ángulos de las agujas en función de la hora actual (Date()).
  4. Dibujo de la esfera
    • Se dibuja un círculo exterior con borde azul oscuro y sombra para dar volumen.
    • Se añaden las rayas de los minutos y las rayas más largas en las posiciones de las horas.
    • Los números (1–12) se colocan alrededor del círculo, centrados y con sombra.
  5. Agujas del reloj
    • Segundero: delgado y de color azul claro.
    • Minutero: más grueso y oscuro.
    • Horario: más corto y ancho.
    • Cada aguja se dibuja como una línea con un pequeño arco en la base para dar efecto.
  6. Centro del reloj
    • Se dibuja un pequeño círculo en el centro para cubrir las uniones de las agujas.
  7. Animación
    • Una función (my_function) redibuja el reloj cada segundo.
    • Se usa setTimeout para actualizar los ángulos y mover las agujas en tiempo real.
  8. Estilos y centrado
    • El reloj se coloca dentro de un contenedor .reloj-container con CSS flexbox para que quede centrado en ordenador y móvil.
    • El canvas es responsivo (width:100%) para adaptarse al ancho del widget.

En resumen

El reloj se construye con:

  • HTML → para definir el canvas.
  • CSS → para centrarlo y hacerlo responsivo.
  • JavaScript → para calcular la hora, dibujar la esfera, los números, las rayas y las agujas, y actualizarlo cada segundo.

Esquema visual (imaginado)

  1. Círculo exterior → esfera del reloj.
  2. Rayas cortas → minutos.
  3. Rayas largas + números → horas.
  4. Agujas → hora, minuto y segundo.
  5. Centro → círculo pequeño que une las agujas.
  6. Animación → función que actualiza cada segundo.

En conclusión: el reloj se construye combinando HTML (canvas)CSS (centrado y responsivo) y JavaScript (cálculo de ángulos y animación).

Esquema visual del reloj analógico

1. Esfera del reloj

  • Un círculo exterior con borde azul oscuro y sombra.
  • Representa la base del reloj.

Código

   ●───────────────●
  /                 \
 ●                   ●
  \                 /
   ●───────────────●

2. Marcas de minutos y horas

  • 60 rayas alrededor de la esfera.
  • Las rayas de las horas (1–12) son más largas.
  • Sirven de guía para colocar los números.

Código

|   |   |   |   |   |   |   |   |   |

3. Números (1–12)

  • Colocados en posiciones radiales usando trigonometría.
  • Separados del borde para que no se peguen a las rayas.
  • Con sombra para dar volumen.

Código

       12
   11      1
10            2
   9        3
       6

4. Agujas

  • Segundero: delgado y azul claro.
  • Minutero: más largo y oscuro.
  • Horario: más corto y ancho.
  • Cada aguja se dibuja según el ángulo calculado con la hora actual.

Código

       |
       |
   ----●----
       |

5. Centro del reloj

  • Un pequeño círculo que cubre la unión de las agujas.
  • Da un acabado limpio y elegante.

6. Animación

  • Una función en JavaScript (my_function) redibuja el reloj cada segundo.
  • Se actualizan los ángulos de las agujas con la hora real (Date()).
  • Se usa setTimeout para que el reloj se mueva en tiempo real.

Resumen gráfico

  1. Esfera → círculo exterior con sombra.
  2. Marcas → rayas cortas y largas.
  3. Números → colocados alrededor con sombra.
  4. Agujas → hora, minuto y segundo.
  5. Centro → círculo pequeño.
  6. Animación → actualización cada segundo.

Ver otro ejemplo de Reloj Analógico.

Plugin Gráfico de Visitas Simple

Plugin Gráfico de Visitas Simple

Gráfico de Visitas (antes Visitas Tracker Simple) es un plugin ligero para WordPress que permite registrar y visualizar las visitas que recibe tu sitio día a día. Su objetivo es ofrecer una referencia clara y sencilla del tráfico sin necesidad de herramientas externas complejas.

🔧 Qué hace

  • Registra automáticamente cada visita al cargar una página del sitio.
  • Almacena los datos por fecha en una tabla propia dentro de la base de datos de WordPress.
  • Muestra métricas agregadas: total general, últimos 7 días y últimos 30 días.
  • Despliega una tabla diaria con el número de visitas por fecha.
  • Incluye un gráfico de barras en el área de administración para visualizar la evolución de las visitas de forma clara y rápida.

Para qué sirve

Este plugin es ideal si quieres:

  • Tener un control básico del tráfico sin depender de servicios externos como Google Analytics.
  • Visualizar de manera sencilla la tendencia de visitas en tu sitio.
  • Consultar estadísticas directamente desde el panel de administración de WordPress.
  • Obtener una referencia general del comportamiento de tus usuarios en periodos cortos (semanales o mensuales).

En resumen: es una herramienta práctica, ligera y fácil de usar para medir y visualizar las visitas de tu webdirectamente en WordPress.

Descargar Plugin Gráfico de Visitas Simple

GRÁFICO DE VISITAS SIMPLE
El RSS

El RSS

El RSS es un formato basado en XML que permite suscribirse a sitios web para recibir automáticamente sus actualizaciones sin necesidad de visitarlos manualmente.

Definición

  • RSS significa Really Simple Syndication (Sindicación Realmente Simple).
  • Es un formato abierto de redifusión web que organiza y distribuye contenido actualizado de manera automática.
  • También se conoce como Rich Site Summary en algunos contextos.

⚙️ Cómo funciona

  • Los sitios web generan un feed RSS (archivo .xml) que contiene sus últimas publicaciones.
  • Los usuarios se suscriben a ese feed mediante un lector o agregador RSS.
  • Cada vez que el sitio publica algo nuevo, el lector lo muestra automáticamente en la lista de actualizaciones.

Ventajas principales

  • Centralización de información: puedes seguir varios blogs, periódicos o podcasts desde un único lugar.
  • Ahorro de tiempo: no necesitas entrar en cada página para comprobar si hay novedades.
  • Personalización: eliges exactamente qué fuentes seguir, evitando algoritmos de redes sociales.
  • Compatibilidad: funciona con noticias, blogs, podcasts y más.

📖 Ejemplo práctico

Imagina que sigues 10 blogs de tecnología. En lugar de abrirlos uno por uno, te suscribes a sus feeds RSS. Tu lector RSS te mostrará en una sola pantalla todas las nuevas publicaciones, ordenadas cronológicamente.

Contexto actual

  • El RSS fue muy popular en los años 2000 como herramienta para organizar el “caos” de información en internet.
  • Aunque perdió protagonismo frente a redes sociales y notificaciones push, sigue siendo usado por periodistas, investigadores y usuarios que quieren controlar su flujo de información sin depender de algoritmos.

👉 En resumen: el RSS es como un canal directo entre un sitio web y tu lector de noticias, que te mantiene informado de manera automática y organizada.

Crear un plugin RSS en WordPress

1. Crear la carpeta del plugin

En tu servidor, dentro de la instalación de WordPress:

bash

cd /var/www/tusitio.com/wordpress/wp-content/plugins/
sudo mkdir rss-tusitio
cd rss-tusitio

2. Crear el archivo principal

bash

sudo nano rss-tusitio.php

3. Pegar el código del plugin

php

<?php
/*
Plugin Name: RSS Tusitio
Description: Muestra el feed RSS de tusitio.com en tu web mediante shortcode.
Version: 1.0
Author: Francisco
*/

function rss_tusitio_shortcode() {
    include_once(ABSPATH . WPINC . '/feed.php');

    $rss = fetch_feed('https://tusitio.com/feed');

    if (is_wp_error($rss)) {
        $msg = esc_html($rss->get_error_message());
        return '<p>No se pudo cargar el feed: ' . $msg . '</p>';
    }

    $maxitems = $rss->get_item_quantity(5);
    $rss_items = $rss->get_items(0, $maxitems);

    if ($maxitems === 0) {
        return '<p>No hay elementos en el feed.</p>';
    }

    $output = '<ul class="rss-tusitio-list">';
    foreach ($rss_items as $item) {
        $title = esc_html($item->get_title());
        $link  = esc_url($item->get_permalink());
        $date  = $item->get_date('d/m/Y');

        $output .= '<li class="rss-tusitio-item">';
        $output .= '<a href="' . $link . '" target="_blank" rel="noopener">' . $title . '</a>';
        if ($date) {
            $output .= ' <span class="rss-tusitio-date">(' . esc_html($date) . ')</span>';
        }
        $output .= '</li>';
    }
    $output .= '</ul>';

    return $output;
}

add_shortcode('rss_tusitio', 'rss_tusitio_shortcode');

4. Ajustar permisos

bash

sudo chown www-data:www-data rss-tusitio.php
sudo chmod 644 rss-tusitio.php

5. Activar el plugin

  • Ve al panel de WordPress → Plugins.
  • Activa “RSS Tusitio”.

6. Usar el shortcode

En cualquier página o entrada (por ejemplo, en Divi dentro de un módulo de texto):

Código

[rss_tusitio]

Esto mostrará los últimos 5 enlaces del feed de https://tusitio.com/feed.