Actualización del 2025-08-16 a las 13:12:01

This commit is contained in:
jlimolina 2025-08-16 13:12:01 +02:00
parent b44096b07c
commit b26e9ad87f
13 changed files with 710 additions and 222 deletions

View file

@ -13,8 +13,8 @@ WEB_PORT=8000
echo "🟢 Paso 0: Verificaciones y confirmación de seguridad"
if [[ $EUID -ne 0 ]]; then
echo "❌ Este script debe ser ejecutado como root (usa sudo)."
exit 1
echo "❌ Este script debe ser ejecutado como root (usa sudo)."
exit 1
fi
echo "------------------------------------------------------------------"
@ -52,6 +52,10 @@ apt-get update
apt-get install -y wget ca-certificates postgresql postgresql-contrib python3-venv python3-pip python3-dev libpq-dev gunicorn
echo "🔥 Paso 2: Eliminando y recreando la base de datos y el usuario..."
## CORRECCIÓN: Se exporta PGPASSWORD para evitar exponer la contraseña en la línea de comandos
## y se agrupa con la del paso 4 para mayor eficiencia.
export PGPASSWORD="$DB_PASS"
sudo -u postgres psql -c "DROP DATABASE IF EXISTS $DB_NAME;"
sudo -u postgres psql -c "DROP USER IF EXISTS $DB_USER;"
echo " -> Entidades de BD anteriores eliminadas."
@ -62,7 +66,7 @@ echo "✅ Base de datos y usuario recreados con éxito."
echo "🐍 Paso 3: Configurando el entorno de la aplicación..."
if ! id "$APP_USER" &>/dev/null; then
echo "👤 Creando usuario del sistema '$APP_USER'..."
sudo useradd -m -s /bin/bash "$APP_USER"
useradd -m -s /bin/bash "$APP_USER"
else
echo "✅ Usuario del sistema '$APP_USER' ya existe."
fi
@ -92,7 +96,7 @@ else
fi
echo "📐 Paso 4: Creando esquema de BD y sembrando datos..."
export PGPASSWORD="$DB_PASS"
# La variable PGPASSWORD ya está exportada desde el paso 2
psql -U "$DB_USER" -h localhost -d "$DB_NAME" <<SQL
CREATE TABLE IF NOT EXISTS continentes (id SERIAL PRIMARY KEY, nombre VARCHAR(50) NOT NULL UNIQUE);
@ -132,30 +136,14 @@ SQL
unset PGPASSWORD
echo "✅ Esquema de base de datos y datos iniciales configurados."
echo "👷 Paso 5: Creando script para el worker de captura..."
cat <<EOF > "$APP_DIR/worker.py"
import sys
import os
import logging
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
try:
from app import app, fetch_and_store
except ImportError as e:
logging.basicConfig()
logging.critical(f"No se pudo importar la aplicación Flask. Error: {e}")
sys.exit(1)
if __name__ == "__main__":
with app.app_context():
fetch_and_store()
EOF
chown "$APP_USER":"$APP_USER" "$APP_DIR/worker.py"
echo "✅ Script del worker creado/actualizado."
## CORRECCIÓN: Se elimina el Paso 5, ya no es necesario crear el worker.py dinámicamente.
echo "⚙️ Paso 6: Creando nuevos archivos de servicio systemd..."
cat <<EOF > /etc/systemd/system/$APP_NAME.service
[Unit]
Description=Gunicorn instance to serve $APP_NAME
After=network.target
[Service]
User=$APP_USER
Group=$APP_USER
@ -169,45 +157,47 @@ Environment="DB_USER=$DB_USER"
Environment="DB_PASS=$DB_PASS"
ExecStart=$PYTHON_ENV/bin/gunicorn --workers 3 --bind 0.0.0.0:$WEB_PORT --timeout 120 $WSGI_APP_ENTRY
Restart=always
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF > /etc/systemd/system/$APP_NAME-worker.service
## CORRECCIÓN: Se elimina la creación de rss-worker.service y rss-worker.timer.
## Se añade el nuevo servicio para el planificador persistente scheduler.py.
cat <<EOF > /etc/systemd/system/$APP_NAME-scheduler.service
[Unit]
Description=$APP_NAME Feed Fetcher Worker
Description=$APP_NAME Scheduler Worker
After=postgresql.service
[Service]
Type=oneshot
Type=simple
User=$APP_USER
Group=$APP_USER
WorkingDirectory=$APP_DIR
Environment="PATH=$PYTHON_ENV/bin"
Environment="SECRET_KEY=$(python3 -c 'import os; print(os.urandom(24).hex())')"
Environment="DB_HOST=localhost"
Environment="DB_PORT=5432"
Environment="DB_NAME=$DB_NAME"
Environment="DB_USER=$DB_USER"
Environment="DB_PASS=$DB_PASS"
ExecStart=$PYTHON_ENV/bin/python $APP_DIR/worker.py
ExecStart=$PYTHON_ENV/bin/python $APP_DIR/scheduler.py
Restart=always
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF > /etc/systemd/system/$APP_NAME-worker.timer
[Unit]
Description=Run $APP_NAME worker every 15 minutes
[Timer]
OnBootSec=5min
OnUnitActiveSec=15min
Unit=$APP_NAME-worker.service
[Install]
WantedBy=timers.target
EOF
echo "✅ Archivos de servicio y timer creados."
echo "✅ Archivos de servicio creados."
echo "🚀 Paso 7: Recargando, habilitando, arrancando servicios y configurando firewall..."
systemctl daemon-reload
systemctl enable $APP_NAME.service
systemctl start $APP_NAME.service
systemctl enable $APP_NAME-worker.timer
systemctl start $APP_NAME-worker.timer
## CORRECCIÓN: Se habilitan e inician el nuevo servicio del planificador.
systemctl enable $APP_NAME-scheduler.service
systemctl start $APP_NAME-scheduler.service
if command -v ufw &> /dev/null && ufw status | grep -q 'Status: active'; then
echo " -> Firewall UFW detectado. Abriendo puerto $WEB_PORT..."
@ -224,8 +214,10 @@ echo " http://<IP_DE_TU_SERVIDOR>:$WEB_PORT"
echo ""
echo "Puedes verificar el estado de los servicios con:"
echo "sudo systemctl status $APP_NAME.service"
echo "sudo systemctl status $APP_NAME-worker.timer"
## CORRECCIÓN: Se actualiza el mensaje para reflejar el nuevo nombre del servicio del worker.
echo "sudo systemctl status $APP_NAME-scheduler.service"
echo ""
echo "Para ver los logs de la aplicación web:"
echo "sudo journalctl -u $APP_NAME.service -f"
echo "Para ver los logs del planificador de noticias:"
echo "sudo journalctl -u $APP_NAME-scheduler.service -f"