diff --git a/assets/css/extra.css b/assets/css/extra.css index d7747a5..d3ce8f0 100644 --- a/assets/css/extra.css +++ b/assets/css/extra.css @@ -49,6 +49,18 @@ max-width: var(--elements-container-maxWidth); } +.has-parent-icon .icon { + color: #ADA9A4; +} + +.has-parent-icon.active .icon { + color: var(--color-primary-500) !important; +} + +.card:hover{ + color:#00304a; +} + p img { border-radius:7px; } diff --git a/content/1.about/1.welcome.md b/content/1.about/1.welcome.md index 2a154d6..05faf64 100644 --- a/content/1.about/1.welcome.md +++ b/content/1.about/1.welcome.md @@ -1,4 +1,5 @@ --- +icon: lucide:home title: Welcome main: fluid: false diff --git a/content/2.general/1.nat.md b/content/2.general/1.networking/1.nat.md similarity index 100% rename from content/2.general/1.nat.md rename to content/2.general/1.networking/1.nat.md diff --git a/content/2.general/2.dns.md b/content/2.general/1.networking/2.dns.md similarity index 100% rename from content/2.general/2.dns.md rename to content/2.general/1.networking/2.dns.md diff --git a/content/2.general/3.samba.md b/content/2.general/1.networking/3.samba.md similarity index 100% rename from content/2.general/3.samba.md rename to content/2.general/1.networking/3.samba.md diff --git a/content/2.general/1.networking/_dir.yml b/content/2.general/1.networking/_dir.yml new file mode 100644 index 0000000..38f5d9b --- /dev/null +++ b/content/2.general/1.networking/_dir.yml @@ -0,0 +1,2 @@ +navigation.title: Networking +icon: lucide:network diff --git a/content/2.general/4.raid.md b/content/2.general/2.storage/1.raid.md similarity index 100% rename from content/2.general/4.raid.md rename to content/2.general/2.storage/1.raid.md diff --git a/content/2.general/5.zfs.md b/content/2.general/2.storage/2.zfs.md similarity index 100% rename from content/2.general/5.zfs.md rename to content/2.general/2.storage/2.zfs.md diff --git a/content/2.general/2.storage/_dir.yml b/content/2.general/2.storage/_dir.yml new file mode 100644 index 0000000..b8ff026 --- /dev/null +++ b/content/2.general/2.storage/_dir.yml @@ -0,0 +1,2 @@ +navigation.title: Storage +icon: lucide:hard-drive \ No newline at end of file diff --git a/content/3.serveex/1.introduction.md b/content/3.serveex/1.introduction.md index 9e61f5c..a2abb6c 100644 --- a/content/3.serveex/1.introduction.md +++ b/content/3.serveex/1.introduction.md @@ -1,4 +1,5 @@ --- +icon: lucide:bookmark navigation: true title: Introduction main: diff --git a/content/3.serveex/2.core/_dir.yml b/content/3.serveex/2.core/_dir.yml index 2eb8930..e6677c8 100644 --- a/content/3.serveex/2.core/_dir.yml +++ b/content/3.serveex/2.core/_dir.yml @@ -1 +1,2 @@ navigation.title: Server core +icon: lucide:server-cog diff --git a/content/3.serveex/3.security/_dir.yml b/content/3.serveex/3.security/_dir.yml index 148ce60..946a40c 100644 --- a/content/3.serveex/3.security/_dir.yml +++ b/content/3.serveex/3.security/_dir.yml @@ -1 +1,2 @@ navigation.title: Security +icon: lucide:shield diff --git a/content/3.serveex/4.monitoring/_dir.yml b/content/3.serveex/4.monitoring/_dir.yml index a147d7a..419b48b 100644 --- a/content/3.serveex/4.monitoring/_dir.yml +++ b/content/3.serveex/4.monitoring/_dir.yml @@ -1 +1,2 @@ navigation.title: Monitoring +icon: lucide:chart-no-axes-column diff --git a/content/3.serveex/5.media/_dir.yml b/content/3.serveex/5.media/_dir.yml index 02b52c4..7ddf5e8 100644 --- a/content/3.serveex/5.media/_dir.yml +++ b/content/3.serveex/5.media/_dir.yml @@ -1 +1,2 @@ navigation.title: Media & Seedbox +icon: lucide:list-video diff --git a/content/3.serveex/6.cloud/_dir.yml b/content/3.serveex/6.cloud/_dir.yml index 2f5fcc6..ee77be3 100644 --- a/content/3.serveex/6.cloud/_dir.yml +++ b/content/3.serveex/6.cloud/_dir.yml @@ -1 +1,2 @@ navigation.title: Cloud Drive & Photos +icon: lucide:cloud-upload diff --git a/content/3.serveex/7.files/_dir.yml b/content/3.serveex/7.files/_dir.yml index b217245..94dcd22 100644 --- a/content/3.serveex/7.files/_dir.yml +++ b/content/3.serveex/7.files/_dir.yml @@ -1 +1,2 @@ -navigation.title: File & share \ No newline at end of file +navigation.title: File & share +icon: lucide:folder-tree \ No newline at end of file diff --git a/content/3.serveex/8.development/_dir.yml b/content/3.serveex/8.development/_dir.yml index 87e09b2..3d2ca2b 100644 --- a/content/3.serveex/8.development/_dir.yml +++ b/content/3.serveex/8.development/_dir.yml @@ -1 +1,2 @@ -navigation.title: Developpement \ No newline at end of file +navigation.title: Developpement +icon: lucide:code-xml \ No newline at end of file diff --git a/content/3.serveex/9.apps/_dir.yml b/content/3.serveex/9.apps/_dir.yml index 6972e2b..7db12ee 100644 --- a/content/3.serveex/9.apps/_dir.yml +++ b/content/3.serveex/9.apps/_dir.yml @@ -1 +1,2 @@ navigation.title: Useful Apps +icon: lucide:award diff --git a/content/4.Stockeex/1.introduction.md b/content/4.Stockeex/1.introduction.md index fbb5ff9..0f6f109 100644 --- a/content/4.Stockeex/1.introduction.md +++ b/content/4.Stockeex/1.introduction.md @@ -1,4 +1,5 @@ --- +icon: lucide:bookmark navigation: true title: Introduction main: diff --git a/content/5.nonsense/1.python/1.nvidia-stock-bot.md b/content/5.nonsense/1.python/1.nvidia-stock-bot.md new file mode 100644 index 0000000..7d4267f --- /dev/null +++ b/content/5.nonsense/1.python/1.nvidia-stock-bot.md @@ -0,0 +1,39 @@ +--- +navigation: true +title: Nvidia Stock Bot +main: + fluid: false +--- +:ellipsis{left=0px width=40rem top=10rem blur=140px} + +# 🤖 Nvidia Stock Bot +--- + +For the past four years, the electronics hardware shortage has been relentless. Graphics cards are no exception. In 2020, I had to wait two months to get my RTX 3080. To manage it, I joined [JV Hardware](https://discord.gg/gxffg3GA96), where a small group of geeks had set up a bot that pinged users when GPUs became available. + +Four years later and with 5,000 members on the server, the RTX 5000 series is being released. Yet, no working stock bot seems to exist. Not to mention a certain “influencer” who charges users for access to a bot that doesn’t even work. He manually copies alerts from other servers like ours, which have already solved the issue. + +Anyway, eager to get an RTX 5090 for my AI-dedicated machine, I decided it was time to dive into Python—with a little help from ChatGPT. Along with another member, KevOut, who helped guide me through the APIs and initial architecture, I ended up building a clean and functional bot that sends different kinds of Discord alerts—all deployable in a simple Docker container. + +After many setbacks, I went from this: + +![Nvidia Stock Bot Old](/img/nonsense/nvidia-stock-bot-old-en.svg) + +To this: + +![Nvidia Stock bot](/img/nonsense/nvidia-stock-bot-en.svg) + +And more recently : + +![Nvidia Stock bot](/img/nonsense/nvidia-stock-bot-en-v4.svg) + +And I was also lucky enough to be referenced in the famous [selfhost newsletter](https://selfh.st/weekly/2025-07-11/) ! + +More info directly on the repo: + +::card +#title + 🐋 __Nvidia Stock Bot__ +#description + [Nvidia GPU stock alert bot](https://git.djeex.fr/Djeex/nvidia-stock-bot) +:: diff --git a/content/5.nonsense/2.python.md b/content/5.nonsense/1.python/2. adguard-cidre.md similarity index 51% rename from content/5.nonsense/2.python.md rename to content/5.nonsense/1.python/2. adguard-cidre.md index a345ddf..d0e9712 100644 --- a/content/5.nonsense/2.python.md +++ b/content/5.nonsense/1.python/2. adguard-cidre.md @@ -1,47 +1,12 @@ --- navigation: true -title: Python Scripts +title: Adguard CIDRE main: fluid: false --- :ellipsis{left=0px width=40rem top=10rem blur=140px} -# Python Scripts -My messy Python creations - -## 🤖 Nvidia Stock Bot ---- - -For the past four years, the electronics hardware shortage has been relentless. Graphics cards are no exception. In 2020, I had to wait two months to get my RTX 3080. To manage it, I joined [JV Hardware](https://discord.gg/gxffg3GA96), where a small group of geeks had set up a bot that pinged users when GPUs became available. - -Four years later and with 5,000 members on the server, the RTX 5000 series is being released. Yet, no working stock bot seems to exist. Not to mention a certain “influencer” who charges users for access to a bot that doesn’t even work. He manually copies alerts from other servers like ours, which have already solved the issue. - -Anyway, eager to get an RTX 5090 for my AI-dedicated machine, I decided it was time to dive into Python—with a little help from ChatGPT. Along with another member, KevOut, who helped guide me through the APIs and initial architecture, I ended up building a clean and functional bot that sends different kinds of Discord alerts—all deployable in a simple Docker container. - -After many setbacks, I went from this: - -![Nvidia Stock Bot Old](/img/nonsense/nvidia-stock-bot-old-en.svg) - -To this: - -![Nvidia Stock bot](/img/nonsense/nvidia-stock-bot-en.svg) - -And more recently : - -![Nvidia Stock bot](/img/nonsense/nvidia-stock-bot-en-v4.svg) - -And I was also lucky enough to be referenced in the famous [selfhost newsletter](https://selfh.st/weekly/2025-07-11/) ! - -More info directly on the repo: - -::card -#title - 🐋 __Nvidia Stock Bot__ -#description - [Nvidia GPU stock alert bot](https://git.djeex.fr/Djeex/nvidia-stock-bot) -:: - -## 🤖 Adguard CIDRE Sync +# 🤖 Adguard CIDRE Sync --- Adguard Home is a fantastic solution for DNS-level ad blocking and rewriting requests—perfect for removing ISP DNS trackers or intrusive ads. diff --git a/content/5.nonsense/1.python/_dir.yml b/content/5.nonsense/1.python/_dir.yml new file mode 100644 index 0000000..699a9cd --- /dev/null +++ b/content/5.nonsense/1.python/_dir.yml @@ -0,0 +1,2 @@ +navigation.title: Python +icon: lucide:file-code-2 \ No newline at end of file diff --git a/content/5.nonsense/1.bash.md b/content/5.nonsense/2.bash/1.servarr-duplicates.md similarity index 64% rename from content/5.nonsense/1.bash.md rename to content/5.nonsense/2.bash/1.servarr-duplicates.md index 3118abc..8ea7d8a 100644 --- a/content/5.nonsense/1.bash.md +++ b/content/5.nonsense/2.bash/1.servarr-duplicates.md @@ -5,11 +5,7 @@ main: fluid: false --- :ellipsis{left=0px width=40rem top=10rem blur=140px} -# Bash Scripts - -A few random scripts that saved my life. - -## Detecting Duplicates and Replacing Them with Hardlinks +# Servarr duplicates corrector --- Six months after downloading terabytes of media, I realized that Sonarr and Radarr were copying them into my Plex library instead of creating hardlinks. This happens due to a counterintuitive mechanism: if you mount multiple folders in Sonarr/Radarr, it sees them as different filesystems and thus cannot create hardlinks. That’s why you should mount only one parent folder containing all child folders (like `downloads`, `movies`, `tvseries` inside a `media` parent folder). @@ -143,84 +139,3 @@ So, in conclusion, I: - Learned never to blindly copy-paste a ChatGPT script without understanding and dry-running it - Learned that Qwen on a RTX 5090 is more coherent than ChatGPT-4o on server farms (not even mentioning “normal” ChatGPT) - Learned that even with 100TB of storage, monitoring it would’ve alerted me much earlier to the 12TB of duplicates lying around - -## Backup of LUKS Headers for Encrypted Disks/Volumes ---- - -I recently realized that having just the password is not enough to unlock a LUKS volume after a failure or corruption. I learned how to dump the LUKS headers from disks/volumes and to use the serial numbers along with partition names to accurately identify which header corresponds to which disk/partition (I have 10 of them!). - -After struggling to do this manually, I asked Qwen3 (an LLM running on my RTX 5090) to create a script that automates the listing and identification of disks, dumps the headers, and stores them in an encrypted archive ready to be backed up on my backup server. - -This script: -* Lists and identifies disks with their serial numbers -* Lists partitions -* Dumps headers into a secured folder under `/root` -* Creates a temporary archive -* Prompts for a password -* Encrypts the archive with that password -* Deletes the unencrypted archive - -```bash -#!/bin/bash - -# Directory where LUKS headers will be backed up -DEST="/root/luks-headers-backup" -mkdir -p "$DEST" - -echo "🔍 Searching for LUKS containers on all partitions..." - -# Loop through all possible disk partitions (including NVMe and SATA) -for part in /dev/sd? /dev/sd?? /dev/nvme?n?p?; do - # Skip if the device doesn't exist - if [ ! -b "$part" ]; then - continue - fi - - # Check if the partition is a LUKS encrypted volume - if cryptsetup isLuks "$part"; then - # Find the parent disk device (e.g. nvme0n1p4 → nvme0n1) - disk=$(lsblk -no pkname "$part" | head -n 1) - full_disk="/dev/$disk" - - # Get the serial number of the parent disk - SERIAL=$(udevadm info --query=all --name="$full_disk" | grep ID_SERIAL= | cut -d= -f2) - if [ -z "$SERIAL" ]; then - SERIAL="unknown" - fi - - # Extract the partition name (e.g. nvme0n1p4) - PART_NAME=$(basename "$part") - - # Build the output filename with partition name and disk serial - OUTPUT="$DEST/luks-header-${PART_NAME}__${SERIAL}.img" - - echo "🔐 Backing up LUKS header of $part (Serial: $SERIAL)..." - - # Backup the LUKS header to the output file - cryptsetup luksHeaderBackup "$part" --header-backup-file "$OUTPUT" - if [[ $? -eq 0 ]]; then - echo "✅ Backup successful → $OUTPUT" - else - echo "❌ Backup failed for $part" - fi - fi -done - -# Create a timestamped compressed tar archive of all header backups -ARCHIVE_NAME="/root/luks-headers-$(date +%Y%m%d_%H%M%S).tar.gz" -echo "📦 Creating archive $ARCHIVE_NAME..." -tar -czf "$ARCHIVE_NAME" -C "$DEST" . - -# Encrypt the archive symmetrically using GPG with AES256 cipher -echo "🔐 Encrypting the archive with GPG..." -gpg --symmetric --cipher-algo AES256 "$ARCHIVE_NAME" -if [[ $? -eq 0 ]]; then - echo "✅ Encrypted archive created: ${ARCHIVE_NAME}.gpg" - # Remove the unencrypted archive for security - rm -f "$ARCHIVE_NAME" -else - echo "❌ Encryption failed" -fi -``` - -**Don’t forget to back up `/etc/fstab` and `/etc/crypttab` as well!** diff --git a/content/5.nonsense/2.bash/2.luks- backup.md b/content/5.nonsense/2.bash/2.luks- backup.md new file mode 100644 index 0000000..92e96bc --- /dev/null +++ b/content/5.nonsense/2.bash/2.luks- backup.md @@ -0,0 +1,88 @@ +--- +navigation: true +title: LUKS Backup +main: + fluid: false +--- +:ellipsis{left=0px width=40rem top=10rem blur=140px} + +# Backup of LUKS Headers for Encrypted Disks/Volumes +--- + +I recently realized that having just the password is not enough to unlock a LUKS volume after a failure or corruption. I learned how to dump the LUKS headers from disks/volumes and to use the serial numbers along with partition names to accurately identify which header corresponds to which disk/partition (I have 10 of them!). + +After struggling to do this manually, I asked Qwen3 (an LLM running on my RTX 5090) to create a script that automates the listing and identification of disks, dumps the headers, and stores them in an encrypted archive ready to be backed up on my backup server. + +This script: +* Lists and identifies disks with their serial numbers +* Lists partitions +* Dumps headers into a secured folder under `/root` +* Creates a temporary archive +* Prompts for a password +* Encrypts the archive with that password +* Deletes the unencrypted archive + +```bash +#!/bin/bash + +# Directory where LUKS headers will be backed up +DEST="/root/luks-headers-backup" +mkdir -p "$DEST" + +echo "🔍 Searching for LUKS containers on all partitions..." + +# Loop through all possible disk partitions (including NVMe and SATA) +for part in /dev/sd? /dev/sd?? /dev/nvme?n?p?; do + # Skip if the device doesn't exist + if [ ! -b "$part" ]; then + continue + fi + + # Check if the partition is a LUKS encrypted volume + if cryptsetup isLuks "$part"; then + # Find the parent disk device (e.g. nvme0n1p4 → nvme0n1) + disk=$(lsblk -no pkname "$part" | head -n 1) + full_disk="/dev/$disk" + + # Get the serial number of the parent disk + SERIAL=$(udevadm info --query=all --name="$full_disk" | grep ID_SERIAL= | cut -d= -f2) + if [ -z "$SERIAL" ]; then + SERIAL="unknown" + fi + + # Extract the partition name (e.g. nvme0n1p4) + PART_NAME=$(basename "$part") + + # Build the output filename with partition name and disk serial + OUTPUT="$DEST/luks-header-${PART_NAME}__${SERIAL}.img" + + echo "🔐 Backing up LUKS header of $part (Serial: $SERIAL)..." + + # Backup the LUKS header to the output file + cryptsetup luksHeaderBackup "$part" --header-backup-file "$OUTPUT" + if [[ $? -eq 0 ]]; then + echo "✅ Backup successful → $OUTPUT" + else + echo "❌ Backup failed for $part" + fi + fi +done + +# Create a timestamped compressed tar archive of all header backups +ARCHIVE_NAME="/root/luks-headers-$(date +%Y%m%d_%H%M%S).tar.gz" +echo "📦 Creating archive $ARCHIVE_NAME..." +tar -czf "$ARCHIVE_NAME" -C "$DEST" . + +# Encrypt the archive symmetrically using GPG with AES256 cipher +echo "🔐 Encrypting the archive with GPG..." +gpg --symmetric --cipher-algo AES256 "$ARCHIVE_NAME" +if [[ $? -eq 0 ]]; then + echo "✅ Encrypted archive created: ${ARCHIVE_NAME}.gpg" + # Remove the unencrypted archive for security + rm -f "$ARCHIVE_NAME" +else + echo "❌ Encryption failed" +fi +``` + +**Don’t forget to back up `/etc/fstab` and `/etc/crypttab` as well!** diff --git a/content/5.nonsense/2.bash/_dir.yml b/content/5.nonsense/2.bash/_dir.yml new file mode 100644 index 0000000..e339ff9 --- /dev/null +++ b/content/5.nonsense/2.bash/_dir.yml @@ -0,0 +1,2 @@ +navigation.title: Bash +icon: lucide:file-terminal \ No newline at end of file