Post

🟢 🧪 Chirpy + 🧭 GPX - LXC 106 (devel) -

🟢 🧪 Chirpy + 🧭 GPX - LXC 106 (devel) -

Installer un générateur de site statique de type jekyll dans un conteneur proxmox LXC Debian 13

Proxmox LXC

Créer un container LXC Debian 13 , ouvrir la console shell et exécuter

1
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh)"

Procédure manuelle Accès root avec mot de passe via ssh Ip fixe 192.168.0.227 gateway 192.168.0.254 dns 1.1.1.1 mémoire 2048Mb Dique 15Go

Debian 13

Se connecter en root via ssh

Créer utilisateur

Mise à jour debian

1
sudo apt update && sudo apt upgrade

Créer un utilisateur

1
2
3
4
adduser jek  # MP jek49
# droits root
apt install sudo
echo "jek     ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/10-userx

Se reconnecter en mode utilisateur via ssh

Connexion avec clés

Sur le poste appelant Générer un jeu de clé

1
ssh-keygen -t ed25519 -o -a 100 -f ~/.ssh/lxc-devel

Envoyer la clé publique sur le container lxc

1
ssh-copy-id -i ~/.ssh/lxc-devel.pub jek@192.168.0.227

Sur le container LXC

1
2
3
4
5
# passer en su
sudo -s
echo "PasswordAuthentication no" > /etc/ssh/sshd_config.d/jek.conf
# Redémarrer le serveur ssh
systemctl restart sshd

Sur le poste appelant Lancer la connexion SSH avec clé

1
ssh -i ~/.ssh/lxc-devel jek@192.168.0.227

Proxmox ajout partage NFS

Le partage NFS a été renommé chirpy et est monté sur /mnt/pve/chirpy

lxc.mount

Dans le conteneur LXC, commencez par créer le dossier qui va accueillir le point de montage.

1
2
mkdir /srv/media 
sudo chown 1000:1000 /srv/media

Dans le shell Proxmox ouvrir le fichier de configuration du conteneur LXC (conteneur 106).

1
nano /etc/pve/lxc/106.conf

Enfin, ajoutez la ligne suivante en pensant bien à l’adapter à votre configuration.

1
lxc.mount.entry = /mnt/pve/chirpy srv/media  none bind 0 0

Sauvegardez le tout (Ctrl+O), redémarrez le conteneur et normalement vous devriez avoir le point de montage qui apparait.

node

Installer NodeJs via nvm

Versions installée node -v && npm -v

1
2
v24.14.0
11.9.0

🧪 Jekyll

Installation jekyll

1
2
3
4
5
6
sudo apt install ruby-full build-essential zlib1g-dev -y
echo '# Install Ruby Gems to ~/gems' >> ~/.bashrc 
echo 'export GEM_HOME="$HOME/gems"' >> ~/.bashrc 
echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.bashrc 
source ~/.bashrc 
gem install jekyll bundler

jekyll-theme-chirpy

Générateur site statique (ruby+jekyll) Installer git et imagemagick

1
sudo apt install git imagemagick

Sur le home

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cd ~
git clone https://github.com/cotes2020/jekyll-theme-chirpy.git
# initialiser le dépôt
cd ~/jekyll-theme-chirpy
bash tools/init.sh
#
cd assets/img/favicons/
magick web-app-manifest-512x512.png -resize 16x16 favicon-16x16.png
magick web-app-manifest-512x512.png -resize 32x32 favicon-32x32.png
magick web-app-manifest-512x512.png -resize 150x150 mstile-150x150.png
magick web-app-manifest-512x512.png -resize 192x192 android-chrome-512x512.png
cp web-app-manifest-512x512.png android-chrome-512x512.png
# A partir d'un fichier svg
magick favicon.svg -resize 512x512 android-chrome-512x512.png
magick favicon.svg -resize 512x512 web-app-manifest-512x512.png
magick favicon.svg -resize 16x16 favicon-16x16.png
magick favicon.svg -resize 32x32 favicon-32x32.png
magick favicon.svg -resize 150x150 mstile-150x150.png
magick favicon.svg -resize 180x180 apple-touch-icon.png
magick favicon.svg -resize 192x192 android-chrome-512x512.png
magick favicon.svg favicon.ico
magick favicon.svg -resize 192x192 android-chrome-192x192.png
magick favicon.svg -resize 96x96 favicon-96x96.png

Retour racine

1
cd ~/jekyll-theme-chirpy

Modifier configuration _config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# The Site Configuration

# Import the theme
theme: jekyll-theme-chirpy

# The language of the webpage › http://www.lingoes.net/en/translator/langcode.htm
# If it has the same name as one of the files in folder `_data/locales`, the layout language wi>
# otherwise, the layout language will use the default value of 'en'.
lang: fr

# Change to your timezone › https://zones.arilyn.cc
timezone: Europe/Paris

# jekyll-seo-tag settings › https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/usage.md
# ↓ --------------------------

title: Chirpy DEV # the main title

social:
  # Change to your full name.
  # It will be displayed as the default author of the posts and the copyright owner in the Foot>
  name: jek
  email: jek@cinay.eu # change to your email address

theme_mode: dark # [light | dark]

Modifier Gemfile

1
2
3
4
5
6
7
8
9
10
11
12
# frozen_string_literal: true

source "https://rubygems.org"

gemspec

gem "html-proofer", "~> 5.0", group: :test

gem "tzinfo", ">= 1", "< 3"
gem "tzinfo-data"

gem "wdm", "~> 0.2.0"

Si Gemfile.lock existe, le supprimer Lancer

1
bundle

Info jekyll: bundle info jekyll

1
2
3
4
5
6
7
8
9
10
11
12
13
  * jekyll (4.4.1)
	Summary: A simple, blog aware, static site generator.
	Homepage: https://jekyllrb.com
	Source Code: https://github.com/jekyll/jekyll
	Changelog: https://github.com/jekyll/jekyll/releases
	Bug Tracker: https://github.com/jekyll/jekyll/issues
	Path: /home/jek/gems/gems/jekyll-4.4.1
	Reverse Dependencies: 
		jekyll-archives (2.3.0) depends on jekyll (>= 3.6, < 5.0)
		jekyll-include-cache (0.2.1) depends on jekyll (>= 3.7, < 5.0)
		jekyll-seo-tag (2.8.0) depends on jekyll (>= 3.8, < 5.0)
		jekyll-sitemap (1.4.0) depends on jekyll (>= 3.7, < 5.0)
		jekyll-theme-chirpy (7.4.1) depends on jekyll (~> 4.3)

Création des liens avec les dossiers files, images et _posts pour le générateur de site

1
2
3
ln -s /srv/media/statique/images $HOME/jekyll-theme-chirpy/images
ln -s /srv/media/statique/files $HOME/jekyll-theme-chirpy/files
ln -s /srv/media/statique/_posts $HOME/jekyll-theme-chirpy/_posts

Par défaut jekyll build génère le dossier _site

1
bundle exec jekyll serve --host 127.0.0.1

On utilise pour cela la commande bundle pour que la version de jekyll utilisée ainsi que celle des dépendances soient bien celles décrites dans les fichiers Gemfile et Gemfile.lock et ne dépendent pas de l’environnement de la machine.

Le serveur est lancé

1
2
3
4
5
6
7
8
9
10
Configuration file: /home/jek/jekyll-theme-chirpy/_config.yml
 Theme Config file: /home/jek/jekyll-theme-chirpy/_config.yml
            Source: /home/jek/jekyll-theme-chirpy
       Destination: /home/jek/jekyll-theme-chirpy/_site
 Incremental build: disabled. Enable with --incremental
      Generating... 
                    done in 59.712 seconds.
 Auto-regeneration: enabled for '/home/jek/jekyll-theme-chirpy'
    Server address: http://127.0.0.1:4000/
  Server running... press ctrl-c to stop.

Accès à la page par une redirection, lancer la commande depuis un terminal du réseau

1
ssh -L 9500:localhost:4000 jek@192.168.0.227

🧭 GPX

Tracer des itinéaires à l’aide du moteur de routage BRouter. Visualiser, éditer et créer des traces gpx avec un fork de l’application web https://gpx.studio

BRouter et gpx.studio sont installés sur un serveur debian cwwk rnmkcy.eu 192.168.0.205

BRouter


BRouter est un moteur de routage conçu pour calculer des itinéraires optimaux en utilisant OpenStreetMap et des données d’élévation.
Comme alternative à la version en ligne, le serveur autonome de BRouter peut également être exécuté localement (https://github.com/nrenner/brouter-web, https://github.com/abrensch/brouter).

Prérequis

Installer java non graphique

1
sudo apt install default-jre-headless

Version : java --version

1
2
3
openjdk 21.0.10 2026-01-20
OpenJDK Runtime Environment (build 21.0.10+7-Debian-1deb13u1)
OpenJDK 64-Bit Server VM (build 21.0.10+7-Debian-1deb13u1, mixed mode, sharing)

Procédure installation

Télécharger et décompresser la dernière archive autonome (brouter-web-standalone.<version>.zip) à partir de https://github.com/nrenner/brouter-web/releases, par exemple pour Linux (remplacez ~/opt/ par votre répertoire d’installation préféré et 0.11.0 par la dernière version) :

1
2
3
4
5
6
sudo mkdir -p /opt/gpxweb/brouter
sudo chown $USER:$USER /opt/gpxweb/brouter
cd /opt/gpxweb/brouter
wget https://github.com/nrenner/brouter-web/releases/download/0.18.1/brouter-web-standalone.0.18.1.zip
unzip brouter-web-standalone.0.18.1.zip
rm brouter-web-standalone.0.18.1.zip

Données rd5

Télécharger un ou plusieurs fichiers de données rd5 depuis le download directory ou le grid map dans le répertoire /opt/segments4.

1
2
3
4
5
6
7
wget -P /opt/gpxweb/brouter/segments4 https://brouter.de/brouter/segments4/W5_N45.rd5
wget -P /opt/gpxweb/brouter/segments4 https://brouter.de/brouter/segments4/E0_N50.rd5
wget -P /opt/gpxweb/brouter/segments4 https://brouter.de/brouter/segments4/E0_N45.rd5
wget -P /opt/gpxweb/brouter/segments4 https://brouter.de/brouter/segments4/E5_N45.rd5
wget -P /opt/gpxweb/brouter/segments4 https://brouter.de/brouter/segments4/E5_N40.rd5
wget -P /opt/gpxweb/brouter/segments4 https://brouter.de/brouter/segments4/E0_N40.rd5
wget -P /opt/gpxweb/brouter/segments4 https://brouter.de/brouter/segments4/W5_N40.rd5

Veuillez patienter quelques minutes…

Le script de lancement

Création d’un script /opt/gpxweb/brouter/srv.sh , Port d’écoute 11955

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/sh

BINDADDRESS="localhost"
# BRouter standalone server
# java -cp brouter.jar btools.brouter.RouteServer <segmentdir> <profile-map> <customprofiledir> <port> <maxthreads> [bindaddress]

# maxRunningTime is the request timeout in seconds, set to 0 to disable timeout
JAVA_OPTS="-Xmx128M -Xms128M -Xmn8M -DmaxRunningTime=300"

# If paths are unset, first search in locations matching the directory structure
# as found in the official BRouter zip archive
CLASSPATH=${CLASSPATH:-"/opt/gpxweb/brouter/brouter.jar"}
SEGMENTSPATH=${SEGMENTSPATH:-"/opt/gpxweb/brouter/segments4"}
PROFILESPATH=${PROFILESPATH:-"/opt/gpxweb/brouter/profiles2"}
CUSTOMPROFILESPATH=${CUSTOMPROFILESPATH:-"/opt/gpxweb/brouter/customprofiles"}


java $JAVA_OPTS -cp $CLASSPATH btools.server.RouteServer "$SEGMENTSPATH" "$PROFILESPATH" "$CUSTOMPROFILESPATH" 11955 1 $BINDADDRESS

Le rendre exécutable

1
chmod +x /opt/gpxweb/brouter/srv.sh

Systemd service brouter

Créer un service brouter

1
sudo nano /etc/systemd/system/brouter.service
1
2
3
4
5
6
7
8
9
10
11
[Unit]
Description=brouter server
 
[Service]
Type=exec
User=jek
WorkingDirectory=/opt/gpxweb/brouter
ExecStart=sh /opt/gpxweb/brouter/srv.sh
 
[Install]
WantedBy=multi-user.target

Recharger , activer et lancer le service brouter

1
2
sudo systemctl daemon-reload
sudo systemctl enable brouter --now

Vérifier : systemctl status brouter

1
2
3
4
5
6
7
8
9
10
11
12
13
● brouter.service - brouter server
     Loaded: loaded (/etc/systemd/system/brouter.service; enabled; preset: enabled)
     Active: active (running) since Sat 2026-03-14 10:42:29 CET; 26s ago
 Invocation: 56b3ed40c5064536926e3870f6190576
   Main PID: 6136 (sh)
      Tasks: 19 (limit: 18602)
     Memory: 23.2M (peak: 23.9M)
        CPU: 184ms
     CGroup: /system.slice/brouter.service
             ├─6136 sh /opt/gpxweb/brouter/srv.sh
             └─6137 java -Xmx128M -Xms128M -Xmn8M -DmaxRunningTime=300 -cp /opt/gpxweb/brouter/brouter.jar btools.server.RouteServer>

Mar 14 10:42:29 devel sh[6137]: BRouter 1.6.3 / 21122021

Proxy routeur.rnmkcy.eu

Proxy nginx brouter /etc/nginx/conf.d/routeur.rnmkcy.eu.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
    # ipv4 listening port/protocol
    listen       443 ssl http2;
    # ipv6 listening port/protocol
    listen           [::]:443 ssl http2;
    server_name  routeur.rnmkcy.eu;

    include /etc/nginx/conf.d/security.conf.inc;

  location / { 
      proxy_pass              http://127.0.0.1:11955 ;
  } 

}

Vérification et rechargement nginx

1
2
sudo nginx -t
sudo systemctl reload nginx

gpx.studio


https://github.com/gpxstudio

Cloner gpx.studio dans le dossier courant

1
2
3
4
5
6
# cloner le dernier gpx.studio
git clone https://github.com/gpxstudio/gpx.studio.git
# Déplacer dans le dossier 
sudo mv gpx.studio /opt/gpxweb/
# Aller dans le dossier
cd /opt/gpxweb/

Le code est divisé en deux parties:

  • gpx: une bibliothèque de typescript pour parser et manipuler des fichiers GPX,
  • site web: le site lui-même, qui est une application SvelteKit.

Vous aurez besoin de Node.js pour construire et exécuter ces deux parties.

Construction bibliothèque gpx

Construction bibliothèque gpx

1
2
3
cd gpx.studio/gpx
npm install
npm run build

Construction site web

Pour pouvoir charger la carte, vous devrez créer votre propre Mapbox access token et le stocker dans un fichier .env dans le répertoire website.

1
2
3
cd ../website
echo "pk.eyJ1IjoidmNvcHBlIiwiYSI6ImNseWlrYXo0cjBocW0ya3F5MGtwM3A1b28ifQ.25xwq1HN121RHqM_zkWweQ" > .env
npm install

Modifications des sources

Modifications pour langue ‘fr’ par défaut et utilisation brouter spécifique

url gpx.rnmkcy.eu

1
2
# Remplacer **gpx.studio** par **gpx.rnmkcy.eu**
find src/ -name "*" -type f -exec sed -i "s#gpx.studio#gpx.rnmkcy.eu#g" {} \;

Utilisation avec BRouter

Fichier: src/lib/components/toolbar/tools/routing/routing.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# ligne 33  adresse de routing remplacer 'https://brouter.gpx.rnmkcy.eu' par 'https://routeur.rnmkcy.eu'
# et on supprime '-private'
    let url = `https://routeur.rnmkcy.eu?lonlats=${points.map((point) => `${point.lon.toFixed(8)},${point.lat.toFixed(8)}`).join('|')}&profile=${brouterProfile + (privateRoads ? '' : '')}&format=geojson&alternativeidx=0`;

# supprimer les lignes 10 à 19
# et ajouter ce qui suit
export const brouterProfiles: { [key: string]: string } = {
    bike: 'trekking',
    racing_bike: 'fastbike',
    foot: 'hiking-beta',
    water: 'river',
    railway: 'rail'
};

Supprimer les boutons aide et donate
Fichier src/lib/components/Menu.svelte , supprimer les lignes 510 à 536

1
2
3
4
5
<div class="h-fit flex flex-row items-center ml-1 gap-1">
  <Button
  ...
  </Button>
</div>

Language ‘fr’
Remplacer ‘en’ par ‘fr’

1
2
# Les pages par défaut en fr
find src/ -name "*" -type f -exec sed -i "s#'en'#'fr'#g" {} \;

Construction

Chunks: vite.config.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { sveltekit } from '@sveltejs/kit/vite';
import { enhancedImages } from '@sveltejs/enhanced-img';
import { defineConfig } from 'vite';
import { nodePolyfills } from 'vite-plugin-node-polyfills';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
    ssr: {
        noExternal: ['gpx'],
    },
    plugins: [
        nodePolyfills({
            globals: {
                Buffer: true,
            },
        }),
        enhancedImages(),
        tailwindcss(),
        sveltekit(),
    ],
  build: {
    chunkSizeWarningLimit: 2000,
  },
});

On lance le build

1
npm run build

Test en local

1
npm run preview

Lance le serveur avec une adresse locale

1
2
3
4
5
6
> website@0.0.1 preview
> vite preview

  ➜  Local:   http://localhost:4173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

cwwk - gpx.rnmkcy.eu

Après la construction on copie le dossier build sous ~/opt/gpxweb/gpx.studio.fr

1
2
# les droits
sudo chown www-data:www-data -R $HOME/opt/gpxweb/gpx.studio.fr

Configuration nginx /etc/nginx/conf.d/gpx.rnmkcy.eu.conf

1
2
3
4
5
6
7
8
9
10
11
12
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name gpx.rnmkcy.eu;

    include /etc/nginx/conf.d/security.conf.inc;
    root /opt/gpxweb/gpx.studio.fr/;

    location / {
      index index.html;
    }
}

Vérifier et recharger nginx

1
2
sudo nginx -t
sudo systemctl reload nginx

Accès par le lien https://gpx.rnmkcy.eu

Reconstruction site

Après modification des sources, exécution du script rebuild

Création script /usr/local/bin/rebuild

1
sudo nano /usr/local/bin/rebuild
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash

echo "Départ exécution script"

# Construction
cd $HOME/media/devel/gpx.studio/website
rm -r build/  # si existant
#export NODE_OPTIONS=--max-old-space-size=4096
npm run build

# Mise à jour site nginx
sudo rm -r /var/www/gpx.studio
sudo cp -r $HOME/media/devel/gpx.studio/website/build /var/www/gpx.studio
sudo chown www-data:www-data -R /var/www/gpx.studio
# Recharger nginx
sudo systemctl reload nginx
echo "Fin exécution script"

Droits en exécution

1
sudo chmod +x /usr/local/bin/rebuild

Annexe

gpx.studio mode dev

1
npm run dev

Le serveur est accessible sur le lien http://localhost:5173/, q pour sortir

1
2
3
4
5
6
7
8
9
10
11
12
13
> website@0.0.1 dev
> vite dev

Forced re-optimization of dependencies

  VITE v5.4.8  ready in 1305 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
Browserslist: caniuse-lite is outdated. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme

L’exécution a lieu sur un serveur, utilisation de SSH tunneling, sur un poste ayant un accès SSH, ouvrir un terminal et exécuter la commande suivante

1
ssh -L 9500:localhost:4173 yick@192.168.0.205 -p 55205 -i /home/yann/.ssh/yick-ed25519

Puis ouvrir le lien suivant dans un navigateur : localhost:9500

Cet article est sous licence CC BY 4.0 par l'auteur.