# --- Configuration ---
SOURCE_DIR = "."
DEST_DIR = "dist"
-EXTENSIONS_TO_HASH = [".html", ".js", ".css", ".svg"] #all text files
+EXTENSIONS_TO_HASH = [".html", ".js", ".css", ".svg"] #all edited files
EXTENSIONS_TO_UPDATE = [".html", ".js", ".css"] #.svg don't contain refs
DYNAMIC_LOAD_EXTENSIONS = (".html", ".js", ".css") #loaded from app.js
IGNORE_FILE_UPDATE = {"app.js"}
# Files and folders to totally ignore
IGNORE_FILES = {
- "LICENSE", "README.md", "TODO", "bundle.py", "parameters.js.dist",
- "initialize.sh", "package-lock.json", "package.json", "server.js",
- "start.sh", "stop.sh", ".gitignore", "assets.zip", "extras.zip", ".pid"
+ "LICENSE", "README.md", "TODO", "bundle.py", "js/parameters.js.dist",
+ "initialize.sh", "package-lock.json", "package.json", "js/server.js", ".gitignore"
+ "nginx_config.example", "start.sh", "stop.sh", "assets.zip", "extras.zip", ".pid"
}
IGNORE_DIRS = {".git", "node_modules", DEST_DIR}
# 1. Walk the tree and do selective copies
for root, dirs, files in os.walk(SOURCE_DIR):
# Filter folders to ignore so that walk() doesn't step in
- dirs[:] = [d for d in dirs if d not in IGNORE_DIRS]
+ dirs[:] = [d for d in dirs if os.path.relpath(os.path.join(root, d), SOURCE_DIR) not in IGNORE_DIRS]
for file in files:
- if file in IGNORE_FILES:
- continue
-
ext = os.path.splitext(file)[1]
rel_path = os.path.relpath(os.path.join(root, file), SOURCE_DIR)
+ if rel_path in IGNORE_FILES:
+ continue
- # Determine dest name (with or without hash)
+ # Determine destination name (with or without hash)
if ext in EXTENSIONS_TO_HASH and file != "index.html":
h = get_file_hash(os.path.join(root, file))
new_name = f"{os.path.splitext(file)[0]}.{h}{ext}"
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
- print(f"Build terminé dans /{DEST_DIR}")
- print(f"Fichiers hashés : {len(hash_map)}")
+ print(f"Build completed in {DEST_DIR}.")
+ print(f"{len(hash_map)} hashed files.")
# 3. Write hash_map to manifest file:
hash_manifest = {
--- /dev/null
+#map $sent_http_content_type $expires {
+# default off;
+## image/png off;
+# application/javascript epoch;
+# text/html epoch;
+# text/css epoch;
+#}
+
+#https://www.nginx.com/blog/websocket-nginx/
+map $http_upgrade $connection_upgrade {
+ default upgrade;
+ '' close;
+}
+
+server {
+ listen *:80;
+ listen [::]:80; #ipv6only=off;
+ server_name my.server.com www.my.server.com;
+ return 301 https://my.server.com$request_uri;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl; #http2 ipv6only=off;
+ http2 on;
+ server_name my.server.com;
+
+ # On pointe sur le dossier généré par ton script
+ root /path/to/xogo/dist;
+
+ error_log /var/log/nginx/xogo_error.log;
+ access_log /var/log/nginx/xogo_access.log;
+
+ # 1. Le point d'entrée : TOUJOURS vérifier s'il y a une mise à jour
+ location = /index.html {
+ add_header Cache-Control "no-cache, must-revalidate";
+ expires 0;
+ }
+
+ # 2. Les fichiers statiques hashés (JS, CSS) + Assets
+ # Ils ont un hash dans le nom, donc s'ils changent, l'URL change.
+ # On peut les cacher de façon agressive.
+ location / {
+ try_files $uri $uri/ /index.html;
+ expires 1y;
+ add_header Cache-Control "public, immutable";
+ }
+
+ # 3. WebSocket : Pas de changement ici, c'est parfait
+ location /ws {
+ proxy_pass http://localhost:WS_PORT;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ #proxy_set_header Connection "Upgrade";
+ proxy_set_header Connection $connection_upgrade;
+ proxy_set_header Host $host;
+
+ # Le cache n'a pas de sens pour un tunnel WebSocket
+ proxy_buffering off;
+ }
+
+ ssl_certificate /etc/letsencrypt/live/my.server.com/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/my.server.com/privkey.pem;
+}