Retour à la topologie
DOCUMENTATION TECHNIQUE

Portfolio (Next.js)

portfolio.md

Portfolio (Next.js)

Ce que fait ce service

Site web personnel de type portfolio qui affiche des statistiques en direct sur l'infrastructure homelab. Il interroge l'API Proxmox (VMs, LXC, CPU, RAM, stockage) et l'API Portainer (liste des containers Docker) pour afficher des métriques en temps réel directement sur la page d'accueil. Le site présente aussi des projets personnels. Il est construit avec Next.js 16 (App Router), Tailwind CSS v4 et shadcn/ui. Le déploiement est automatisé via un GitHub Actions runner auto-hébergé sur la VM.

Où il est installé

  • Code source (runner CI/CD) : ~/actions-runner/
  • Ancien code source : /opt/portfolio/Edwin-Portfolio/
  • Fichier de config principal : ~/actions-runner/docker-compose.yml
  • Dockerfile : ~/actions-runner/Dockerfile
  • Workflow CI/CD : ~/actions-runner/.github/workflows/deploy.yml
  • Env de prod : ~/website/.env.local (copié par le workflow)
  • Configuration actuelle

    docker-compose.yml (version active, utilisée par le CI/CD) :
    services:
      portfolio:
        build: .
        container_name: portfolio
        restart: unless-stopped
        ports:
          - "3000:3000"
        env_file:
          - .env.local
    Dockerfile — build multi-stage Node.js 22 Alpine :
    FROM node:22-alpine AS deps      # installe les dépendances npm
    FROM node:22-alpine AS builder   # compile (next build)
    FROM node:22-alpine AS runner    # image finale production standalone
    ENV NODE_ENV=production
    ENV PORT=3000
    ENV HOSTNAME="0.0.0.0"
    EXPOSE 3000
    CMD ["node", "server.js"]
    Workflow CI/CD (.github/workflows/deploy.yml) — déclenché sur push main :
    jobs:
      deploy:
        runs-on: self-hosted
        steps:
          - uses: actions/checkout@v4
          - run: cp ~/website/.env.local ${{ github.workspace }}/.env.local
          - run: docker compose -f ${{ github.workspace }}/docker-compose.yml up --build -d --remove-orphans

    Ports et réseau

  • Port en écoute : 3000 (HTTP)
  • Accessible depuis : Internet via Nginx Proxy Manager (reverse proxy)
  • URL : probablement portfolio.fatonfaton.fr (géré par NPM)
  • Variables d'environnement

    Injectées depuis .env.local au moment du build Docker :
    VariableValeur
    ------
    PROXMOX_HOST192.168.1.12
    PROXMOX_PORT8006
    PROXMOX_TOKEN_IDroot@pam!portfolio
    PROXMOX_TOKEN_SECRET*
    PORTAINER_HOST192.168.1.9
    PORTAINER_PORT9443
    PORTAINER_TOKEN*

    Dépendances

  • Dépend de :
  • - Proxmox API (192.168.1.12:8006) — métriques CPU/RAM/stockage des nodes et VMs - Portainer API (192.168.1.9:9443) — liste des containers Docker - Nginx Proxy Manager — expose le service vers l'extérieur
  • Est utilisé par : visiteurs web externes
  • Commandes

    Voir le statut

    docker ps --filter name=portfolio

    Voir les logs

    docker logs portfolio --tail 50

    Démarrer

    cd /home/portainer/actions-runner/_work/portfolio/portfolio
    docker compose up -d

    Arrêter

    docker compose -f ~/actions-runner/docker-compose.yml down

    Redémarrer

    docker compose -f ~/actions-runner/docker-compose.yml restart

    Rebuilder manuellement (équivalent CI/CD)

    cd /home/portainer/actions-runner/_work/portfolio/portfolio
    docker compose up --build -d --remove-orphans

    Logs — Dernière activité

    ▲ Next.js 16.2.4
    
  • • Local: http://localhost:3000
  • • Network: http://0.0.0.0:3000
  • ✓ Ready in 0ms

    Points d'attention

  • • Le GitHub Actions runner est auto-hébergé sur cette VM, sous le compte portainer. Chaque git push sur main reconstruit et redémarre le container automatiquement.
  • • Le fichier .env.local de production est stocké dans ~/website/ et non dans le repo git (protégé via .gitignore). Le workflow le copie au moment du déploiement.
  • • Les routes API /api/proxmox et /api/docker font des requêtes HTTPS vers des hôtes locaux avec rejectUnauthorized: false (certificats auto-signés acceptés).
  • • L'ancienne version Astro du site existe dans /opt/portfolio/Edwin-Portfolio/ avec un docker-compose.yml différent (port 8080). Elle n'est pas le container actif.
  • • Le container actif s'appelle portfolio (pas netlab_portfolio comme dans l'ancien compose).