Paso a paso¶
Esta seccion esta escrita "tal como lo fuimos haciendo", con los problemas tipicos que fueron saliendo y como los fuimos resolviendo.
1) Preparacion del servidor (Debian 13)¶
Nos conectamos como root (no tenemos sudo instalado).
apt update
apt upgrade -y
Nos salio
sudo: command not foundporque ya eramos root y Debian minimal no lleva sudo por defecto.
2) Instalar paquetes necesarios (Laravel)¶
apt install -y nginx git curl unzip
apt install -y mariadb-server
apt install -y php php-fpm php-cli php-mysql php-curl php-mbstring php-xml php-bcmath php-zip
3) Instalar Composer¶
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
chmod +x /usr/local/bin/composer
composer --version
4) Clonar el proyecto a /var/www¶
cd /var/www
git clone https://gitlab.inf.edt.cat/a241627gm/streaming-victor-garcia-ucha-shubitidze-gemma-mulet.git
mv streaming-victor-garcia-ucha-shubitidze-gemma-mulet streaming
cd streaming
5) Dependencias de PHP y .env¶
composer install
cp .env.example .env
php artisan key:generate
6) Base de datos (MariaDB) y usuario¶
Evitamos usar root porque daba error (auth por socket). Creamos un usuario de BD para la app.
mysql
Dentro de MariaDB:
CREATE DATABASE IF NOT EXISTS streaming
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
DROP USER IF EXISTS 'streaming'@'localhost';
DROP USER IF EXISTS 'streaming'@'127.0.0.1';
DROP USER IF EXISTS 'streaming'@'%';
CREATE USER 'streaming'@'localhost' IDENTIFIED BY 'Streaming123!';
CREATE USER 'streaming'@'127.0.0.1' IDENTIFIED BY 'Streaming123!';
GRANT ALL PRIVILEGES ON streaming.* TO 'streaming'@'localhost';
GRANT ALL PRIVILEGES ON streaming.* TO 'streaming'@'127.0.0.1';
FLUSH PRIVILEGES;
EXIT;
Test de login (important):
mysql -u streaming -p -h 127.0.0.1 streaming
Despues editamos el .env:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=streaming
DB_USERNAME=streaming
DB_PASSWORD=Streaming123!
7) Migraciones y error de created_at duplicado¶
Ejecutamos:
php artisan migrate
Fallo con:
Duplicate column name 'created_at'
Solucion: era un problema de las migraciones (una ya creaba timestamps y otra los anadia).
Solucion aplicada¶
Modificamos la migracion add_timestamps... porque solo lo hiciera si la columna no existia.
Despues reiniciamos la BD y volvimos a migrar:
mysql -e "DROP DATABASE IF EXISTS streaming; CREATE DATABASE streaming CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
php artisan optimize:clear
php artisan migrate
8) Permisos de Laravel¶
chown -R www-data:www-data /var/www/streaming
find storage bootstrap/cache -type d -exec chmod 775 {} \;
find storage bootstrap/cache -type f -exec chmod 664 {} \;
9) Configuracion Nginx (backend Laravel)¶
Archivo:
nano /etc/nginx/sites-available/streaming
Configuracion:
server {
listen 80;
server_name _;
root /var/www/streaming/public;
index index.php index.html;
client_max_body_size 64M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
}
location ~ /\. {
deny all;
}
}
Activar y reiniciar:
rm -f /etc/nginx/sites-enabled/default
ln -sf /etc/nginx/sites-available/streaming /etc/nginx/sites-enabled/streaming
nginx -t
systemctl restart nginx
Nos salio que el puerto 80 estaba ocupado porque habia Apache. Paramos Apache y despues nginx arranco bien.
10) Error 500: Vite manifest¶
Cuando nginx ya respondia, Laravel daba 500 y en el log salia:
Vite manifest not found
Aqui pasaba porque faltaba compilar el frontend (Vite).
Instalar Node y build¶
apt install -y nodejs npm
cd /var/www/streaming
npm install
npm run build
Error extra: resources/css/style.css no existe¶
Vite fallaba porque en el repo habia styles.css (plural).
Solucion:
- corregir vite.config.js por usar app.css, styles.css y app.js
- corregir el Blade que decia style.css
En nuestro caso era:
resources/views/layouts/header.blade.php
Cambiamos:
@vite(['resources/css/app.css', 'resources/css/style.css', 'resources/js/app.js'])
Por:
@vite(['resources/css/app.css', 'resources/css/styles.css', 'resources/js/app.js'])
Limpiar caches:
php artisan view:clear
php artisan optimize:clear
Comprobar que ya funciona:
curl -I http://127.0.0.1/
curl -I http://127.0.0.1/build/manifest.json
11) Clonacion de contenedores (Proxmox)¶
A partir del contenedor base (UVG-PRO1) creamos:
- UVG-PRO2
- UVG-TEST
- UVG-LB
y asignamos IPs:
- PRO1 10.200.145.211
- PRO2 10.200.145.212
- TEST 10.200.145.213
- LB 10.200.145.214
12) Load Balancer a UVG-LB (Nginx)¶
Importante: al principio el LB estaba sirviendo Laravel localmente porque tenia root /var/www/streaming/public.
Lo cambiamos porque actuase como reverse proxy hacia PRO1 y PRO2.
A UVG-LB:
nano /etc/nginx/sites-available/streaming
Contenido final (balanceo):
upstream streaming_backends {
server 10.200.145.211:80 max_fails=3 fail_timeout=10s;
server 10.200.145.212:80 max_fails=3 fail_timeout=10s;
}
server {
listen 80;
server_name _;
location / {
proxy_pass http://streaming_backends;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Aplicar:
nginx -t
systemctl reload nginx
Test:
curl -I http://10.200.145.214
13) CI/CD con GitLab (test y produccion)¶
Objetivo¶
test-> despliega a UVG-TEST (10.200.145.213)main-> despliega a UVG-PRO1 y UVG-PRO2
Como lo hariamos (resumen)¶
- Crear ramas
testymain - Instalar un runner dentro de la misma red (ex: UVG-LB)
- Hacer
.gitlab-ci.ymlcon deploy por SSH
Ejemplo simple (estilo clase):
stages:
- deploy
deploy_test:
stage: deploy
only:
- test
script:
- ssh root@10.200.145.213 "cd /var/www/streaming && git pull && composer install && npm ci && npm run build && php artisan migrate --force && php artisan optimize:clear"
deploy_prod:
stage: deploy
only:
- main
script:
- ssh root@10.200.145.211 "cd /var/www/streaming && git pull && composer install --no-dev && npm ci && npm run build && php artisan migrate --force && php artisan optimize:clear"
- ssh root@10.200.145.212 "cd /var/www/streaming && git pull && composer install --no-dev && npm ci && npm run build && php artisan migrate --force && php artisan optimize:clear"
14) Monitoreo (Prometheus + Grafana)¶
Node Exporter (a cada nodo)¶
A PRO1/PRO2/TEST/LB:
useradd --no-create-home --shell /usr/sbin/nologin node_exporter || true
cd /tmp
VER="1.8.1"
wget -q https://github.com/prometheus/node_exporter/releases/download/v${VER}/node_exporter-${VER}.linux-amd64.tar.gz
tar xzf node_exporter-${VER}.linux-amd64.tar.gz
cp node_exporter-${VER}.linux-amd64/node_exporter /usr/local/bin/
Service:
cat >/etc/systemd/system/node_exporter.service <<'EOF'
[Unit]
Description=Node Exporter
After=network-online.target
Wants=network-online.target
[Service]
User=node_exporter
Group=node_exporter
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now node_exporter
Test:
curl -I http://127.0.0.1:9100/metrics
Prometheus + Grafana (en UVG-LB)¶
Con Docker Compose (ejemplo):
- Prometheus a
:9090 - Grafana a
:3000
Targets (node exporter):
- 10.200.145.211:9100
- 10.200.145.212:9100
- 10.200.145.213:9100
- 10.200.145.214:9100
Dashboard recomendado: 1860 (Node Exporter Full).
15) Comandos de admin (por si se rompe)¶
systemctl restart nginx
systemctl restart php8.4-fpm
tail -n 80 /var/www/streaming/storage/logs/laravel.log
tail -n 80 /var/log/nginx/error.log
php artisan optimize:clear
php artisan view:clear
16) Documentacion con MkDocs (esta web)¶
Para verlo en local:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
mkdocs serve -a 0.0.0.0:8000
Para publicar en GitLab Pages, el repo tiene un .gitlab-ci.yml que construye el site a public/.