Harden Tailwind Docker build and add deploy verification
This commit is contained in:
@@ -35,7 +35,6 @@ CONTRIBUTING.md
|
|||||||
|
|
||||||
# Development
|
# Development
|
||||||
node_modules/
|
node_modules/
|
||||||
package-lock.json
|
|
||||||
Makefile
|
Makefile
|
||||||
.env*
|
.env*
|
||||||
|
|
||||||
|
|||||||
+18
-8
@@ -1,22 +1,33 @@
|
|||||||
# Multi-stage build per LLM Monitor
|
# Multi-stage build per LLM Monitor
|
||||||
|
|
||||||
# Stage 1: Build CSS with Tailwind
|
# Stage 1: Build CSS with Tailwind
|
||||||
FROM node:18-alpine as css-builder
|
FROM node:18-alpine AS css-builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Copiare file di configurazione
|
# Copiare file di configurazione e lockfile per install consistente
|
||||||
COPY package.json tailwind.config.js ./
|
COPY package.json package-lock.json tailwind.config.js ./
|
||||||
COPY app/web/static/css/input.css ./app/web/static/css/
|
|
||||||
|
|
||||||
# Installare dipendenze Node
|
# Installare dipendenze Node
|
||||||
RUN npm install
|
RUN npm ci
|
||||||
|
|
||||||
|
# Copiare input CSS e file usati dal content scan di Tailwind.
|
||||||
|
# Questo passaggio deve avvenire prima della build per invalidare cache quando cambiano template/js.
|
||||||
|
COPY app/web/static/css/input.css ./app/web/static/css/
|
||||||
|
COPY app/web/templates/ ./app/web/templates/
|
||||||
|
COPY app/web/static/js/ ./app/web/static/js/
|
||||||
|
|
||||||
# Compilare CSS Tailwind
|
# Compilare CSS Tailwind
|
||||||
RUN npm run tailwind:build
|
RUN npm run tailwind:build
|
||||||
|
|
||||||
|
# Verifica bloccante: output.css deve essere compilato e non vuoto.
|
||||||
|
RUN test -s ./app/web/static/css/output.css && \
|
||||||
|
CSS_LINES=$(wc -l < ./app/web/static/css/output.css) && \
|
||||||
|
echo "[css-builder] output.css lines: ${CSS_LINES}" && \
|
||||||
|
test "${CSS_LINES}" -ge 100
|
||||||
|
|
||||||
# Stage 2: Build Python packages
|
# Stage 2: Build Python packages
|
||||||
FROM python:3.11-slim as builder
|
FROM python:3.11-slim AS builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
@@ -48,10 +59,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
COPY --from=builder /opt/venv /opt/venv
|
COPY --from=builder /opt/venv /opt/venv
|
||||||
|
|
||||||
# Copiare codice dell'app
|
# Copiare codice dell'app
|
||||||
COPY --from=css-builder /app/app/web/static/css/output.css ./app/web/static/css/
|
COPY --from=css-builder /app/app/web/static/css/output.css ./app/web/static/css/output.css
|
||||||
COPY app/ /app/app/
|
COPY app/ /app/app/
|
||||||
COPY main.py /app/
|
COPY main.py /app/
|
||||||
COPY .env* /app/
|
|
||||||
|
|
||||||
# Impostare PATH
|
# Impostare PATH
|
||||||
ENV PATH="/opt/venv/bin:$PATH"
|
ENV PATH="/opt/venv/bin:$PATH"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.PHONY: help install dev prod test lint format clean docker-build docker-up docker-down
|
.PHONY: help install dev prod test lint format clean docker-build docker-up docker-down docker-build-no-cache verify-css deploy-no-cache
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "LLM Monitor - Makefile Commands"
|
@echo "LLM Monitor - Makefile Commands"
|
||||||
@@ -11,8 +11,11 @@ help:
|
|||||||
@echo "make format - Formatta il codice"
|
@echo "make format - Formatta il codice"
|
||||||
@echo "make clean - Pulisce cache e file temporanei"
|
@echo "make clean - Pulisce cache e file temporanei"
|
||||||
@echo "make docker-build - Build dell'immagine Docker"
|
@echo "make docker-build - Build dell'immagine Docker"
|
||||||
|
@echo "make docker-build-no-cache - Build Docker senza cache (fix Tailwind)"
|
||||||
@echo "make docker-up - Avvia i container con Docker Compose"
|
@echo "make docker-up - Avvia i container con Docker Compose"
|
||||||
@echo "make docker-down - Ferma i container con Docker Compose"
|
@echo "make docker-down - Ferma i container con Docker Compose"
|
||||||
|
@echo "make verify-css - Verifica output.css compilato nel container"
|
||||||
|
@echo "make deploy-no-cache - Deploy completo con build no-cache + verifica CSS"
|
||||||
|
|
||||||
install:
|
install:
|
||||||
python3 -m venv venv
|
python3 -m venv venv
|
||||||
@@ -41,12 +44,21 @@ clean:
|
|||||||
docker-build:
|
docker-build:
|
||||||
docker build -t llm-monitor:latest .
|
docker build -t llm-monitor:latest .
|
||||||
|
|
||||||
|
docker-build-no-cache:
|
||||||
|
docker compose build --no-cache
|
||||||
|
|
||||||
docker-up:
|
docker-up:
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
|
|
||||||
docker-down:
|
docker-down:
|
||||||
docker compose down
|
docker compose down
|
||||||
|
|
||||||
|
verify-css:
|
||||||
|
./scripts/verify-tailwind-css.sh
|
||||||
|
|
||||||
|
deploy-no-cache:
|
||||||
|
./scripts/deploy-no-cache.sh
|
||||||
|
|
||||||
docker-logs:
|
docker-logs:
|
||||||
docker compose logs -f llm-monitor
|
docker compose logs -f llm-monitor
|
||||||
|
|
||||||
|
|||||||
@@ -236,6 +236,12 @@ Usa il file `docker-compose.yml` fornito:
|
|||||||
# Avviare i servizi
|
# Avviare i servizi
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
|
|
||||||
|
# Rebuild completo senza cache (consigliato dopo modifiche UI/Tailwind)
|
||||||
|
docker compose build --no-cache
|
||||||
|
|
||||||
|
# Verificare che il CSS compilato non sia vuoto
|
||||||
|
docker exec llm-monitor-app wc -l /app/app/web/static/css/output.css
|
||||||
|
|
||||||
# Visualizzare i log
|
# Visualizzare i log
|
||||||
docker compose logs -f llm-monitor
|
docker compose logs -f llm-monitor
|
||||||
|
|
||||||
@@ -246,6 +252,41 @@ docker compose down
|
|||||||
docker compose restart llm-monitor
|
docker compose restart llm-monitor
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Deploy consigliato (Tailwind-safe)
|
||||||
|
|
||||||
|
Se l'interfaccia appare senza stili o una modale non si posiziona correttamente, usa il deploy con rebuild no-cache e verifica CSS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/llm-monitor
|
||||||
|
docker compose down
|
||||||
|
docker compose build --no-cache
|
||||||
|
docker compose up -d
|
||||||
|
sleep 5
|
||||||
|
docker exec llm-monitor-app wc -l /app/app/web/static/css/output.css
|
||||||
|
```
|
||||||
|
|
||||||
|
In alternativa dal repository:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make deploy-no-cache
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tailwind Build Process
|
||||||
|
|
||||||
|
- Lo stage `css-builder` del Dockerfile installa dipendenze Node con `npm ci`.
|
||||||
|
- Prima della build Tailwind vengono copiati template HTML e JS usati dal content scan.
|
||||||
|
- Dopo `npm run tailwind:build` una verifica bloccante controlla che `output.css` esista e abbia almeno 100 linee.
|
||||||
|
- Lo stage runtime copia `output.css` compilato da `css-builder` con `COPY --from=css-builder`.
|
||||||
|
|
||||||
|
### Troubleshooting UI
|
||||||
|
|
||||||
|
Se la modale non appare o i componenti sembrano "unstyled":
|
||||||
|
|
||||||
|
1. Esegui `docker compose build --no-cache`.
|
||||||
|
2. Riavvia con `docker compose up -d`.
|
||||||
|
3. Verifica CSS compilato: `docker exec llm-monitor-app wc -l /app/app/web/static/css/output.css`.
|
||||||
|
4. Se il numero linee e `< 100`, la build Tailwind non e riuscita correttamente.
|
||||||
|
|
||||||
### Container sempre acceso
|
### Container sempre acceso
|
||||||
|
|
||||||
Il container `llm-monitor` rimarrà in esecuzione fino al suo arresto manuale:
|
Il container `llm-monitor` rimarrà in esecuzione fino al suo arresto manuale:
|
||||||
|
|||||||
+1174
-1
File diff suppressed because one or more lines are too long
+2
-2
@@ -1,5 +1,3 @@
|
|||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# LLM Monitor Dashboard
|
# LLM Monitor Dashboard
|
||||||
llm-monitor:
|
llm-monitor:
|
||||||
@@ -24,6 +22,8 @@ services:
|
|||||||
|
|
||||||
# Istruzioni di avvio:
|
# Istruzioni di avvio:
|
||||||
# docker compose up -d # Avvia i servizi
|
# docker compose up -d # Avvia i servizi
|
||||||
|
# docker compose build --no-cache # Rebuild completo (consigliato se output.css e vuoto o UI rotta)
|
||||||
|
# docker exec llm-monitor-app wc -l /app/app/web/static/css/output.css # Verifica CSS compilato
|
||||||
# docker compose logs -f # Visualizza i log
|
# docker compose logs -f # Visualizza i log
|
||||||
# docker compose down # Ferma i servizi
|
# docker compose down # Ferma i servizi
|
||||||
# docker compose restart # Riavvia i servizi
|
# docker compose restart # Riavvia i servizi
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"tailwind:dev": "tailwindcss -i ./app/web/static/css/input.css -o ./app/web/static/css/output.css --watch",
|
"tailwind:dev": "tailwindcss -i ./app/web/static/css/input.css -o ./app/web/static/css/output.css --watch",
|
||||||
"tailwind:build": "tailwindcss -i ./app/web/static/css/input.css -o ./app/web/static/css/output.css --minify"
|
"tailwind:build": "tailwindcss -i ./app/web/static/css/input.css -o ./app/web/static/css/output.css"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"tailwindcss": "^3.4.0"
|
"tailwindcss": "^3.4.0"
|
||||||
|
|||||||
Executable
+34
@@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PROJECT_DIR="${PROJECT_DIR:-/opt/llm-monitor}"
|
||||||
|
CONTAINER_NAME="${CONTAINER_NAME:-llm-monitor-app}"
|
||||||
|
|
||||||
|
if [[ -d "$PROJECT_DIR" ]]; then
|
||||||
|
cd "$PROJECT_DIR"
|
||||||
|
else
|
||||||
|
echo "[deploy] PROJECT_DIR non trovato: $PROJECT_DIR"
|
||||||
|
echo "[deploy] uso directory corrente: $PWD"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[deploy] stop stack"
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
if [[ ! -f ".env" && -f ".env.local" ]]; then
|
||||||
|
echo "[deploy] .env non trovato, copio .env.local -> .env"
|
||||||
|
cp .env.local .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[deploy] build stack (no cache)"
|
||||||
|
docker compose build --no-cache
|
||||||
|
|
||||||
|
echo "[deploy] start stack"
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
echo "[deploy] waiting for container startup"
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
echo "[deploy] verify Tailwind CSS"
|
||||||
|
./scripts/verify-tailwind-css.sh "$CONTAINER_NAME"
|
||||||
|
|
||||||
|
echo "[deploy] completed successfully"
|
||||||
Executable
+28
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONTAINER_NAME="${1:-llm-monitor-app}"
|
||||||
|
CSS_PATH="/app/app/web/static/css/output.css"
|
||||||
|
MIN_LINES="${MIN_TAILWIND_LINES:-100}"
|
||||||
|
|
||||||
|
if ! docker ps --format '{{.Names}}' | grep -Fxq "$CONTAINER_NAME"; then
|
||||||
|
echo "[verify-css] ERROR: container '$CONTAINER_NAME' non in esecuzione"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! docker exec "$CONTAINER_NAME" test -f "$CSS_PATH"; then
|
||||||
|
echo "[verify-css] ERROR: file CSS non trovato: $CSS_PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
LINES=$(docker exec "$CONTAINER_NAME" wc -l "$CSS_PATH" | awk '{print $1}')
|
||||||
|
BYTES=$(docker exec "$CONTAINER_NAME" wc -c "$CSS_PATH" | awk '{print $1}')
|
||||||
|
|
||||||
|
echo "[verify-css] $CSS_PATH -> ${LINES} lines, ${BYTES} bytes"
|
||||||
|
|
||||||
|
if [[ "$LINES" -lt "$MIN_LINES" ]]; then
|
||||||
|
echo "[verify-css] ERROR: output.css ha meno di ${MIN_LINES} linee"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[verify-css] OK: Tailwind CSS compilato correttamente"
|
||||||
Reference in New Issue
Block a user