# static.alpinux.org

CDN pour les fichiers binaires et assets statiques de l'association : logos, favicons, images Open Graph.
Tableau de bord d'administration accessible sur `https://static.alpinux.org` (authentification AlpID).

---

## Flux de publication

Il y a **deux cibles** distinctes sur le serveur, gérées par des scripts séparés :

| Quoi | Destination serveur | Script | Passe par git ? |
|------|--------------------|---------|----|
| Assets CDN (logo/, wiki/, stats/, error/…) | `/var/www/clients/client1/web17/web` | `push-assets.sh` | Non — rsync direct |
| App Flask (`app/`) | `/opt/static-cdn/` + redémarrage service | `deploy-app.sh` | Non — rsync direct |

Git sert à **versionner et sauvegarder** le code sur Gitea. Il n'est pas dans la boucle de déploiement : les scripts rsynchent depuis le dépôt local, pas depuis Gitea.

### Modifier les assets CDN (logo, wiki, stats…)

```bash
# 1. Modifier les fichiers dans static/
# 2. Versionner (optionnel mais recommandé)
git add <fichiers>
git commit -m "..."
git push                        # sauvegarde sur gitea.alpinux.org

# 3. Pousser sur le serveur
./scripts/push-assets.sh        # aperçu + confirmation
./scripts/push-assets.sh -y     # sans confirmation
```

> `push-assets.sh` exclut automatiquement `app/`, `scripts/`, `.git/`, `.env`, `README.md`.
> Il envoie : `logo/`, `wiki/`, `stats/`, `error/`, `favicon.ico`, `robots.txt`, `standard_index.html`.

### Modifier l'app Flask (`app/`)

```bash
# 1. Modifier les fichiers dans static/app/
# 2. Versionner
git add app/
git commit -m "..."
git push                        # sauvegarde sur gitea.alpinux.org

# 3. Déployer sur le serveur
./scripts/deploy-app.sh         # rsync + pip install + restart service
./scripts/deploy-app.sh -n      # dry-run
```

> `deploy-app.sh` rsync `app/` vers `/opt/static-cdn/`, met à jour le venv Python,
> et redémarre le service systemd `static-cdn`.

---

## Configuration locale (`.env`)

```bash
cp .env.example .env
```

| Variable | Obligatoire | Description |
|----------|-------------|-------------|
| `STATIC_HOST` | oui | Alias SSH ou nom d'hôte (`alpinux.org`) |
| `STATIC_PATH` | oui | Chemin absolu du web root sur le serveur |
| `LOCAL_ASSETS_DIR` | oui | Chemin absolu du dépôt local (`static/`) |
| `STATIC_USER` | non | Login SSH — laisser vide si `~/.ssh/config` définit l'utilisateur |

Si l'hôte est déclaré dans `~/.ssh/config` (recommandé), laisser `STATIC_USER` vide.
Sinon, renseigner `STATIC_USER=<login>` — les scripts construisent alors `USER@HOST:PATH`.

---

## Scripts

```bash
# Synchroniser les assets CDN
./scripts/pull-assets.sh        # serveur → local (aperçu + confirmation)
./scripts/pull-assets.sh -y     # sans confirmation
./scripts/pull-assets.sh -n     # dry-run

./scripts/push-assets.sh        # local → serveur (aperçu + confirmation)
./scripts/push-assets.sh -y     # sans confirmation
./scripts/push-assets.sh -n     # dry-run

# Déployer l'app Flask
./scripts/deploy-app.sh         # déploie et redémarre le service
./scripts/deploy-app.sh -n      # dry-run
```

---

## Tableau de bord Flask (`app/`)

Application Flask déployée sur le serveur via `deploy-app.sh`.
Accessible sur `https://static.alpinux.org` (proxy Apache → `127.0.0.1:5003`).
Authentification SSO via AlpID (Keycloak).

### Fonctionnalités

| Route | Description |
|-------|-------------|
| `/` | Tableau de bord — statistiques CDN par dossier |
| `/browse/` | Navigateur de fichiers — aperçu, suppression, **upload** |
| `/search` | Recherche par nom / contenu / date |
| `/stats/` | Rapport de trafic GoAccess |

### Upload de fichiers

Dans le navigateur (`/browse/`), une zone de dépôt est affichée en bas de chaque dossier.
Elle accepte plusieurs fichiers à la fois (glisser-déposer ou sélection).
Les chemins protégés (`.git`, `app`, `scripts`, etc.) sont refusés avec 403.

Pour limiter la taille des uploads, ajouter dans `app/app.py` :

```python
app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024  # 50 Mo
```

### Variables d'environnement de l'app

Le fichier de référence est `app/.env.example`. Sur le serveur : `/opt/static-cdn/.env`.

**Auth & Flask**

| Variable | Obligatoire | Description |
|----------|-------------|-------------|
| `SECRET_KEY` | oui | Clé secrète Flask (chaîne aléatoire longue) |
| `ALPID_CLIENT_ID` | oui | Client Keycloak (`static-cdn`) |
| `ALPID_CLIENT_SECRET` | oui | Secret client Keycloak |
| `ALPID_DISCOVERY_URL` | oui | URL OIDC discovery AlpID |
| `ADMIN_GROUPS` | non | Groupes Keycloak autorisés (défaut : `admins`) |
| `ADMIN_EMAILS` | non | Fallback si le claim `groups` est absent du token |
| `ASSETS_ROOT` | oui | Racine du CDN (`/var/www/clients/client1/web17/web` en prod) |

**Stats GoAccess**

| Variable | Description |
|----------|-------------|
| `STATS_FILE` | Rapport HTML GoAccess servi dans `/stats/` (défaut : `/opt/static-cdn/goaccess.html`) |
| `STATS_JSON` | Rapport JSON GoAccess pour les badges "Vues" (défaut : `/opt/static-cdn/goaccess.json`) |
| `STATS_LOG_FILE` | Log Apache à analyser pour la génération à la demande |
| `STATS_GENERATE_CMD` | Commande GoAccess complète — remplace la commande par défaut si renseigné |

---

## Première installation (nouveau serveur)

### 1. Créer le site dans ISPConfig

`https://owni.alpinux.org:8080` → *Sites → Ajouter un site web*

- Domaine : `static.alpinux.org`
- Activer **Let's Encrypt SSL**
- DocumentRoot : `/var/www/clients/client1/web17/web`

### 2. Configurer le proxy Apache

Dans ISPConfig → onglet **Directives Apache SSL** du site :

```apache
# CDN public → Apache sert directement depuis DocumentRoot
ProxyPass /logo/        !
ProxyPass /wiki/        !
ProxyPass /error/       !
ProxyPass /favicon.ico  !
ProxyPass /robots.txt   !

# Tableau de bord → Flask
RequestHeader set X-Forwarded-Proto "https"
ProxyPreserveHost On
ProxyPass        / http://127.0.0.1:5003/
ProxyPassReverse / http://127.0.0.1:5003/
```

### 3. Déployer l'app Flask

```bash
# Depuis la machine locale
./scripts/deploy-app.sh

# Sur le serveur — créer /opt/static-cdn/.env (voir app/.env.example)
ssh alpinux.org
nano /opt/static-cdn/.env

# Activer le service
sudo systemctl enable --now static-cdn
```

### 4. Pousser les assets CDN

```bash
./scripts/push-assets.sh -y
```

---

## Voir aussi

Vue d'ensemble des projets, procédures de déploiement globales et accès :  
`~/Projects/org.alpinux.owni/README.md`
