Add bilingual French/English support with Hugo multilingual config

Configure Hugo multilingual mode (fr default, en secondary) with
Hextra's language-switch menu entry, and translate all existing
content pages to English using Hugo's per-file language suffix
convention (.en.md alongside .fr.md).
This commit is contained in:
Damien
2026-07-18 09:48:18 +02:00
parent a4cffd8916
commit f49c0f45dd
20 changed files with 2706 additions and 2 deletions

View File

@@ -0,0 +1,5 @@
---
title: "Blog"
---
My articles and experience feedback on networking, systems, and DevOps.

View File

@@ -0,0 +1,111 @@
---
title: "AIOps and Network Observability: Preparing the Ground for AI"
date: 2026-07-14
authors:
- name: Damien
link: https://gitea.arnodo.fr/Damien
tags:
- AIOps
- Observability
- Network Automation
- AI Agents
---
I just finished building a full observability stack on my EVPN/VXLAN lab: topology, telemetry, and near real-time visualization. While building it, I realized I wasn't just doing monitoring — I was preparing a network to one day be "seen" by an AI. This first article sets the frame for a five-part series: why observability is the mandatory prerequisite before plugging an agent into your infrastructure.
<!--more-->
## What I've actually just built
Over the past few months, I've set up a Containerlab EVPN/VXLAN lab with 28 Arista EOS devices, spread across three sites (campus, core, datacenter). Beyond BGP EVPN itself, I wanted this lab to be **observable**: to be able to say, at any moment, what the real state of the network is. Not just "does it ping," but what the actual topology is, which interfaces are up, and which counters are drifting.
The result is a stack combining four building blocks:
- a network discovery and assurance tool that serves as the **topological source of truth** (who is connected to whom, which VLANs, which VRFs);
- **telemetry collection via gNMI** directly from the EOS devices;
- a **time-series database** for metric storage;
- a **visualization layer** automatically regenerated by cross-referencing topology and metrics.
It works today. But it's not the stack itself that made me write this article: it's a realization I had while building it. I wasn't just setting up monitoring — I was laying the foundations of a pipeline that could, one day, allow an AI agent to reason about my network. And that has a name.
## AIOps, not MLOps
Let's clear up an ambiguity right away, because the two terms are often conflated.
**MLOps** (Machine Learning Operations) is the discipline of operationalizing the lifecycle of machine learning models: training, dataset versioning, deployment, drift monitoring. That's not what I'm doing here. I'm not training any model, I'm not deploying any.
What I'm doing falls under **AIOps**: making an infrastructure observable and usable by automated systems, and eventually by an AI. The center of gravity isn't the model, it's the **infrastructure data**: its freshness, its consistency, its structure. That's exactly the scope of this series.
I still cite MLOps once, as a sister discipline, because it's the one that normalized an idea AIOps directly inherits: **observability isn't an option you bolt on afterward, it's the foundation everything else rests on.** The ML community learned this the hard way: a large share of projects that work in a notebook never survive the move to production, for lack of monitoring. The lesson applies to any system we claim to delegate to a machine. Including a network.
## The blind agent
Here's the central thesis of this article, and the thread running through the whole series.
An AI agent without observability is a blind agent. It only "sees" what it's exposed to. And a blind person given nothing to see doesn't stop moving for that reason: they keep going, with the same confidence as if they could see clearly.
Take a concrete case. I migrated a server from one VLAN to another last weekend. The topological source of truth hasn't yet gone through its discovery cycle: it still describes the old attachment. I open a conversation with an agent that's supposed to help me: "this server has stopped responding since this morning, where's the problem?"
The agent queries what it's been exposed to, reads the old topology, and answers confidently: "The server is attached to leaf-3 on VLAN 20, the uplink is nominal, check its IP configuration instead." The answer is coherent, well phrased, well argued. It's also entirely wrong: the server has been on leaf-7 since Saturday. The agent didn't lie, it didn't hallucinate in the strict sense: it reasoned correctly over stale data. And at no point did it flag that it might be wrong, because at no point was it aware that it couldn't see.
That's the real danger. An experienced human compensates for lack of observability with intuition, tribal memory, historical context ("that link has always been flaky, don't worry about it"). An agent has none of that. Partial data, stale data, or an inconsistency between the declared topology and the real state doesn't make it cautious: it makes it wrongly confident. The assurance of the answer generated in natural language masks the poverty of what it actually perceived.
I should note that no agent runs on this lab today: that will be precisely the subject of the last article in this series.
Observability, then, is not an end in itself. It's **the condition of possibility** for an agent to one day see the network before acting on it. Without it, you're not building an assistant: you're building a confidently blind one.
## A layered reading grid
What helped me structure all this was thinking in stacked layers, and accepting that you don't skip a step:
1. **Infrastructure first.** Is the base data reliable, complete, up to date? Topology, metrics, logs.
2. **The model next.** What's built on top: a correlation rule, a model, an LLM — does it receive quality inputs, and can its relevance be measured over time?
3. **Agent behavior last.** Can its answers and actions be trusted, and can they be audited?
The order isn't negotiable. An agent built on top of a shaky layer 1 inherits all its weaknesses in cascade, with the added bonus of the illusion of reliability that comes from an assertive answer by construction. You can't make up for a poorly instrumented infrastructure with a better prompt.
Applied to the network, this gives a very concrete order of priorities: before thinking "AI," you need reliable telemetry, an up-to-date topological source of truth, and usable logs. That's layer 1. It's what I've been working on for months, and it's what this series is going to detail.
## What "seeing" means for a network
Concretely, giving a network agent sight means bringing together three things:
- **An up-to-date topological source of truth.** Who is connected to what, which VLANs, which VRFs, which site. Without it, the agent doesn't even know what it's talking about: this is the core of the next article.
- **Real-time telemetry.** The living state of the network: interfaces up/down, counters, utilization, drift. Topology tells the structure; telemetry tells the behavior.
- **Usable logs.** The narrative of events: who changed what, when, and which errors were raised.
Of these three pillars, two are in place on my lab. The third, logs, remains a **work item I haven't tackled yet**. I say this honestly, because it's the kind of gap you're tempted to sweep under the rug: "I have the topology and the metrics, that's already good." Except an agent deprived of logs sees the present state without understanding how it got there. It's a prerequisite, not a bonus.
There's a principle running through this entire layer 1, one I've set for myself as a rule: **standardization over adaptability.** When naming conventions are respected everywhere: interfaces, hostnames, labels, no code has to compensate for discrepancies. It's a human who fixes the configuration upstream, not a script that guesses. This choice has a cost, ongoing rigor, but a direct benefit: clean, predictable data. And clean data is precisely what allows an agent to avoid building sound reasoning on false facts.
## Seeing isn't enough: you have to make it visible
Gathering the data: topology, telemetry, logs, isn't enough: it still needs to be structured and intelligently exposed to the agent, rather than dumped on it wholesale, at the risk of saturating its context window and getting answers just as confident but just as unreliable. This is where two concepts worth remembering come in, *context engineering* and the **Model Context Protocol (MCP)**, which I'll cover in detail in the fifth and final article of this series.
## The series
This series will follow the order in which I built (and am still building) this stack:
1. **(this article) AIOps and the importance of network observability**: the general framework.
2. **Topology as source of truth**: using network discovery and assurance to drive the rest of the stack.
3. **Real-time telemetry**: the mechanics of metrics and time series, from device to dashboard.
4. **Log management**: the piece still missing from my stack, which I need to tackle before going further.
5. **Making the network "visible" to an AI agent**: context engineering, MCP, and the early steps of AIOps applied to my lab.
## Conclusion
None of this is revolutionary in isolation: network telemetry has been around for a long time. What changes is the frame. As long as you instrument a network for humans, missing data translates into a question mark, someone notices the gap and goes looking for the info elsewhere. The day you plug in an agent, that same gap no longer produces doubt: it produces a wrong answer, stated with confidence.
That's why observability comes first, and the agent comes last: not because AI is a side matter, but because it's blind by default, and you don't hand a system its eyes before building what it's supposed to see. If you're building something similar, I'd be curious to compare notes on your architecture choices.
## Resources
### Concepts
- [What is AIOps?](https://www.ibm.com/think/topics/aiops) — definition and origin of the term (Gartner)
- [Model Context Protocol — official documentation](https://modelcontextprotocol.io/docs/getting-started/intro)
- [Introducing the Model Context Protocol](https://www.anthropic.com/news/model-context-protocol) — the original announcement, which frames well the problem MCP solves
- [Effective context engineering for AI agents](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents) — the reference article on context engineering, including the phenomenon of context window saturation
- *Observability Engineering* (O'Reilly, 2nd edition), Charity Majors, Liz Fong-Jones, George Miranda: the field's reference book, with a chapter dedicated to the rise of agents and LLMs
### My repo
- [arista-evpn-vxlan-clab](https://gitea.arnodo.fr/Damien/arista-evpn-vxlan-clab)

View File

@@ -0,0 +1,602 @@
---
title: "Self-Hosting and Hybrid Cloud: My Personal Infrastructure with Gitea and Scaleway"
date: 2025-11-20
authors:
- name: Damien
link: https://gitea.arnodo.fr/Damien
tags:
- Homelab
- DevOps
- Self-Hosting
- Network Engineering
---
A write-up on building my personal infrastructure: migrating from GitHub to self-hosted Gitea, and deploying ephemeral network labs on Scaleway. All powered by Proxmox and Wireguard.
<!--more-->
## Context and Motivations
As a network engineer working in automation and orchestration, I've always needed an environment to experiment and learn in. Until recently, I used GitHub for my code and ContainerLab locally/on AWS via [DevPod](/documentation/devpod/) for my network simulations.
But several needs emerged:
- **Learning**: Deploying and managing a full Git server with CI/CD
- **Sovereignty**: Hosting my data in France (or at least in Europe), controlling my infrastructure
- **Flexibility**: Being able to spin up network labs on demand without saturating my local machine
- **Automation**: Scripting the complete provisioning of my environments
## The Overall Architecture
![Architecture](global_architecture.fr.svg)
### Tech Stack
**Homelab**:
- **Proxmox VE**: Hypervisor for VMs and LXC
- **LXC Containers**: Gitea, runners, various services
- **Ansible**: Configuration management and updates
- **Grafana/Prometheus/Loki**: Monitoring and observability
**Public exposure**:
- **Scaleway Dedibox**: Dedicated instance with a fixed IP
- **Nginx Proxy Manager**: Reverse proxy with automatic SSL
- **Wireguard VPN**: Secure tunnel between Scaleway and the homelab
**Scaleway Cloud**:
- **Object Storage**: Hosting for the Hugo blog (S3-compatible)
- **Instances**: Ephemeral network labs provisioned on demand
- **Scaleway CLI**: Full automation
## Part 1: Migrating from GitHub to Self-Hosted Gitea
### Why Gitea?
[Gitea](https://gitea.io/) is a lightweight Git server, perfect for self-hosting:
- **Lightweight**: Ideal for an LXC on Proxmox
- **GitHub Actions compatible**: Migrate workflows without rewriting them
- **Full-featured**: Issues, PRs, CI/CD, webhooks
- **Open-source**: Active community
### Deployment with Proxmox Helper Scripts
Rather than configuring everything manually, I use the excellent [Proxmox Helper Scripts](https://community-scripts.github.io/ProxmoxVE/), which automate the creation of preconfigured LXCs.
**Installing Gitea**:
```bash
# On the Proxmox node, run the script
bash -c "$(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/ct/gitea.sh)"
```
The script:
- Creates a Debian 12 LXC
- Installs Gitea and sqlite
- Configures the systemd services
- Sets up the environment with the correct permissions
**Post-installation configuration**:
- Web access: `http://<IP_LXC>:3000`
- Initial setup via the interface
- Site URL: `https://gitea.arnodo.fr`
### Network Architecture: Wireguard + Nginx Proxy Manager
**The problem**: Gitea runs inside my homelab (private IP), but I want to access it from the Internet.
**The solution**:
1. A **Scaleway Dedibox** with a fixed public IP and Nginx Proxy Manager
2. A **Wireguard VPN** between the Dedibox and the homelab
3. The reverse proxy routes `gitea.arnodo.fr` to the LXC's private IP through the tunnel
**Wireguard configuration (homelab side)**:
```ini
[Interface]
Address = 10.0.0.1/24
PrivateKey = <private_key>
ListenPort = 51820
[Peer]
# Dedibox Scaleway
PublicKey = <dedibox_public_key>
AllowedIPs = 10.0.0.2/32
Endpoint = <dedibox_public_ip>:51820
PersistentKeepalive = 25
```
**Nginx Proxy Manager**:
- Proxy Host: `gitea.arnodo.fr`
- Forward Hostname/IP: `10.0.0.x` (Gitea LXC IP over Wireguard)
- Forward Port: `3000`
- SSL: automatic Let's Encrypt
- Websockets: Enabled
### Management with Ansible
To keep Gitea up to date and manage configurations, I use Ansible.
**Update playbook** (`update-gitea.yml`):
```yaml
---
- name: Update Gitea
hosts: gitea
become: yes
tasks:
- name: Update apt cache
apt:
update_cache: yes
cache_valid_time: 3600
- name: Upgrade Gitea and system packages
apt:
upgrade: dist
autoremove: yes
autoclean: yes
- name: Restart Gitea service
systemd:
name: gitea
state: restarted
enabled: yes
- name: Check Gitea version
command: gitea --version
register: gitea_version
- debug:
msg: "{{ gitea_version.stdout }}"
```
**Execution**:
```bash
ansible-playbook -i inventory.ini update-gitea.yml
```
### Monitoring with Grafana
Gitea exposes Prometheus metrics (https://docs.gitea.com/administration/config-cheat-sheet#metrics-metrics)
Configuration:
**In Gitea (`app.ini`)**:
```ini
[metrics]
ENABLED = true
TOKEN = <secret_token>
```
**Prometheus scrape config**:
```yaml
scrape_configs:
- job_name: 'gitea'
metrics_path: /metrics
bearer_token: '<secret_token>'
static_configs:
- targets: ['<gitea_lxc_ip>:3000']
```
**Grafana dashboard** (https://grafana.com/docs/grafana-cloud/monitor-infrastructure/integrations/integration-reference/integration-gitea/#gitea-integration-for-grafana-cloud):
- Number of repositories, users
- HTTP requests (rate, latency)
- CI/CD runner status
- LXC CPU/RAM usage
### Migrating Code from GitHub
Simple and fast:
Use Gitea's import feature (Settings > New Migration > GitHub), which also migrates issues and releases.
### CI/CD: Deploying Hugo to Scaleway Object Storage
My Hugo blog deploys automatically to Scaleway Object Storage on every push.
**Installing the Gitea Runner** (https://docs.gitea.com/usage/actions/act-runner)
Create the system user for the runner:
```bash
useradd -r -m -d /var/lib/gitea-runner -s /bin/bash gitea-runner
```
Here's a small script that can help install the runner directly inside an LXC:
```bash
sudo apt install -y jq curl tar # si pas déjà
LATEST=$(curl -s 'https://gitea.com/api/v1/repos/gitea/act_runner/releases' | jq -r '.[0].tag_name')
echo "Latest act_runner: $LATEST"
# construire URL de binaire (nommage used: act_runner-<os>-<arch>)
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
# Certains serveurs distribuent binaire sans tar; adapter si archive
URL="https://gitea.com/gitea/act_runner/releases/download/${LATEST}/act_runner-${LATEST#v}-${OS}-${ARCH}"
# essayer télécharger binaire
curl -fL "$URL" -o /tmp/act_runner || {
echo "Téléchargement direct échoué — vérifier le nom exact sur la page release." >&2
exit 1
}
sudo mv /tmp/act_runner /usr/local/bin/act_runner
sudo chmod +x /usr/local/bin/act_runner
```
and to verify:
```bash
/usr/local/bin/act_runner --version
```
>[!NOTE]
> It's important to register the runner so it's recognized by Gitea.
> For more information on configuring the runner, check the official Gitea documentation.
> https://docs.gitea.io/fr/docs/usage/actions/runner/
**Gitea Actions workflow** (`.gitea/workflows/deploy.yml`):
```yaml
name: Build and Deploy Hugo
on:
pull_request:
types: [closed]
branches:
- main
jobs:
build_and_deploy:
if: github.event.pull_request.merged == true
name: Deploy Hugo Website
runs-on: self-hosted
container:
image: debian:bookworm-slim
steps:
- name: Install dependencies
run: |
apt-get update
apt-get install -y git curl ca-certificates wget
- name: Install Hugo
run: |
wget https://github.com/gohugoio/hugo/releases/download/v0.152.2/hugo_extended_withdeploy_0.152.2_linux-amd64.deb -O /tmp/hugo.deb
dpkg -i /tmp/hugo.deb
- name: Checkout code
run: |
git clone --recurse-submodules https://gitea.arnodo.fr/Damien/Notebook.git /tmp/workspace
cd /tmp/workspace
git checkout ${{ github.sha }}
- name: Build site
run: /usr/local/bin/hugo
working-directory: /tmp/workspace
- name: Deploy to Scaleway
run: /usr/local/bin/hugo deploy --force --maxDeletes -1
working-directory: /tmp/workspace
env:
AWS_ACCESS_KEY_ID: ${{ secrets.SCW_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SCW_SECRET_KEY }}
```
**Hugo configuration** (`hugo.yaml`):
```yaml
deployment:
targets:
- name: "notebook-arnodo-fr"
URL: "s3://notebook-arnodo-fr?endpoint=https://s3.fr-par.scw.cloud&region=fr-par"
```
**Scaleway Object Storage configuration**:
1. Create a `notebook-arnodo-fr` bucket
2. Enable "Static Website Hosting" mode
3. Generate API credentials (Access Key + Secret Key)
4. Add them as secrets in Gitea (Settings > Secrets > Actions)
**Deployment**:
```bash
git add .
git commit -m "New blog post"
git push origin main
```
The workflow triggers automatically, Hugo builds the site, and deploys it to Scaleway Object Storage. The site is instantly available via the CDN.
## Part 2: Network Labs on Scaleway
### The Problem
Running ContainerLab with several Arista EOS instances locally is:
- **Resource-hungry**: 4-8 GB RAM per cEOS container
- **Local-only**: No access from outside
- **Conflict-prone**: With other Docker/K8s services
### The Solution: On-Demand Scaleway Instances
**Concept**:
- Spin up a Scaleway instance whenever I need a lab
- Automatically install ContainerLab/the VPN via cloud-init
- Destroy the instance after use
- Billed by the hour (< €1 for a few hours of lab time)
### Automation Script: Scaleway CLI
I built a Bash script that manages the entire lifecycle of a lab instance.
**Features**:
- **Creation**: Instance + Security Group (SSH from my IP only)
- **Start/Stop**: Instance management
- **Deletion**: Full cleanup (instance, volumes, IP, SG)
**Script structure** (`scaleway-instance.sh`):
```bash
#!/bin/bash
# Configuration
INSTANCE_NAME="NetLab"
ZONE="fr-par-1"
IMAGE="debian_bookworm"
VOLUME_SIZE=20 # GB
USER_DATA_FILE="user_data.txt"
SECURITY_GROUP_NAME="${INSTANCE_NAME}-SG"
# Détecte l'IP publique actuelle
get_public_ip() {
curl -4 -s ifconfig.me
}
# Crée un Security Group limitant SSH à l'IP publique
create_or_update_security_group() {
PUBLIC_IP=$(get_public_ip)
# Crée le SG avec inbound SSH uniquement depuis PUBLIC_IP/32
# ...
}
# Actions : create, start, stop, delete
case "$1" in
start)
# Démarre l'instance existante
scw instance server start "$INSTANCE_ID" --wait
;;
stop)
# Arrête l'instance
scw instance server stop "$INSTANCE_ID" --wait
;;
delete)
# Supprime instance + volumes + IP + SG
scw instance server terminate "$INSTANCE_ID" --with-ip --with-block
scw instance security-group delete "$SG_ID"
;;
*)
# Crée une nouvelle instance
create_instance "$1" # Type d'instance (DEV1-S, GP1-XS, ...)
;;
esac
```
### Cloud-Init: Automatic Configuration
The `user_data.txt` file contains the cloud-init instructions to automatically provision the instance.
**Example** (`user_data.txt`):
```yaml
#cloud-config
package_update: true
package_upgrade: true
packages:
- git
- curl
- docker.io
- docker-compose
runcmd:
# Installation de ContainerLab
- bash -c "$(curl -sL https://get.containerlab.dev)"
# Clone d'un repo avec des topologies
- git clone https://gitea.arnodo.fr/Damien/network-labs.git /root/labs
# Démarrage d'une topologie par défaut
- cd /root/labs && containerlab deploy -t spine-leaf.clab.yml
```
### Practical Usage
**Create a lab**:
```bash
# Crée une instance DEV1-S avec 20 GB de stockage
./scaleway-instance.sh DEV1-S 20
# Attend quelques minutes pour cloud-init
# Récupère l'IP publique
scw instance server list name=NetLab -o json | jq -r '.servers[0].public_ip.address'
# SSH vers l'instance
ssh root@<IP_PUBLIQUE>
# ContainerLab est déjà lancé !
containerlab inspect
```
**Destroy the lab**:
```bash
./scaleway-instance.sh delete
```
### Raycast Integration
To make things even simpler, I created a Raycast script that lets me manage my instances directly from my Mac.
**Raycast script**:
```bash
#!/bin/bash
# @raycast.schemaVersion 1
# @raycast.title Scaleway Instance
# @raycast.mode silent
# @raycast.icon 🖥️
# @raycast.argument1 { "type": "text", "placeholder": "Action or instance type" }
# @raycast.argument2 { "type": "text", "placeholder": "Volume size", "optional": true }
# @raycast.packageName NetLab
/path/to/scaleway-instance.sh "$1" "$2"
```
**Usage**:
- `⌘ + Space` → "Scaleway Instance DEV1-S" → Creates the instance
- `⌘ + Space` → "Scaleway Instance delete" → Deletes the instance
### Use Case: BGP/EVPN Lab with Arista
**ContainerLab topology** (`spine-leaf.clab.yml`):
```yaml
name: evpn-lab
topology:
nodes:
spine1:
kind: ceos
image: ceos:latest
spine2:
kind: ceos
image: ceos:latest
leaf1:
kind: ceos
image: ceos:latest
leaf2:
kind: ceos
image: ceos:latest
links:
- endpoints: ["spine1:eth1", "leaf1:eth1"]
- endpoints: ["spine1:eth2", "leaf2:eth1"]
- endpoints: ["spine2:eth1", "leaf1:eth2"]
- endpoints: ["spine2:eth2", "leaf2:eth2"]
```
**Workflow**:
1. Create the Scaleway instance
2. Cloud-init deploys the topology
3. Configure BGP/EVPN via Ansible or manually
4. Test, experiment
5. Destroy the instance
**Cost**: DEV1-S instance (2 vCPU, 2GB) = ~€0.015/hour. 4 hours of lab time = €0.06.
## Digital Sovereignty: Why It Matters
This hybrid infrastructure reflects a personal conviction about digital sovereignty.
### The Context
In my work as a network engineer, I see how important it is to be in control of your own infrastructure.
Choosing Scaleway (part of the Iliad group, French) and self-hosting Gitea means:
- **Supporting the European tech ecosystem**
- **Ensuring GDPR compliance**: French jurisdiction
- **Reducing latency**: Datacenters in Paris
- **Understanding**: Owning your entire chain end-to-end
### Learning by Doing
As a network professional (Arista, BGP/EVPN, automation), self-hosting lets me:
- Apply Infrastructure as Code principles
- Deeply understand CI/CD mechanics
- Experiment without limits
- Reproduce professional environments
## Assessment
### What Works Well
**Self-hosted Gitea**:
- Very fast and stable
- Proxmox Helper Scripts = 5-minute install
- Ansible handles updates cleanly
- Grafana monitors everything
**Wireguard + Nginx Proxy Manager**:
- Secure exposure of the homelab
- Excellent performance
- Simple configuration
**Scaleway labs**:
- Provisioning in 3 minutes
- Total flexibility (size, duration)
- Predictable costs (hourly billing)
**CI/CD Hugo → Scaleway Object Storage**:
- Push-to-deploy in 2 minutes
- Free (a few cents/month for storage)
- Built-in CDN = ultra-fast site
### The Challenges
**Initial complexity**:
- Wireguard + reverse proxy = learning curve
- First Proxmox/LXC setup = a few hours
**Maintenance**:
- Responsibility for updates (thankfully Ansible helps!)
- Monitoring to set up yourself
- Backups to automate
**Dependencies**:
- If the Dedibox goes down, Gitea becomes unreachable
- Solution: failover with a second Dedibox or VPS (coming soon)
## Next Steps
- **High availability**: A second Dedibox for failover
- **Automatic backup**: Scripts to back up Gitea to Scaleway Object Storage
- **More automation**: Terraform to provision the entire Scaleway infrastructure
- **Arista MCP**: Building an MCP server to interact with network equipment via local LLMs
- **Netbox integration**: Webhook from Netbox to a network validation pipeline
## Conclusion
This hybrid infrastructure (Proxmox homelab + Scaleway cloud) offers the best of both worlds:
- **Control**: Sensitive data (code, configurations) stays in the homelab
- **Flexibility**: Cloud resources for one-off needs
- **Learning**: A complete environment to experiment in
- **Sovereignty**: Everything hosted in France, with European providers
Self-hosting isn't just about costs (spoiler: I pay about as much as before, if not more), but about learning, mastery, and a deep understanding of systems.
For a network or DevOps engineer, it's the ideal environment to reproduce professional use cases and build up skills.
## Resources
### Documentation
- [Gitea](https://docs.gitea.io/)
- [Proxmox Helper Scripts](https://community-scripts.github.io/ProxmoxVE/)
- [Scaleway CLI](https://www.scaleway.com/en/cli/)
- [ContainerLab](https://containerlab.dev/)
- [Nginx Proxy Manager](https://nginxproxymanager.com/)
### My Repos
- [Blog Hugo](https://gitea.arnodo.fr/Damien/blog)
- [Network Labs](https://gitea.arnodo.fr/Damien/arista-evpn-vxlan-clab) (ContainerLab topologies)
- [Scaleway Scripts](https://gitea.arnodo.fr/Damien/scaleway-automation)
### Community
- [Proxmox Forum](https://forum.proxmox.com/)
- [r/homelab](https://reddit.com/r/homelab)
- [ContainerLab Slack](https://containerlab.dev/)