mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-01 18:32:13 +00:00
Merge pull request #538 from jcastro/feature/proxmenux-oci-next-10
Add ten OCI application profiles
This commit is contained in:
+32
-1
@@ -8877,5 +8877,36 @@
|
||||
"⚠ Disk data will NOT be erased.": "⚠ Festplattendaten werden NICHT gelöscht.",
|
||||
"⚠ Disk will be unmounted and removed from /etc/fstab.": "⚠ Die Festplatte wird ausgehängt und aus /etc/fstab entfernt.",
|
||||
"⚠ The /etc/fstab entry will be removed.": "⚠ Der /etc/fstab-Eintrag wird entfernt.",
|
||||
"⚠ The disk will be unmounted.": "⚠ Die Festplatte wird ausgehängt."
|
||||
"⚠ The disk will be unmounted.": "⚠ Die Festplatte wird ausgehängt.",
|
||||
"A REST backend for restic backups; it has no web interface.": "Ein REST-Backend für restic-Sicherungen ohne Weboberfläche.",
|
||||
"A lightweight self-hosted URL shortener with SQLite storage.": "Ein schlanker, selbst gehosteter URL-Kürzer mit SQLite-Speicher.",
|
||||
"A personal, self-hosted microblog and timeline.": "Ein persönlicher, selbst gehosteter Microblog mit Chronik.",
|
||||
"A self-hosted app for organizing tabletop role-playing campaigns.": "Eine selbst gehostete App zum Organisieren von Pen-and-Paper-Rollenspielkampagnen.",
|
||||
"A self-hosted tracker for habits, tasks, notes and goals.": "Ein selbst gehosteter Tracker für Gewohnheiten, Aufgaben, Notizen und Ziele.",
|
||||
"Activepieces": "Activepieces",
|
||||
"Build reports and dashboards from your data.": "Erstellen Sie Berichte und Dashboards aus Ihren Daten.",
|
||||
"Build visual automations for personal and hobby use.": "Erstellen Sie visuelle Automatisierungen für private Zwecke und Hobbys.",
|
||||
"Campfire first-run setup": "Ersteinrichtung von Campfire",
|
||||
"Chhoto URL": "Chhoto URL",
|
||||
"Chhoto URL administrator password": "Administratorkennwort für Chhoto URL",
|
||||
"Configured username": "Konfigurierter Benutzername",
|
||||
"Create encrypted, deduplicated backups and restore files.": "Erstellen Sie verschlüsselte, deduplizierte Sicherungen und stellen Sie Dateien wieder her.",
|
||||
"Create with create_user in the container console": "Erstellen Sie den Benutzer mit create_user in der Container-Konsole",
|
||||
"Created during first-run setup": "Wird bei der Ersteinrichtung erstellt",
|
||||
"Ech0": "Ech0",
|
||||
"Email address for the OpenHabitTracker account": "E-Mail-Adresse für das OpenHabitTracker-Konto",
|
||||
"Enter the base URL clients and webhook providers will use to reach this Activepieces instance.": "Geben Sie die Basis-URL ein, über die Clients und Webhook-Anbieter diese Activepieces-Instanz erreichen.",
|
||||
"First Ech0 account (becomes Owner)": "Erstes Ech0-Konto (wird zum Eigentümer)",
|
||||
"First Watcharr account (becomes administrator)": "Erstes Watcharr-Konto (wird zum Administrator)",
|
||||
"Kopia Web UI": "Kopia-Weboberfläche",
|
||||
"Kopia Web UI login": "Anmeldung an der Kopia-Weboberfläche",
|
||||
"Manage database changes, access and workflows.": "Verwalten Sie Datenbankänderungen, Zugriffsrechte und Workflows.",
|
||||
"OpenHabitTracker": "OpenHabitTracker",
|
||||
"OpenHabitTracker account": "OpenHabitTracker-Konto",
|
||||
"OpenHabitTracker initial username": "Erster OpenHabitTracker-Benutzername",
|
||||
"REST API Basic Authentication user": "Benutzer für die HTTP-Basisauthentifizierung der REST-API",
|
||||
"Repository encryption password": "Kennwort zur Verschlüsselung des Repositorys",
|
||||
"Set to 1 only for a private HTTP-only LAN; use HTTPS otherwise.": "Setzen Sie den Wert nur in einem privaten LAN mit ausschließlich HTTP auf 1; andernfalls verwenden Sie HTTPS.",
|
||||
"Track movies, television, anime and games you want to enjoy.": "Behalten Sie Filme, Serien, Anime und Spiele im Blick, die Sie ansehen oder spielen möchten.",
|
||||
"Watcharr": "Watcharr"
|
||||
}
|
||||
|
||||
+32
-1
@@ -8849,5 +8849,36 @@
|
||||
"⚠ Disk data will NOT be erased.": "⚠ Los datos del disco NO se borrarán.",
|
||||
"⚠ Disk will be unmounted and removed from /etc/fstab.": "⚠ El disco se desmontará y se eliminará de /etc/fstab.",
|
||||
"⚠ The /etc/fstab entry will be removed.": "⚠ Se eliminará la entrada /etc/fstab.",
|
||||
"⚠ The disk will be unmounted.": "⚠ El disco se desmontará."
|
||||
"⚠ The disk will be unmounted.": "⚠ El disco se desmontará.",
|
||||
"A REST backend for restic backups; it has no web interface.": "Backend REST para copias de seguridad de restic, sin interfaz web.",
|
||||
"A lightweight self-hosted URL shortener with SQLite storage.": "Acortador de URL ligero y autoalojado con almacenamiento SQLite.",
|
||||
"A personal, self-hosted microblog and timeline.": "Microblog y cronología personales, autoalojados.",
|
||||
"A self-hosted app for organizing tabletop role-playing campaigns.": "Aplicación autoalojada para organizar campañas de juegos de rol de mesa.",
|
||||
"A self-hosted tracker for habits, tasks, notes and goals.": "Registro autoalojado de hábitos, tareas, notas y objetivos.",
|
||||
"Activepieces": "Activepieces",
|
||||
"Build reports and dashboards from your data.": "Crea informes y paneles a partir de tus datos.",
|
||||
"Build visual automations for personal and hobby use.": "Crea automatizaciones visuales para uso personal o aficiones.",
|
||||
"Campfire first-run setup": "Configuración inicial de Campfire",
|
||||
"Chhoto URL": "Chhoto URL",
|
||||
"Chhoto URL administrator password": "Contraseña de administrador de Chhoto URL",
|
||||
"Configured username": "Nombre de usuario configurado",
|
||||
"Create encrypted, deduplicated backups and restore files.": "Crea copias de seguridad cifradas y deduplicadas y restaura archivos.",
|
||||
"Create with create_user in the container console": "Crea el usuario con create_user desde la consola del contenedor",
|
||||
"Created during first-run setup": "Se crea durante la configuración inicial",
|
||||
"Ech0": "Ech0",
|
||||
"Email address for the OpenHabitTracker account": "Correo electrónico de la cuenta de OpenHabitTracker",
|
||||
"Enter the base URL clients and webhook providers will use to reach this Activepieces instance.": "Introduce la URL base que usarán los clientes y proveedores de webhooks para acceder a esta instancia de Activepieces.",
|
||||
"First Ech0 account (becomes Owner)": "Primera cuenta de Ech0 (será la propietaria)",
|
||||
"First Watcharr account (becomes administrator)": "Primera cuenta de Watcharr (será la administradora)",
|
||||
"Kopia Web UI": "Interfaz web de Kopia",
|
||||
"Kopia Web UI login": "Acceso a la interfaz web de Kopia",
|
||||
"Manage database changes, access and workflows.": "Gestiona cambios en bases de datos, accesos y flujos de trabajo.",
|
||||
"OpenHabitTracker": "OpenHabitTracker",
|
||||
"OpenHabitTracker account": "Cuenta de OpenHabitTracker",
|
||||
"OpenHabitTracker initial username": "Nombre de usuario inicial de OpenHabitTracker",
|
||||
"REST API Basic Authentication user": "Usuario de autenticación básica para la API REST",
|
||||
"Repository encryption password": "Contraseña de cifrado del repositorio",
|
||||
"Set to 1 only for a private HTTP-only LAN; use HTTPS otherwise.": "Establécelo en 1 solo en una LAN privada que utilice exclusivamente HTTP; en los demás casos, usa HTTPS.",
|
||||
"Track movies, television, anime and games you want to enjoy.": "Lleva un registro de películas, series, anime y videojuegos que quieras disfrutar.",
|
||||
"Watcharr": "Watcharr"
|
||||
}
|
||||
|
||||
+32
-1
@@ -8876,5 +8876,36 @@
|
||||
"⚠ Disk data will NOT be erased.": "⚠ Les données du disque ne seront PAS effacées.",
|
||||
"⚠ Disk will be unmounted and removed from /etc/fstab.": "⚠ Le disque sera démonté et supprimé de /etc/fstab.",
|
||||
"⚠ The /etc/fstab entry will be removed.": "⚠ L'entrée /etc/fstab sera supprimée.",
|
||||
"⚠ The disk will be unmounted.": "⚠ Le disque sera démonté."
|
||||
"⚠ The disk will be unmounted.": "⚠ Le disque sera démonté.",
|
||||
"A REST backend for restic backups; it has no web interface.": "Un backend REST pour les sauvegardes restic, sans interface web.",
|
||||
"A lightweight self-hosted URL shortener with SQLite storage.": "Un raccourcisseur d’URL léger et auto-hébergé avec stockage SQLite.",
|
||||
"A personal, self-hosted microblog and timeline.": "Un microblog et un fil d’actualité personnels, auto-hébergés.",
|
||||
"A self-hosted app for organizing tabletop role-playing campaigns.": "Une application auto-hébergée pour organiser des campagnes de jeux de rôle sur table.",
|
||||
"A self-hosted tracker for habits, tasks, notes and goals.": "Un outil auto-hébergé pour suivre les habitudes, tâches, notes et objectifs.",
|
||||
"Activepieces": "Activepieces",
|
||||
"Build reports and dashboards from your data.": "Créez des rapports et des tableaux de bord à partir de vos données.",
|
||||
"Build visual automations for personal and hobby use.": "Créez des automatisations visuelles pour un usage personnel ou vos loisirs.",
|
||||
"Campfire first-run setup": "Configuration initiale de Campfire",
|
||||
"Chhoto URL": "Chhoto URL",
|
||||
"Chhoto URL administrator password": "Mot de passe administrateur de Chhoto URL",
|
||||
"Configured username": "Nom d’utilisateur configuré",
|
||||
"Create encrypted, deduplicated backups and restore files.": "Créez des sauvegardes chiffrées et dédupliquées, puis restaurez vos fichiers.",
|
||||
"Create with create_user in the container console": "Créez l’utilisateur avec create_user dans la console du conteneur",
|
||||
"Created during first-run setup": "Créé lors de la configuration initiale",
|
||||
"Ech0": "Ech0",
|
||||
"Email address for the OpenHabitTracker account": "Adresse e-mail du compte OpenHabitTracker",
|
||||
"Enter the base URL clients and webhook providers will use to reach this Activepieces instance.": "Saisissez l’URL de base que les clients et fournisseurs de webhooks utiliseront pour accéder à cette instance d’Activepieces.",
|
||||
"First Ech0 account (becomes Owner)": "Premier compte Ech0 (il devient propriétaire)",
|
||||
"First Watcharr account (becomes administrator)": "Premier compte Watcharr (il devient administrateur)",
|
||||
"Kopia Web UI": "Interface web de Kopia",
|
||||
"Kopia Web UI login": "Connexion à l’interface web de Kopia",
|
||||
"Manage database changes, access and workflows.": "Gérez les modifications de base de données, les accès et les flux de travail.",
|
||||
"OpenHabitTracker": "OpenHabitTracker",
|
||||
"OpenHabitTracker account": "Compte OpenHabitTracker",
|
||||
"OpenHabitTracker initial username": "Nom d’utilisateur initial d’OpenHabitTracker",
|
||||
"REST API Basic Authentication user": "Utilisateur de l’authentification HTTP Basic de l’API REST",
|
||||
"Repository encryption password": "Mot de passe de chiffrement du dépôt",
|
||||
"Set to 1 only for a private HTTP-only LAN; use HTTPS otherwise.": "Définissez la valeur sur 1 uniquement pour un réseau local privé utilisant exclusivement HTTP ; sinon, utilisez HTTPS.",
|
||||
"Track movies, television, anime and games you want to enjoy.": "Suivez les films, séries, animés et jeux vidéo que vous souhaitez découvrir.",
|
||||
"Watcharr": "Watcharr"
|
||||
}
|
||||
|
||||
+32
-1
@@ -8877,5 +8877,36 @@
|
||||
"⚠ Disk data will NOT be erased.": "⚠ I dati del disco NON verranno cancellati.",
|
||||
"⚠ Disk will be unmounted and removed from /etc/fstab.": "⚠ Il disco verrà smontato e rimosso da /etc/fstab.",
|
||||
"⚠ The /etc/fstab entry will be removed.": "⚠ La voce /etc/fstab verrà rimossa.",
|
||||
"⚠ The disk will be unmounted.": "⚠ Il disco verrà smontato."
|
||||
"⚠ The disk will be unmounted.": "⚠ Il disco verrà smontato.",
|
||||
"A REST backend for restic backups; it has no web interface.": "Un backend REST per i backup di restic, senza interfaccia web.",
|
||||
"A lightweight self-hosted URL shortener with SQLite storage.": "Un accorciatore di URL leggero e self-hosted con archivio SQLite.",
|
||||
"A personal, self-hosted microblog and timeline.": "Un microblog e una cronologia personali, self-hosted.",
|
||||
"A self-hosted app for organizing tabletop role-playing campaigns.": "Un’app self-hosted per organizzare campagne di giochi di ruolo da tavolo.",
|
||||
"A self-hosted tracker for habits, tasks, notes and goals.": "Un tracker self-hosted per abitudini, attività, note e obiettivi.",
|
||||
"Activepieces": "Activepieces",
|
||||
"Build reports and dashboards from your data.": "Crea report e dashboard a partire dai tuoi dati.",
|
||||
"Build visual automations for personal and hobby use.": "Crea automazioni visive per uso personale e per i tuoi hobby.",
|
||||
"Campfire first-run setup": "Configurazione iniziale di Campfire",
|
||||
"Chhoto URL": "Chhoto URL",
|
||||
"Chhoto URL administrator password": "Password amministratore di Chhoto URL",
|
||||
"Configured username": "Nome utente configurato",
|
||||
"Create encrypted, deduplicated backups and restore files.": "Crea backup cifrati e deduplicati e ripristina i file.",
|
||||
"Create with create_user in the container console": "Crea l’utente con create_user nella console del container",
|
||||
"Created during first-run setup": "Creato durante la configurazione iniziale",
|
||||
"Ech0": "Ech0",
|
||||
"Email address for the OpenHabitTracker account": "Indirizzo e-mail dell’account OpenHabitTracker",
|
||||
"Enter the base URL clients and webhook providers will use to reach this Activepieces instance.": "Inserisci l’URL di base che client e provider webhook useranno per raggiungere questa istanza di Activepieces.",
|
||||
"First Ech0 account (becomes Owner)": "Primo account Ech0 (diventa proprietario)",
|
||||
"First Watcharr account (becomes administrator)": "Primo account Watcharr (diventa amministratore)",
|
||||
"Kopia Web UI": "Interfaccia web di Kopia",
|
||||
"Kopia Web UI login": "Accesso all’interfaccia web di Kopia",
|
||||
"Manage database changes, access and workflows.": "Gestisci le modifiche al database, gli accessi e i flussi di lavoro.",
|
||||
"OpenHabitTracker": "OpenHabitTracker",
|
||||
"OpenHabitTracker account": "Account OpenHabitTracker",
|
||||
"OpenHabitTracker initial username": "Nome utente iniziale di OpenHabitTracker",
|
||||
"REST API Basic Authentication user": "Utente per l’autenticazione di base dell’API REST",
|
||||
"Repository encryption password": "Password di cifratura del repository",
|
||||
"Set to 1 only for a private HTTP-only LAN; use HTTPS otherwise.": "Imposta il valore su 1 solo per una LAN privata che usa esclusivamente HTTP; altrimenti usa HTTPS.",
|
||||
"Track movies, television, anime and games you want to enjoy.": "Tieni traccia di film, serie TV, anime e videogiochi che vuoi guardare o provare.",
|
||||
"Watcharr": "Watcharr"
|
||||
}
|
||||
|
||||
+32
-1
@@ -8877,5 +8877,36 @@
|
||||
"⚠ Disk data will NOT be erased.": "⚠ Os dados do disco NÃO serão apagados.",
|
||||
"⚠ Disk will be unmounted and removed from /etc/fstab.": "⚠ O disco será desmontado e removido de /etc/fstab.",
|
||||
"⚠ The /etc/fstab entry will be removed.": "⚠ A entrada /etc/fstab será removida.",
|
||||
"⚠ The disk will be unmounted.": "⚠ O disco será desmontado."
|
||||
"⚠ The disk will be unmounted.": "⚠ O disco será desmontado.",
|
||||
"A REST backend for restic backups; it has no web interface.": "Um backend REST para cópias de segurança do restic, sem interface web.",
|
||||
"A lightweight self-hosted URL shortener with SQLite storage.": "Um encurtador de URLs leve e autoalojado, com armazenamento SQLite.",
|
||||
"A personal, self-hosted microblog and timeline.": "Um microblog e uma cronologia pessoais, autoalojados.",
|
||||
"A self-hosted app for organizing tabletop role-playing campaigns.": "Uma aplicação autoalojada para organizar campanhas de jogos de interpretação de mesa.",
|
||||
"A self-hosted tracker for habits, tasks, notes and goals.": "Um gestor autoalojado de hábitos, tarefas, notas e objetivos.",
|
||||
"Activepieces": "Activepieces",
|
||||
"Build reports and dashboards from your data.": "Crie relatórios e painéis com os seus dados.",
|
||||
"Build visual automations for personal and hobby use.": "Crie automações visuais para uso pessoal e passatempos.",
|
||||
"Campfire first-run setup": "Configuração inicial do Campfire",
|
||||
"Chhoto URL": "Chhoto URL",
|
||||
"Chhoto URL administrator password": "Palavra-passe de administrador do Chhoto URL",
|
||||
"Configured username": "Nome de utilizador configurado",
|
||||
"Create encrypted, deduplicated backups and restore files.": "Crie cópias de segurança cifradas e deduplicadas e restaure ficheiros.",
|
||||
"Create with create_user in the container console": "Crie o utilizador com create_user na consola do contentor",
|
||||
"Created during first-run setup": "Criado durante a configuração inicial",
|
||||
"Ech0": "Ech0",
|
||||
"Email address for the OpenHabitTracker account": "Endereço de e-mail da conta OpenHabitTracker",
|
||||
"Enter the base URL clients and webhook providers will use to reach this Activepieces instance.": "Introduza o URL base que os clientes e fornecedores de webhooks utilizarão para aceder a esta instância do Activepieces.",
|
||||
"First Ech0 account (becomes Owner)": "Primeira conta Ech0 (passa a ser proprietária)",
|
||||
"First Watcharr account (becomes administrator)": "Primeira conta Watcharr (passa a ser administradora)",
|
||||
"Kopia Web UI": "Interface web do Kopia",
|
||||
"Kopia Web UI login": "Acesso à interface web do Kopia",
|
||||
"Manage database changes, access and workflows.": "Gira alterações à base de dados, acessos e fluxos de trabalho.",
|
||||
"OpenHabitTracker": "OpenHabitTracker",
|
||||
"OpenHabitTracker account": "Conta OpenHabitTracker",
|
||||
"OpenHabitTracker initial username": "Nome de utilizador inicial do OpenHabitTracker",
|
||||
"REST API Basic Authentication user": "Utilizador da autenticação básica da API REST",
|
||||
"Repository encryption password": "Palavra-passe de encriptação do repositório",
|
||||
"Set to 1 only for a private HTTP-only LAN; use HTTPS otherwise.": "Defina como 1 apenas numa LAN privada que utilize exclusivamente HTTP; caso contrário, utilize HTTPS.",
|
||||
"Track movies, television, anime and games you want to enjoy.": "Acompanhe os filmes, séries, anime e videojogos que quer ver ou jogar.",
|
||||
"Watcharr": "Watcharr"
|
||||
}
|
||||
|
||||
+32
-1
@@ -8878,5 +8878,36 @@
|
||||
"⚠ Disk data will NOT be erased.": "⚠ Dáta na disku sa NEVYMAŽÚ.",
|
||||
"⚠ Disk will be unmounted and removed from /etc/fstab.": "⚠ Disk sa odpojí a odstráni z /etc/fstab.",
|
||||
"⚠ The /etc/fstab entry will be removed.": "⚠ Záznam v /etc/fstab bude odstránený.",
|
||||
"⚠ The disk will be unmounted.": "⚠ Disk bude odpojený."
|
||||
"⚠ The disk will be unmounted.": "⚠ Disk bude odpojený.",
|
||||
"A REST backend for restic backups; it has no web interface.": "REST backend na zálohy restic bez webového rozhrania.",
|
||||
"A lightweight self-hosted URL shortener with SQLite storage.": "Odľahčovač URL adries s vlastným hostingom a úložiskom SQLite.",
|
||||
"A personal, self-hosted microblog and timeline.": "Osobný mikroblog a časová os s vlastným hostingom.",
|
||||
"A self-hosted app for organizing tabletop role-playing campaigns.": "Aplikácia s vlastným hostingom na organizovanie kampaní stolových hier na hrdinov.",
|
||||
"A self-hosted tracker for habits, tasks, notes and goals.": "Sledovanie návykov, úloh, poznámok a cieľov s vlastným hostingom.",
|
||||
"Activepieces": "Activepieces",
|
||||
"Build reports and dashboards from your data.": "Vytvárajte prehľady a dashboardy zo svojich údajov.",
|
||||
"Build visual automations for personal and hobby use.": "Vytvárajte vizuálne automatizácie na osobné použitie a koníčky.",
|
||||
"Campfire first-run setup": "Prvotné nastavenie Campfire",
|
||||
"Chhoto URL": "Chhoto URL",
|
||||
"Chhoto URL administrator password": "Heslo správcu pre Chhoto URL",
|
||||
"Configured username": "Nastavené používateľské meno",
|
||||
"Create encrypted, deduplicated backups and restore files.": "Vytvárajte šifrované, deduplikované zálohy a obnovujte súbory.",
|
||||
"Create with create_user in the container console": "Používateľa vytvorte príkazom create_user v konzole kontajnera",
|
||||
"Created during first-run setup": "Vytvorí sa počas prvotného nastavenia",
|
||||
"Ech0": "Ech0",
|
||||
"Email address for the OpenHabitTracker account": "E-mailová adresa účtu OpenHabitTracker",
|
||||
"Enter the base URL clients and webhook providers will use to reach this Activepieces instance.": "Zadajte základnú adresu URL, ktorú klienti a poskytovatelia webhookov použijú na prístup k tejto inštancii Activepieces.",
|
||||
"First Ech0 account (becomes Owner)": "Prvý účet Ech0 (stane sa vlastníkom)",
|
||||
"First Watcharr account (becomes administrator)": "Prvý účet Watcharr (stane sa správcom)",
|
||||
"Kopia Web UI": "Webové rozhranie Kopia",
|
||||
"Kopia Web UI login": "Prihlásenie do webového rozhrania Kopia",
|
||||
"Manage database changes, access and workflows.": "Spravujte zmeny v databáze, prístupy a pracovné postupy.",
|
||||
"OpenHabitTracker": "OpenHabitTracker",
|
||||
"OpenHabitTracker account": "Účet OpenHabitTracker",
|
||||
"OpenHabitTracker initial username": "Počiatočné používateľské meno OpenHabitTracker",
|
||||
"REST API Basic Authentication user": "Používateľ základného overenia REST API",
|
||||
"Repository encryption password": "Heslo na šifrovanie úložiska",
|
||||
"Set to 1 only for a private HTTP-only LAN; use HTTPS otherwise.": "Nastavte na 1 iba v súkromnej LAN používajúcej výhradne HTTP; inak použite HTTPS.",
|
||||
"Track movies, television, anime and games you want to enjoy.": "Sledujte filmy, seriály, anime a hry, ktoré si chcete pozrieť alebo zahrať.",
|
||||
"Watcharr": "Watcharr"
|
||||
}
|
||||
|
||||
+32
-1
@@ -8877,5 +8877,36 @@
|
||||
"⚠ Disk data will NOT be erased.": "⚠ Diskdata kommer INTE att raderas.",
|
||||
"⚠ Disk will be unmounted and removed from /etc/fstab.": "⚠ Disken kommer att avmonteras och tas bort från /etc/fstab.",
|
||||
"⚠ The /etc/fstab entry will be removed.": "⚠ /etc/fstab-posten kommer att tas bort.",
|
||||
"⚠ The disk will be unmounted.": "⚠ Disken kommer att avmonteras."
|
||||
"⚠ The disk will be unmounted.": "⚠ Disken kommer att avmonteras.",
|
||||
"A REST backend for restic backups; it has no web interface.": "En REST-backend för restic-säkerhetskopior utan webbgränssnitt.",
|
||||
"A lightweight self-hosted URL shortener with SQLite storage.": "En lättviktig, egenhostad URL-förkortare med SQLite-lagring.",
|
||||
"A personal, self-hosted microblog and timeline.": "En personlig, egenhostad mikroblogg och tidslinje.",
|
||||
"A self-hosted app for organizing tabletop role-playing campaigns.": "En egenhostad app för att organisera kampanjer för bordsrollspel.",
|
||||
"A self-hosted tracker for habits, tasks, notes and goals.": "En egenhostad spårare för vanor, uppgifter, anteckningar och mål.",
|
||||
"Activepieces": "Activepieces",
|
||||
"Build reports and dashboards from your data.": "Skapa rapporter och instrumentpaneler från dina data.",
|
||||
"Build visual automations for personal and hobby use.": "Skapa visuella automatiseringar för personligt bruk och hobbyprojekt.",
|
||||
"Campfire first-run setup": "Första konfigurationen av Campfire",
|
||||
"Chhoto URL": "Chhoto URL",
|
||||
"Chhoto URL administrator password": "Administratörslösenord för Chhoto URL",
|
||||
"Configured username": "Konfigurerat användarnamn",
|
||||
"Create encrypted, deduplicated backups and restore files.": "Skapa krypterade, deduplicerade säkerhetskopior och återställ filer.",
|
||||
"Create with create_user in the container console": "Skapa användaren med create_user i containerns konsol",
|
||||
"Created during first-run setup": "Skapas under den första konfigurationen",
|
||||
"Ech0": "Ech0",
|
||||
"Email address for the OpenHabitTracker account": "E-postadress för OpenHabitTracker-kontot",
|
||||
"Enter the base URL clients and webhook providers will use to reach this Activepieces instance.": "Ange bas-URL:en som klienter och webhook-leverantörer ska använda för att nå den här Activepieces-instansen.",
|
||||
"First Ech0 account (becomes Owner)": "Första Ech0-kontot (blir ägare)",
|
||||
"First Watcharr account (becomes administrator)": "Första Watcharr-kontot (blir administratör)",
|
||||
"Kopia Web UI": "Kopia-webbgränssnitt",
|
||||
"Kopia Web UI login": "Inloggning till Kopias webbgränssnitt",
|
||||
"Manage database changes, access and workflows.": "Hantera databasändringar, åtkomst och arbetsflöden.",
|
||||
"OpenHabitTracker": "OpenHabitTracker",
|
||||
"OpenHabitTracker account": "OpenHabitTracker-konto",
|
||||
"OpenHabitTracker initial username": "Första användarnamnet för OpenHabitTracker",
|
||||
"REST API Basic Authentication user": "Användare för REST API:s grundläggande autentisering",
|
||||
"Repository encryption password": "Lösenord för kryptering av arkivet",
|
||||
"Set to 1 only for a private HTTP-only LAN; use HTTPS otherwise.": "Ange 1 endast för ett privat nätverk som enbart använder HTTP; använd annars HTTPS.",
|
||||
"Track movies, television, anime and games you want to enjoy.": "Håll koll på filmer, tv-serier, anime och spel som du vill se eller spela.",
|
||||
"Watcharr": "Watcharr"
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
<!-- Generated from oci/catalog/verification.json by .github/scripts/oci_validation.py. Do not edit by hand. -->
|
||||
|
||||
43 of 515 applications in the OCI catalog have been tested for real: 41 in the ProxMenux lab and 2 by the community. The OCI installer shows them as verified, with a ✓ in the lists.
|
||||
43 of 525 applications in the OCI catalog have been tested for real: 41 in the ProxMenux lab and 2 by the community. The OCI installer shows them as verified, with a ✓ in the lists.
|
||||
|
||||
Each test describes the scenario that was run and names the image it ran on. It does not cover every possible configuration of the application, and a newer image has not been tested until someone reports it.
|
||||
|
||||
|
||||
@@ -0,0 +1,524 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-activepieces",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Activepieces",
|
||||
"es_ES": "Activepieces"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "Build visual automations for personal and hobby use.",
|
||||
"es_ES": "Crea automatizaciones visuales para uso personal."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Build and run automation flows from a self-hosted visual interface. This single-container profile uses Activepieces’ documented personal mode with embedded storage and an in-memory queue.",
|
||||
"es_ES": "Diseña y ejecuta flujos de automatización desde una interfaz visual autoalojada. Este perfil de un solo contenedor usa el modo personal documentado de Activepieces, con almacenamiento integrado y cola en memoria."
|
||||
},
|
||||
"category": "automation",
|
||||
"category_label": "Automation & Scheduling",
|
||||
"author": "Activepieces",
|
||||
"developer": "Activepieces",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/activepieces.webp",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 80,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://www.activepieces.com/",
|
||||
"documentation": "https://www.activepieces.com/docs/install/options/docker",
|
||||
"repository": "https://github.com/activepieces/activepieces",
|
||||
"tips": [
|
||||
"The first account you create becomes the administrator; Activepieces has no default username or password.",
|
||||
"Use the base URL entered during setup. Webhooks and app triggers need it to be reachable by third parties.",
|
||||
"This single-container mode uses embedded PGLite and an in-memory queue for personal use on one machine. It is not the production or multi-instance setup."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "activepieces",
|
||||
"repository": "https://github.com/activepieces/activepieces",
|
||||
"revision": "bc26934b0a08842ec4fd24d83ecd08907cbaec1e4d7a985d30138e4f67ea6855",
|
||||
"image_repository_url": "https://github.com/activepieces/activepieces/pkgs/container/activepieces",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "bc26934b0a08842ec4fd24d83ecd08907cbaec1e4d7a985d30138e4f67ea6855",
|
||||
"generated_at": "2026-10-26T10:22:17+00:00",
|
||||
"readme_raw_url": "https://raw.githubusercontent.com/activepieces/activepieces/main/README.md"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "activepieces",
|
||||
"container_name": "activepieces",
|
||||
"image": {
|
||||
"reference": "ghcr.io/activepieces/activepieces:latest",
|
||||
"registry": "ghcr.io",
|
||||
"repository": "ghcr.io/activepieces/activepieces",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "AP_DB_TYPE",
|
||||
"example": "PGLITE",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"name": "AP_REDIS_TYPE",
|
||||
"example": "MEMORY",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"name": "AP_FRONTEND_URL",
|
||||
"example": "",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt_user": true,
|
||||
"prompt": "Enter the base URL clients and webhook providers will use to reach this Activepieces instance."
|
||||
},
|
||||
{
|
||||
"name": "AP_ENCRYPTION_KEY",
|
||||
"example": "${GENERATED_AP_ENCRYPTION_KEY}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"name": "AP_JWT_SECRET",
|
||||
"example": "${GENERATED_AP_JWT_SECRET}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/root/.activepieces",
|
||||
"compose_source_example": "./activepieces-data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 80,
|
||||
"published_example": 80,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "name: activepieces\nservices:\n activepieces:\n environment:\n AP_DB_TYPE: PGLITE\n AP_ENCRYPTION_KEY: ${GENERATED_GENERATED_AP_ENCRYPTION_KEY}\n AP_FRONTEND_URL: ''\n AP_JWT_SECRET: ${GENERATED_GENERATED_AP_JWT_SECRET}\n AP_REDIS_TYPE: MEMORY\n image: ghcr.io/activepieces/activepieces:latest\n ports:\n - 80:80\n volumes:\n - ./.activepieces:/root/.activepieces\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "activepieces",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "activepieces",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "activepieces",
|
||||
"image": "ghcr.io/activepieces/activepieces:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"environment": {
|
||||
"AP_DB_TYPE": "PGLITE",
|
||||
"AP_ENCRYPTION_KEY": "${GENERATED_GENERATED_AP_ENCRYPTION_KEY}",
|
||||
"AP_FRONTEND_URL": "",
|
||||
"AP_JWT_SECRET": "${GENERATED_GENERATED_AP_JWT_SECRET}",
|
||||
"AP_REDIS_TYPE": "MEMORY"
|
||||
},
|
||||
"image": "ghcr.io/activepieces/activepieces:latest",
|
||||
"ports": [
|
||||
"80:80"
|
||||
],
|
||||
"volumes": [
|
||||
"./.activepieces:/root/.activepieces"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "activepieces"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "activepieces-volume-0",
|
||||
"service": "activepieces",
|
||||
"container_path": "/root/.activepieces",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": false,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"activepieces"
|
||||
],
|
||||
"stop_order": [
|
||||
"activepieces"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "generated-ap-encryption-key",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "activepieces",
|
||||
"environment_variable": "AP_ENCRYPTION_KEY"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "generated-ap-jwt-secret",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "activepieces",
|
||||
"environment_variable": "AP_JWT_SECRET"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Activepieces",
|
||||
"scheme": "http",
|
||||
"port": 80,
|
||||
"path": "/",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": []
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 2048,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/root/.activepieces",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-application-user",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"generated_sensitive_environment": {
|
||||
"AP_ENCRYPTION_KEY": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 16
|
||||
},
|
||||
"AP_JWT_SECRET": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 32
|
||||
}
|
||||
},
|
||||
"minimum_secret_length": {
|
||||
"AP_ENCRYPTION_KEY": 32,
|
||||
"AP_JWT_SECRET": 32
|
||||
},
|
||||
"volume_owner": {
|
||||
"uid": 0,
|
||||
"gid": 0
|
||||
},
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 80,
|
||||
"path": "/api/v1/health",
|
||||
"timeout_seconds": 300,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 5,
|
||||
"verify_tls": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,445 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-bytebase",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Bytebase",
|
||||
"es_ES": "Bytebase"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "Manage database changes, access and workflows.",
|
||||
"es_ES": "Administra cambios, accesos y flujos de trabajo de bases de datos."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Manage database changes, access and workflows through a browser-based workspace. The image contains its own database, so this profile does not require a second service.",
|
||||
"es_ES": "Gestiona cambios, accesos y flujos de bases de datos desde un espacio de trabajo web. La imagen incluye su propia base de datos, por lo que este perfil no necesita otro servicio."
|
||||
},
|
||||
"category": "databases",
|
||||
"category_label": "Databases",
|
||||
"author": "Bytebase",
|
||||
"developer": "Bytebase",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/bytebase/bytebase@main/frontend/src/assets/logo-icon.svg",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://www.bytebase.com/",
|
||||
"documentation": "https://docs.bytebase.com/get-started/self-host/deploy-with-docker",
|
||||
"repository": "https://github.com/bytebase/bytebase",
|
||||
"tips": [
|
||||
"On first visit, complete the web setup wizard to create the initial administrator and workspace; the image has no default login credentials.",
|
||||
"To use Bytebase for database changes, connect the database instances you want to manage from its web interface.",
|
||||
"En la primera visita, completa el asistente web para crear el administrador y el espacio de trabajo inicial; la imagen no tiene credenciales de acceso predeterminadas.",
|
||||
"Para gestionar cambios de bases de datos, conecta desde la interfaz las instancias que quieras administrar."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "Bytebase",
|
||||
"repository": "https://github.com/bytebase/bytebase",
|
||||
"revision": "e77473a25aa12a669dc15bc33d37c276d7478b47",
|
||||
"image_repository_url": "https://hub.docker.com/r/bytebase/bytebase",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "b3756c0ae20c2a82b17f7cd04f116c4aef1b4a49d6ccf651bd865d74ab865e22",
|
||||
"generated_at": "2026-10-26T09:44:16+00:00",
|
||||
"readme_raw_url": "https://github.com/bytebase/bytebase",
|
||||
"default_branch": "main"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "bytebase",
|
||||
"container_name": "bytebase",
|
||||
"image": {
|
||||
"reference": "bytebase/bytebase:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "bytebase/bytebase",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-selected-tag-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/var/opt/bytebase",
|
||||
"compose_source_example": "bytebase-data-0",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 16
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 8080,
|
||||
"published_example": 8080,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "{\n \"name\": \"bytebase\",\n \"services\": {\n \"bytebase\": {\n \"image\": \"bytebase/bytebase:latest\",\n \"restart\": \"unless-stopped\",\n \"command\": [\n \"--port\",\n \"8080\",\n \"--data\",\n \"/var/opt/bytebase\"\n ],\n \"ports\": [\n \"8080:8080/tcp\"\n ],\n \"volumes\": [\n \"bytebase-data-0:/var/opt/bytebase\"\n ]\n }\n },\n \"volumes\": {\n \"bytebase-data-0\": {}\n }\n}"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "bytebase",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "bytebase",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "bytebase",
|
||||
"image": "bytebase/bytebase:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "bytebase/bytebase:latest",
|
||||
"restart": "unless-stopped",
|
||||
"command": [
|
||||
"--port",
|
||||
"8080",
|
||||
"--data",
|
||||
"/var/opt/bytebase"
|
||||
],
|
||||
"ports": [
|
||||
"8080:8080/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"bytebase-data-0:/var/opt/bytebase"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "bytebase",
|
||||
"volumes": {
|
||||
"bytebase-data-0": {}
|
||||
}
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "bytebase-volume-0",
|
||||
"service": "bytebase",
|
||||
"container_path": "/var/opt/bytebase",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": false,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"bytebase"
|
||||
],
|
||||
"stop_order": [
|
||||
"bytebase"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": []
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Web UI",
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": []
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 2048,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 60
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/healthz",
|
||||
"timeout_seconds": 180,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false
|
||||
},
|
||||
"generated_sensitive_environment": {}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "pending",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,457 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-campfire",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Campfire",
|
||||
"es_ES": "Campfire"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "A self-hosted app for organizing tabletop role-playing campaigns.",
|
||||
"es_ES": "Aplicación autoalojada para organizar partidas de rol de mesa."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "A self-hosted web application for organizing tabletop role-playing games.",
|
||||
"es_ES": "Una aplicación web autoalojada para organizar campañas y sesiones de juegos de rol."
|
||||
},
|
||||
"category": "gaming",
|
||||
"category_label": "Gaming & Leisure",
|
||||
"author": "AwsomeFox",
|
||||
"developer": "AwsomeFox",
|
||||
"icon": "https://raw.githubusercontent.com/AwsomeFox/campfire/main/apps/web/public/pwa-512x512.png",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/auth/setup"
|
||||
},
|
||||
"website": "https://github.com/AwsomeFox/campfire",
|
||||
"documentation": "https://github.com/AwsomeFox/campfire#readme",
|
||||
"repository": "https://github.com/AwsomeFox/campfire",
|
||||
"tips": [
|
||||
"Create the first account at /auth/setup after startup.",
|
||||
"For direct access over plain HTTP on a trusted LAN, set ALLOW_INSECURE_HTTP=1 in advanced settings. Leave it unset when using HTTPS."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "AwsomeFox",
|
||||
"repository": "https://github.com/AwsomeFox/campfire",
|
||||
"revision": "f0dd871f5d2ab0b949db8c8a15a90ec56d40d3dc",
|
||||
"image_repository_url": "https://github.com/AwsomeFox/campfire/pkgs/container/campfire",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "0cb682cac1fd76326b551b057b28256280b7d7a982f6f418526b39bf75f5da45",
|
||||
"generated_at": "2026-10-26T06:55:28+00:00",
|
||||
"readme_raw_url": "https://github.com/AwsomeFox/campfire#readme"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "campfire",
|
||||
"container_name": "campfire",
|
||||
"image": {
|
||||
"reference": "ghcr.io/awsomefox/campfire:latest",
|
||||
"registry": "ghcr.io",
|
||||
"repository": "awsomefox/campfire",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-selected-tag-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "ALLOW_INSECURE_HTTP",
|
||||
"example": null,
|
||||
"required": false,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt": "Set to 1 only for a private HTTP-only LAN; use HTTPS otherwise."
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/data",
|
||||
"compose_source_example": "./data-0",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 8080,
|
||||
"published_example": 8080,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "{\n \"name\": \"campfire\",\n \"services\": {\n \"campfire\": {\n \"image\": \"ghcr.io/awsomefox/campfire:latest\",\n \"restart\": \"unless-stopped\",\n \"ports\": [\n \"8080:8080/tcp\"\n ],\n \"volumes\": [\n \"./data-0:/data\"\n ]\n }\n }\n}"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "campfire",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "campfire",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "campfire",
|
||||
"image": "ghcr.io/awsomefox/campfire:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "ghcr.io/awsomefox/campfire:latest",
|
||||
"restart": "unless-stopped",
|
||||
"ports": [
|
||||
"8080:8080/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"./data-0:/data"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "campfire"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "campfire-volume-0",
|
||||
"service": "campfire",
|
||||
"container_path": "/data",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"campfire"
|
||||
],
|
||||
"stop_order": [
|
||||
"campfire"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": []
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Campfire first-run setup",
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/auth/setup",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": []
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 1024,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 120
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/readyz",
|
||||
"timeout_seconds": 240,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 4,
|
||||
"verify_tls": false
|
||||
},
|
||||
"volume_owner": {
|
||||
"uid": 1000,
|
||||
"gid": 1000
|
||||
},
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/data",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-application-user",
|
||||
"mode": "2775",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
]
|
||||
},
|
||||
"catalog": {
|
||||
"replaces_discovered_ids": []
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,500 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-chhoto-url",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Chhoto URL",
|
||||
"es_ES": "Chhoto URL"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "A lightweight self-hosted URL shortener with SQLite storage.",
|
||||
"es_ES": "Un acortador de enlaces ligero y autoalojado con almacenamiento SQLite."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Create and manage short links from a small web interface. Chhoto URL stores its link database in SQLite and supports password-protected administration without a separate database service.",
|
||||
"es_ES": "Crea y administra enlaces cortos desde una interfaz web sencilla. Chhoto URL guarda los enlaces en SQLite y protege la administración con contraseña, sin necesitar otra base de datos."
|
||||
},
|
||||
"category": "tools",
|
||||
"category_label": "Tools",
|
||||
"author": "sintan1729",
|
||||
"developer": "sintan1729",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/chhoto-url.webp",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 4567,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://github.com/SinTan1729/chhoto-url",
|
||||
"documentation": "https://github.com/SinTan1729/chhoto-url/blob/main/docs/INSTALLATION.md",
|
||||
"repository": "https://github.com/SinTan1729/chhoto-url",
|
||||
"tips": [
|
||||
"The installer generates the required administrator password. Use HTTPS through a reverse proxy when sending the password over a network; upstream notes that it is not encrypted in plain HTTP."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "sintan1729",
|
||||
"repository": "https://github.com/SinTan1729/chhoto-url",
|
||||
"revision": "611ac292c2dc998fac78a3f726afc3c61a344991",
|
||||
"image_repository_url": "https://hub.docker.com/r/sintan1729/chhoto-url",
|
||||
"readme_pushed_at": "",
|
||||
"default_branch": "main",
|
||||
"compose_sha256": "ccfc1092edaa68277222f013a8c42a4f33c01f0e70bfffb78188c33643f28a87",
|
||||
"generated_at": "2026-10-26T08:45:03+00:00",
|
||||
"readme_raw_url": "https://raw.githubusercontent.com/SinTan1729/chhoto-url/main/README.md"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "chhoto-url",
|
||||
"container_name": "chhoto-url",
|
||||
"image": {
|
||||
"reference": "sintan1729/chhoto-url:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "sintan1729/chhoto-url",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "CHHOTO_PASSWORD",
|
||||
"example": "${GENERATED_CHHOTO_PASSWORD}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"name": "CHHOTO_DB_URL",
|
||||
"example": "/data/urls.sqlite",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt_user": false
|
||||
},
|
||||
{
|
||||
"name": "CHHOTO_SQLITE_USE_WAL_MODE",
|
||||
"example": "True",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt_user": false
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/data",
|
||||
"compose_source_example": "data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 4
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 4567,
|
||||
"published_example": 4567,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "services:\n chhoto-url:\n image: sintan1729/chhoto-url:latest\n container_name: chhoto-url\n restart: unless-stopped\n ports:\n - 4567:4567/tcp\n volumes:\n - ./data:/data\n environment:\n CHHOTO_PASSWORD: ${GENERATED_CHHOTO_PASSWORD}\n CHHOTO_DB_URL: /data/urls.sqlite\n CHHOTO_SQLITE_USE_WAL_MODE: 'True'\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "chhoto-url",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "chhoto-url",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "chhoto-url",
|
||||
"image": "sintan1729/chhoto-url:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"environment": {
|
||||
"CHHOTO_PASSWORD": "${GENERATED_CHHOTO_PASSWORD}",
|
||||
"CHHOTO_DB_URL": "/data/urls.sqlite",
|
||||
"CHHOTO_SQLITE_USE_WAL_MODE": "True"
|
||||
},
|
||||
"image": "sintan1729/chhoto-url:latest",
|
||||
"ports": [
|
||||
"4567:4567/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"./data:/data"
|
||||
],
|
||||
"container_name": "chhoto-url",
|
||||
"restart": "unless-stopped"
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "chhoto-url"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "chhoto-url-volume-0",
|
||||
"service": "chhoto-url",
|
||||
"container_path": "/data",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"chhoto-url"
|
||||
],
|
||||
"stop_order": [
|
||||
"chhoto-url"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "generated-chhoto-password",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "chhoto-url",
|
||||
"environment_variable": "CHHOTO_PASSWORD"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Chhoto URL",
|
||||
"scheme": "http",
|
||||
"port": 4567,
|
||||
"path": "/",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "Chhoto URL administrator password",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "Not required (password only)",
|
||||
"password": null,
|
||||
"password_environment": "CHHOTO_PASSWORD",
|
||||
"change_required": false,
|
||||
"source": "proxmenux-installer-generated",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 512,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/data",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-root",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"generated_sensitive_environment": {
|
||||
"CHHOTO_PASSWORD": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 24,
|
||||
"prompt": false
|
||||
}
|
||||
},
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 4567,
|
||||
"path": "/",
|
||||
"timeout_seconds": 180,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false,
|
||||
"accept_any_status": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,482 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-ech0",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Ech0",
|
||||
"es_ES": "Ech0"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "A personal, self-hosted microblog and timeline.",
|
||||
"es_ES": "Un microblog y una cronología personal que alojas en tu propio servidor."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Publish short posts, links and media on a personal timeline that you control. Ech0 includes accounts, comments, RSS and local data storage in one lightweight service.",
|
||||
"es_ES": "Publica textos breves, enlaces y contenido multimedia en una cronología propia. Ech0 incluye cuentas, comentarios, RSS y almacenamiento local en un único servicio."
|
||||
},
|
||||
"category": "communication",
|
||||
"category_label": "Communication & Community",
|
||||
"author": "lin-snow",
|
||||
"developer": "lin-snow",
|
||||
"icon": "https://raw.githubusercontent.com/lin-snow/Ech0/main/docs/imgs/logo.svg",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 6277,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://www.ech0.app/",
|
||||
"documentation": "https://github.com/lin-snow/Ech0/blob/main/DEPLOYMENT.md",
|
||||
"repository": "https://github.com/lin-snow/Ech0",
|
||||
"tips": [
|
||||
"The first registered account becomes the Owner. Publishing is restricted to privileged accounts by default.",
|
||||
"Keep the generated JWT secret and the /app/data volume persistent; back up the data volume and retain the same secret across restarts."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "lin-snow",
|
||||
"repository": "https://github.com/lin-snow/Ech0",
|
||||
"revision": "f2da207f4ab7bd89053898dd1e18ffb4ded1204d",
|
||||
"image_repository_url": "https://hub.docker.com/r/sn0wl1n/ech0",
|
||||
"readme_pushed_at": "",
|
||||
"default_branch": "main",
|
||||
"compose_sha256": "3ccb02dfdb7cd5198b2181a1a2f78e0b3a7e205efaf6920c1ca1257a4416b0bd",
|
||||
"generated_at": "2026-10-26T09:32:51+00:00",
|
||||
"readme_raw_url": "https://raw.githubusercontent.com/lin-snow/Ech0/main/README.md"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "ech0",
|
||||
"container_name": "ech0",
|
||||
"image": {
|
||||
"reference": "sn0wl1n/ech0:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "sn0wl1n/ech0",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "JWT_SECRET",
|
||||
"example": "${GENERATED_JWT_SECRET}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/app/data",
|
||||
"compose_source_example": "data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 6277,
|
||||
"published_example": 6277,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "services:\n ech0:\n image: sn0wl1n/ech0:latest\n container_name: ech0\n restart: unless-stopped\n ports:\n - 6277:6277/tcp\n volumes:\n - ./data:/app/data\n environment:\n JWT_SECRET: ${GENERATED_JWT_SECRET}\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "ech0",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "ech0",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "ech0",
|
||||
"image": "sn0wl1n/ech0:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "sn0wl1n/ech0:latest",
|
||||
"ports": [
|
||||
"6277:6277/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"./data:/app/data"
|
||||
],
|
||||
"container_name": "ech0",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {
|
||||
"JWT_SECRET": "${GENERATED_JWT_SECRET}"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "ech0"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "ech0-volume-0",
|
||||
"service": "ech0",
|
||||
"container_path": "/app/data",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"ech0"
|
||||
],
|
||||
"stop_order": [
|
||||
"ech0"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "generated-jwt-secret",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "ech0",
|
||||
"environment_variable": "JWT_SECRET"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Ech0",
|
||||
"scheme": "http",
|
||||
"port": 6277,
|
||||
"path": "/",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "First Ech0 account (becomes Owner)",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "Created during first-run setup",
|
||||
"password": null,
|
||||
"change_required": false,
|
||||
"source": "upstream-documentation",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 512,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/app/data",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-root",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"generated_sensitive_environment": {
|
||||
"JWT_SECRET": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 32,
|
||||
"prompt": false
|
||||
}
|
||||
},
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 6277,
|
||||
"path": "/",
|
||||
"timeout_seconds": 180,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false,
|
||||
"accept_any_status": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,540 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-kopia",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Kopia",
|
||||
"es_ES": "Kopia"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "Create encrypted, deduplicated backups and restore files.",
|
||||
"es_ES": "Crea copias cifradas y deduplicadas y restaura archivos."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Kopia provides encrypted, deduplicated backups with a web interface for repositories, policies, snapshots and restores. This profile supports browsing and restoring files through the UI; mounting snapshots with FUSE is not enabled.",
|
||||
"es_ES": "Kopia ofrece copias cifradas y deduplicadas, con una interfaz web para repositorios, políticas, snapshots y restauraciones. Este perfil permite explorar y restaurar archivos desde la interfaz; no habilita el montaje de snapshots mediante FUSE."
|
||||
},
|
||||
"category": "backup",
|
||||
"category_label": "Backup & Recovery",
|
||||
"author": "kopia",
|
||||
"developer": "kopia",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/kopia.webp",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 51515,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://github.com/kopia/kopia",
|
||||
"documentation": "https://kopia.io/docs/installation/",
|
||||
"repository": "https://github.com/kopia/kopia",
|
||||
"tips": [
|
||||
"The installer generates a web UI password and a separate repository encryption password. Keep the Proxmox LXC configuration and /app/config volume in backups; without the repository password, encrypted snapshots cannot be opened.",
|
||||
"On first visit, create a repository in Kopia UI at /repository, then add /data as a read-only source and choose /restore for restores. Choose a host bind for /data and for /repository if you want to back up a NAS or other host directory.",
|
||||
"The recipe keeps the LXC unprivileged and does not configure FUSE snapshot mounting. Use Kopia UI restore workflows rather than mounting snapshots into the host.",
|
||||
"The server uses HTTP on its LXC address. Keep it on a trusted LAN or put it behind an HTTPS reverse proxy before allowing access from untrusted networks.",
|
||||
"This profile uses the web interface to browse and restore files. It does not enable mounting snapshots with FUSE or shared mount propagation.",
|
||||
"Este perfil usa la interfaz web para explorar y restaurar archivos. No habilita el montaje de snapshots con FUSE ni la propagación compartida de montajes."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "kopia",
|
||||
"repository": "https://github.com/kopia/kopia",
|
||||
"revision": "0835005737025dc3e5203df0138c8265686cb4b3",
|
||||
"image_repository_url": "https://hub.docker.com/r/kopia/kopia",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "e17828b2fb52ceea822dc412d87549dabe2fb0f404ba16b21272e01d8a78b5c8",
|
||||
"generated_at": "2026-10-26T06:50:27+00:00",
|
||||
"readme_raw_url": "https://kopia.io/docs/installation/"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "kopia",
|
||||
"container_name": "kopia",
|
||||
"image": {
|
||||
"reference": "kopia/kopia:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "kopia/kopia",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "KOPIA_PASSWORD",
|
||||
"example": "${GENERATED_KOPIA_PASSWORD}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "official-docker-documentation"
|
||||
},
|
||||
{
|
||||
"name": "KOPIA_SERVER_USERNAME",
|
||||
"example": "kopia",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "official-kopia-cli",
|
||||
"prompt_user": false
|
||||
},
|
||||
{
|
||||
"name": "KOPIA_SERVER_PASSWORD",
|
||||
"example": "${GENERATED_KOPIA_SERVER_PASSWORD}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "official-kopia-cli"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/app/config",
|
||||
"compose_source_example": "kopia-config",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "volume-1",
|
||||
"container_path": "/app/cache",
|
||||
"compose_source_example": "kopia-cache",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "volume-2",
|
||||
"container_path": "/app/logs",
|
||||
"compose_source_example": "kopia-logs",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "volume-3",
|
||||
"container_path": "/data",
|
||||
"compose_source_example": "./backup-source",
|
||||
"read_only": true,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"host-bind"
|
||||
],
|
||||
"default": "host-bind",
|
||||
"managed_volume": {
|
||||
"backup": false,
|
||||
"default_size_gb": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "volume-4",
|
||||
"container_path": "/repository",
|
||||
"compose_source_example": "./kopia-repository",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 16
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "volume-5",
|
||||
"container_path": "/restore",
|
||||
"compose_source_example": "kopia-restore",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 51515,
|
||||
"published_example": 51515,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "{\n \"name\": \"kopia\",\n \"services\": {\n \"kopia\": {\n \"image\": \"kopia/kopia:latest\",\n \"container_name\": \"kopia\",\n \"hostname\": \"kopia\",\n \"restart\": \"unless-stopped\",\n \"command\": [\n \"server\",\n \"start\",\n \"--async-repo-connect\",\n \"--address=0.0.0.0:51515\",\n \"--server-username=kopia\"\n ],\n \"environment\": {\n \"KOPIA_PASSWORD\": \"${GENERATED_KOPIA_PASSWORD}\",\n \"KOPIA_SERVER_USERNAME\": \"kopia\",\n \"KOPIA_SERVER_PASSWORD\": \"${GENERATED_KOPIA_SERVER_PASSWORD}\"\n },\n \"ports\": [\n \"51515:51515/tcp\"\n ],\n \"volumes\": [\n \"kopia-config:/app/config\",\n \"kopia-cache:/app/cache\",\n \"kopia-logs:/app/logs\",\n \"./backup-source:/data:ro\",\n \"kopia-repository:/repository\",\n \"kopia-restore:/restore\"\n ]\n }\n }\n}\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "kopia",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "kopia",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "kopia",
|
||||
"image": "kopia/kopia:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "kopia/kopia:latest",
|
||||
"container_name": "kopia",
|
||||
"hostname": "kopia",
|
||||
"restart": "unless-stopped",
|
||||
"command": [
|
||||
"server",
|
||||
"start",
|
||||
"--async-repo-connect",
|
||||
"--address=0.0.0.0:51515",
|
||||
"--server-username=kopia",
|
||||
"--insecure"
|
||||
],
|
||||
"environment": {
|
||||
"KOPIA_PASSWORD": "${GENERATED_KOPIA_PASSWORD}",
|
||||
"KOPIA_SERVER_USERNAME": "kopia",
|
||||
"KOPIA_SERVER_PASSWORD": "${GENERATED_KOPIA_SERVER_PASSWORD}"
|
||||
},
|
||||
"ports": [
|
||||
"51515:51515/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"kopia-config:/app/config",
|
||||
"kopia-cache:/app/cache",
|
||||
"kopia-logs:/app/logs",
|
||||
"./backup-source:/data:ro",
|
||||
"kopia-repository:/repository",
|
||||
"kopia-restore:/restore"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "kopia"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "kopia-volume-0",
|
||||
"service": "kopia",
|
||||
"container_path": "/app/config",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "kopia-volume-1",
|
||||
"service": "kopia",
|
||||
"container_path": "/app/cache",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "kopia-volume-2",
|
||||
"service": "kopia",
|
||||
"container_path": "/app/logs",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "kopia-volume-3",
|
||||
"service": "kopia",
|
||||
"container_path": "/data",
|
||||
"mode": "host-bind",
|
||||
"user_selectable": false,
|
||||
"backup": false,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "kopia-volume-4",
|
||||
"service": "kopia",
|
||||
"container_path": "/repository",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "kopia-volume-5",
|
||||
"service": "kopia",
|
||||
"container_path": "/restore",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"kopia"
|
||||
],
|
||||
"stop_order": [
|
||||
"kopia"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "kopia-password",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "kopia",
|
||||
"environment_variable": "KOPIA_PASSWORD"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "kopia-server-password",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "kopia",
|
||||
"environment_variable": "KOPIA_SERVER_PASSWORD"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Kopia Web UI",
|
||||
"scheme": "http",
|
||||
"port": 51515,
|
||||
"path": "/",
|
||||
"source": "official-docker-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "Kopia Web UI login",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "kopia",
|
||||
"password": null,
|
||||
"password_environment": "KOPIA_SERVER_PASSWORD",
|
||||
"change_required": false,
|
||||
"source": "official-kopia-cli",
|
||||
"retrieval": null
|
||||
},
|
||||
{
|
||||
"label": "Repository encryption password",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "Not applicable",
|
||||
"password": null,
|
||||
"password_environment": "KOPIA_PASSWORD",
|
||||
"change_required": false,
|
||||
"source": "official-docker-documentation",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 2048,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 120
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "The Compose definition publishes service ports on its Docker host.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the image service ports and exposes them on this LXC address without Docker port NAT.",
|
||||
"reason": "The application runs in its own Proxmox LXC network namespace.",
|
||||
"behavioral_impact": "Connect to the LXC address and the service port shown in the install summary.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose provides the command that starts the service.",
|
||||
"native_lxc_behavior": "ProxMenux imports the image entrypoint and applies the reviewed command as the native OCI process.",
|
||||
"reason": "The image runs directly as a native OCI LXC process.",
|
||||
"behavioral_impact": "The process starts with the upstream server command.",
|
||||
"validation": "pending-per-application"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"generated_sensitive_environment": {
|
||||
"KOPIA_PASSWORD": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 32,
|
||||
"prompt": false
|
||||
},
|
||||
"KOPIA_SERVER_PASSWORD": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 24,
|
||||
"prompt": true
|
||||
}
|
||||
},
|
||||
"runtime": {
|
||||
"command": [
|
||||
"server",
|
||||
"start",
|
||||
"--async-repo-connect",
|
||||
"--address=0.0.0.0:51515",
|
||||
"--server-username=kopia",
|
||||
"--insecure"
|
||||
],
|
||||
"hostname": "kopia"
|
||||
},
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 51515,
|
||||
"path": "/",
|
||||
"timeout_seconds": 240,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false,
|
||||
"accept_any_status": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"command",
|
||||
"container_name",
|
||||
"environment",
|
||||
"hostname",
|
||||
"image",
|
||||
"ports",
|
||||
"restart",
|
||||
"volumes"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "The single upstream image runs as a native Proxmox OCI LXC. Only the documented image command, environment, ports and persistent paths are translated."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-metabase",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Metabase",
|
||||
"es_ES": "Metabase"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "Build reports and dashboards from your data.",
|
||||
"es_ES": "Crea informes y paneles a partir de tus datos."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "An open-source business intelligence platform for querying data and building dashboards. This single-container profile uses embedded H2 for a home-lab trial or small instance; PostgreSQL is recommended for production.",
|
||||
"es_ES": "Plataforma de inteligencia de negocio de código abierto para consultar datos y crear paneles. Este perfil de un solo contenedor usa H2 integrada para pruebas o instalaciones pequeñas; para producción se recomienda PostgreSQL."
|
||||
},
|
||||
"category": "monitoring",
|
||||
"category_label": "Monitoring & Analytics",
|
||||
"author": "Metabase",
|
||||
"developer": "Metabase",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/metabase.webp",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 3000,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://www.metabase.com/",
|
||||
"documentation": "https://www.metabase.com/docs/latest/installation-and-operation/running-metabase-on-docker",
|
||||
"repository": "https://github.com/metabase/metabase",
|
||||
"tips": [
|
||||
"This profile uses the built-in H2 application database for a simple single-container home-lab setup. Metabase recommends PostgreSQL for production; its application database stores users, questions, dashboards and settings.",
|
||||
"On first visit, complete the setup wizard and create the administrator account. Keep the service on a trusted LAN until setup and authentication are complete.",
|
||||
"The H2 database is stored at /metabase-data/metabase.db. Keep the managed volume persistent and back it up before upgrades or migration.",
|
||||
"ProxMenux generates MB_ENCRYPTION_SECRET_KEY at installation. Keep that key with your backups; losing it can prevent Metabase from decrypting saved database connection credentials.",
|
||||
"The image follows the v0.64 LTS release track. The installer gives it 2 GiB RAM and caps the Java heap at 1 GiB, leaving memory for the rest of the JVM.",
|
||||
"The embedded H2 application database is suitable for a trial or small instance. Metabase recommends PostgreSQL for production; this profile does not add a separate database service.",
|
||||
"La base de datos H2 integrada sirve para pruebas o instalaciones pequeñas. Metabase recomienda PostgreSQL para producción; este perfil no añade una base de datos aparte."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "metabase",
|
||||
"repository": "https://github.com/metabase/metabase",
|
||||
"revision": "9fe55abf5c14d7b4a585be9736affcdd0890be36",
|
||||
"image_repository_url": "https://hub.docker.com/r/metabase/metabase",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "eb8044f4c7c178e640b24d7cd0e6ce2edf51aafcf4f30ee112f5f1e37b4a2dd3",
|
||||
"generated_at": "2026-10-26T07:19:57+00:00",
|
||||
"readme_raw_url": "https://www.metabase.com/docs/latest/installation-and-operation/running-metabase-on-docker"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "metabase",
|
||||
"container_name": "metabase",
|
||||
"image": {
|
||||
"reference": "metabase/metabase:v0.64-lts",
|
||||
"registry": "docker.io",
|
||||
"repository": "metabase/metabase",
|
||||
"tag": "v0.64-lts",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "MB_DB_TYPE",
|
||||
"example": "h2",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "MB_DB_FILE",
|
||||
"example": "/metabase-data/metabase.db",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "MB_ENCRYPTION_SECRET_KEY",
|
||||
"example": "${GENERATED_MB_ENCRYPTION_SECRET_KEY}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "MUID",
|
||||
"example": "2000",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "MGID",
|
||||
"example": "2000",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "JAVA_OPTS",
|
||||
"example": "-Xmx1g",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/metabase-data",
|
||||
"compose_source_example": "metabase-data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 3000,
|
||||
"published_example": 3000,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "name: metabase\nservices:\n metabase:\n image: metabase/metabase:v0.64-lts\n restart: unless-stopped\n ports:\n - 3000:3000/tcp\n volumes:\n - metabase-data:/metabase-data\n environment:\n MB_DB_TYPE: h2\n MB_DB_FILE: /metabase-data/metabase.db\n MB_ENCRYPTION_SECRET_KEY: ${GENERATED_MB_ENCRYPTION_SECRET_KEY}\n MUID: '2000'\n MGID: '2000'\n JAVA_OPTS: -Xmx1g\n healthcheck:\n test:\n - CMD-SHELL\n - curl --fail -I http://localhost:3000/api/health || exit 1\n interval: 15s\n timeout: 5s\n retries: 5\n start_period: 180s\nvolumes:\n metabase-data: {}\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "metabase",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "metabase",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "metabase",
|
||||
"image": "metabase/metabase:v0.64-lts",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "metabase/metabase:v0.64-lts",
|
||||
"restart": "unless-stopped",
|
||||
"ports": [
|
||||
"3000:3000/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"metabase-data:/metabase-data"
|
||||
],
|
||||
"environment": {
|
||||
"MB_DB_TYPE": "h2",
|
||||
"MB_DB_FILE": "/metabase-data/metabase.db",
|
||||
"MB_ENCRYPTION_SECRET_KEY": "${GENERATED_MB_ENCRYPTION_SECRET_KEY}",
|
||||
"MUID": "2000",
|
||||
"MGID": "2000",
|
||||
"JAVA_OPTS": "-Xmx1g"
|
||||
},
|
||||
"healthcheck": {
|
||||
"test": [
|
||||
"CMD-SHELL",
|
||||
"curl --fail -I http://localhost:3000/api/health || exit 1"
|
||||
],
|
||||
"interval": "15s",
|
||||
"timeout": "5s",
|
||||
"retries": 5,
|
||||
"start_period": "180s"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "metabase",
|
||||
"volumes": {
|
||||
"metabase-data": {}
|
||||
}
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "metabase-volume-0",
|
||||
"service": "metabase",
|
||||
"container_path": "/metabase-data",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": false,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"metabase"
|
||||
],
|
||||
"stop_order": [
|
||||
"metabase"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "mb-encryption-secret-key",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "metabase",
|
||||
"environment_variable": "MB_ENCRYPTION_SECRET_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Web UI",
|
||||
"scheme": "http",
|
||||
"port": 3000,
|
||||
"path": "/",
|
||||
"source": "compose-metadata"
|
||||
}
|
||||
],
|
||||
"credentials": []
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 2048,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"installer_profile": {
|
||||
"startup_healthcheck": {
|
||||
"type": "http",
|
||||
"scheme": "http",
|
||||
"port": 3000,
|
||||
"path": "/api/health",
|
||||
"timeout_seconds": 300,
|
||||
"request_timeout_seconds": 5,
|
||||
"stability_seconds": 0,
|
||||
"verify_tls": false,
|
||||
"required": true,
|
||||
"source": "compose-healthcheck"
|
||||
},
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/metabase-data",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-application-user",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"volume_owner": {
|
||||
"uid": 2000,
|
||||
"gid": 2000
|
||||
},
|
||||
"generated_sensitive_environment": {
|
||||
"MB_ENCRYPTION_SECRET_KEY": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 32,
|
||||
"prompt": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
]
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,533 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-openhabittracker",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "OpenHabitTracker",
|
||||
"es_ES": "OpenHabitTracker"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "A self-hosted tracker for habits, tasks, notes and goals.",
|
||||
"es_ES": "Seguimiento autoalojado de hábitos, tareas, notas y objetivos."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "The official image includes the Blazor Server application for one user. It persists application data and backups in /app/.OpenHabitTracker.",
|
||||
"es_ES": "La imagen oficial incluye la aplicación Blazor Server para una persona. Guarda los datos y las copias de seguridad en /app/.OpenHabitTracker."
|
||||
},
|
||||
"category": "productivity",
|
||||
"category_label": "Productivity & Workflows",
|
||||
"author": "Jinjinov",
|
||||
"developer": "Jinjinov",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/Jinjinov/OpenHabitTracker@main/OpenHabitTracker.Web/icons/icon-512.png",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/login"
|
||||
},
|
||||
"website": "https://github.com/Jinjinov/OpenHabitTracker",
|
||||
"documentation": "https://github.com/Jinjinov/OpenHabitTracker/blob/main/README.md",
|
||||
"repository": "https://github.com/Jinjinov/OpenHabitTracker",
|
||||
"tips": [
|
||||
"The installer sets the initial username, email and password. Sign in at /login after startup."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "Jinjinov",
|
||||
"repository": "https://github.com/Jinjinov/OpenHabitTracker",
|
||||
"revision": "a285bf78c04ecebf3b3acc701f1776d4da326905",
|
||||
"image_repository_url": "https://hub.docker.com/r/jinjinov/openhabittracker",
|
||||
"readme_pushed_at": "",
|
||||
"default_branch": "main",
|
||||
"compose_sha256": "1405f9aea98cdf7cc414b9c00a13a1b5086cba2de51f3ba6d1d607e48c94a5d8",
|
||||
"generated_at": "2026-10-26T08:45:03+00:00",
|
||||
"readme_raw_url": "https://raw.githubusercontent.com/Jinjinov/OpenHabitTracker/main/README.md"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "openhabittracker",
|
||||
"container_name": "openhabittracker",
|
||||
"image": {
|
||||
"reference": "jinjinov/openhabittracker:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "jinjinov/openhabittracker",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "AppSettings__UserName",
|
||||
"example": "",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt": "OpenHabitTracker initial username"
|
||||
},
|
||||
{
|
||||
"name": "AppSettings__Email",
|
||||
"example": "",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt": "Email address for the OpenHabitTracker account"
|
||||
},
|
||||
{
|
||||
"name": "AppSettings__Password",
|
||||
"example": "${GENERATED_APPSETTINGS_PASSWORD}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"name": "AppSettings__JwtSecret",
|
||||
"example": "${GENERATED_APPSETTINGS_JWT_SECRET}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"name": "TZ",
|
||||
"example": "Europe/Madrid",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt_user": false
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/app/.OpenHabitTracker",
|
||||
"compose_source_example": "data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 8080,
|
||||
"published_example": 8080,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "services:\n openhabittracker:\n image: jinjinov/openhabittracker:latest\n container_name: openhabittracker\n restart: unless-stopped\n ports:\n - 8080:8080/tcp\n volumes:\n - ./data:/app/.OpenHabitTracker\n environment:\n AppSettings__UserName: ${AppSettings__UserName}\n AppSettings__Email: ${AppSettings__Email}\n AppSettings__Password: ${GENERATED_APPSETTINGS_PASSWORD}\n AppSettings__JwtSecret: ${GENERATED_APPSETTINGS_JWT_SECRET}\n TZ: Europe/Madrid\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "openhabittracker",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "openhabittracker",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "openhabittracker",
|
||||
"image": "jinjinov/openhabittracker:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"environment": {
|
||||
"AppSettings__UserName": "${AppSettings__UserName}",
|
||||
"AppSettings__Email": "${AppSettings__Email}",
|
||||
"AppSettings__Password": "${GENERATED_APPSETTINGS_PASSWORD}",
|
||||
"AppSettings__JwtSecret": "${GENERATED_APPSETTINGS_JWT_SECRET}",
|
||||
"TZ": "Europe/Madrid"
|
||||
},
|
||||
"image": "jinjinov/openhabittracker:latest",
|
||||
"ports": [
|
||||
"8080:8080/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"./data:/app/.OpenHabitTracker"
|
||||
],
|
||||
"container_name": "openhabittracker",
|
||||
"restart": "unless-stopped"
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "openhabittracker"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "openhabittracker-volume-0",
|
||||
"service": "openhabittracker",
|
||||
"container_path": "/app/.OpenHabitTracker",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"openhabittracker"
|
||||
],
|
||||
"stop_order": [
|
||||
"openhabittracker"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "generated-appsettings-password",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "openhabittracker",
|
||||
"environment_variable": "AppSettings__Password"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "generated-appsettings-jwtsecret",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "openhabittracker",
|
||||
"environment_variable": "AppSettings__JwtSecret"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "OpenHabitTracker",
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/login",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "OpenHabitTracker account",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "Configured username",
|
||||
"username_environment": "AppSettings__UserName",
|
||||
"password": null,
|
||||
"password_environment": "AppSettings__Password",
|
||||
"change_required": false,
|
||||
"source": "proxmenux-installer-generated",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 512,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/app/.OpenHabitTracker",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-root",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"generated_sensitive_environment": {
|
||||
"AppSettings__Password": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 24,
|
||||
"prompt": false
|
||||
},
|
||||
"AppSettings__JwtSecret": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 32,
|
||||
"prompt": false
|
||||
}
|
||||
},
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/login",
|
||||
"timeout_seconds": 180,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false,
|
||||
"accept_any_status": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-restic-rest-server",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Restic REST Server",
|
||||
"es_ES": "Restic REST Server"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "A REST backend for restic backups; it has no web interface.",
|
||||
"es_ES": "Un backend REST para copias de Restic, sin interfaz web."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "The official rest-server image provides an authenticated HTTP REST backend for restic clients, with persistent repositories and bcrypt-protected user accounts. It exposes an API, not a browser-based application.",
|
||||
"es_ES": "La imagen oficial rest-server ofrece un backend HTTP REST autenticado para clientes Restic, con repositorios persistentes y cuentas protegidas con bcrypt. Expone una API, no una aplicación web."
|
||||
},
|
||||
"category": "backup",
|
||||
"category_label": "Backup & Recovery",
|
||||
"author": "restic",
|
||||
"developer": "restic",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/restic.webp",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": null,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://github.com/restic/rest-server",
|
||||
"documentation": "https://github.com/restic/rest-server",
|
||||
"repository": "https://github.com/restic/rest-server",
|
||||
"tips": [
|
||||
"Authentication stays enabled. Before connecting any backup client, open the container console and run create_user <username>; enter the password at the hidden prompt. Do not pass the password as a command-line argument. The image stores the bcrypt hash in /data/.htpasswd.",
|
||||
"The API has no web interface. Use a restic client with a repository URL that includes the username-specific path, for example rest:http://USER@HOST:8000/USER when private repositories are enabled.",
|
||||
"The upstream default uses HTTP, which sends Basic Authentication credentials in clear text. Use a trusted LAN or route clients through an HTTPS reverse proxy before remote access.",
|
||||
"With --private-repos enabled, each user can access only a matching repository subdirectory. Keep /data persistent; it contains both backups and the authentication file.",
|
||||
"The upstream endpoint uses HTTP. Use an HTTPS reverse proxy for remote clients; the example API URL shown in this entry is HTTP.",
|
||||
"El endpoint original usa HTTP. Para clientes remotos, coloca un proxy HTTPS delante; la URL de ejemplo de esta ficha usa HTTP."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "restic",
|
||||
"repository": "https://github.com/restic/rest-server",
|
||||
"revision": "cfcf3fea23edb404c860e8708e39306717fe3e85",
|
||||
"image_repository_url": "https://hub.docker.com/r/restic/rest-server",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "f346e67428e1c6e8e265d607401fe5d5289b5c7ad478170abb4984fa8dcb01ad",
|
||||
"generated_at": "2026-10-26T06:50:27+00:00",
|
||||
"readme_raw_url": "https://github.com/restic/rest-server"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "restic-rest-server",
|
||||
"container_name": "restic-rest-server",
|
||||
"image": {
|
||||
"reference": "restic/rest-server:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "restic/rest-server",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "OPTIONS",
|
||||
"example": "--private-repos",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "official-rest-server-documentation",
|
||||
"prompt_user": false
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/data",
|
||||
"compose_source_example": "restic-data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 16
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 8000,
|
||||
"published_example": 8000,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "{\n \"name\": \"restic-rest-server\",\n \"services\": {\n \"restic-rest-server\": {\n \"image\": \"restic/rest-server:latest\",\n \"container_name\": \"restic-rest-server\",\n \"restart\": \"unless-stopped\",\n \"ports\": [\n \"8000:8000/tcp\"\n ],\n \"volumes\": [\n \"restic-data:/data\"\n ],\n \"environment\": {\n \"OPTIONS\": \"--private-repos\"\n }\n }\n },\n \"volumes\": {\n \"restic-data\": {}\n }\n}\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "restic-rest-server",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "restic-rest-server",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "restic-rest-server",
|
||||
"image": "restic/rest-server:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "restic/rest-server:latest",
|
||||
"container_name": "restic-rest-server",
|
||||
"restart": "unless-stopped",
|
||||
"ports": [
|
||||
"8000:8000/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"restic-data:/data"
|
||||
],
|
||||
"environment": {
|
||||
"OPTIONS": "--private-repos"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "restic-rest-server",
|
||||
"volumes": {
|
||||
"restic-data": {}
|
||||
}
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "restic-rest-server-volume-0",
|
||||
"service": "restic-rest-server",
|
||||
"container_path": "/data",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"restic-rest-server"
|
||||
],
|
||||
"stop_order": [
|
||||
"restic-rest-server"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": []
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "REST API Basic Authentication user",
|
||||
"username": "Create with create_user in the container console",
|
||||
"password": null,
|
||||
"change_required": false,
|
||||
"source": "official-rest-server-documentation",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 1,
|
||||
"memory_mb": 512,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 120
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "The Compose definition publishes service ports on its Docker host.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the image service ports and exposes them on this LXC address without Docker port NAT.",
|
||||
"reason": "The application runs in its own Proxmox LXC network namespace.",
|
||||
"behavioral_impact": "Connect to the LXC address and the service port shown in the install summary.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose provides the command that starts the service.",
|
||||
"native_lxc_behavior": "ProxMenux imports the image entrypoint and applies the reviewed command as the native OCI process.",
|
||||
"reason": "The image runs directly as a native OCI LXC process.",
|
||||
"behavioral_impact": "The process starts with the upstream server command.",
|
||||
"validation": "pending-per-application"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 8000,
|
||||
"path": "/",
|
||||
"timeout_seconds": 120,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false,
|
||||
"accept_any_status": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"command",
|
||||
"container_name",
|
||||
"environment",
|
||||
"hostname",
|
||||
"image",
|
||||
"ports",
|
||||
"restart",
|
||||
"volumes"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "The single upstream image runs as a native Proxmox OCI LXC. Only the documented image command, environment, ports and persistent paths are translated."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,453 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-watcharr",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Watcharr",
|
||||
"es_ES": "Watcharr"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "Track movies, television, anime and games you want to enjoy.",
|
||||
"es_ES": "Lleva un registro de películas, series, anime y videojuegos."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Track movies, television shows, anime and games you want to watch or play. The single container stores its database and cache in /data.",
|
||||
"es_ES": "Haz seguimiento de películas, series, anime y juegos que quieres ver o jugar. El contenedor guarda la base de datos y la caché en /data."
|
||||
},
|
||||
"category": "media",
|
||||
"category_label": "Media & Streaming",
|
||||
"author": "sbondCo",
|
||||
"developer": "sbondCo",
|
||||
"icon": "https://raw.githubusercontent.com/sbondCo/Watcharr/dev/doc/static/img/logo-col.png",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 3080,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://watcharr.app/",
|
||||
"documentation": "https://watcharr.app/docs/installation/docker-compose",
|
||||
"repository": "https://github.com/sbondCo/Watcharr",
|
||||
"tips": [
|
||||
"The first account created becomes the administrator. Keep access limited to your trusted network until initial setup is complete."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "sbondCo",
|
||||
"repository": "https://github.com/sbondCo/Watcharr",
|
||||
"revision": "aa2a765788a4d0f6eb607e7f90acb0d89d62fcd7",
|
||||
"image_repository_url": "https://github.com/orgs/sbondco/packages/container/package/watcharr",
|
||||
"readme_pushed_at": "",
|
||||
"default_branch": "dev",
|
||||
"compose_sha256": "8c4aa4fc5f19e33730685e75e89a7d6a79253bc3ea7ebd6ea6e27e0981fe5f54",
|
||||
"generated_at": "2026-10-26T08:45:03+00:00",
|
||||
"readme_raw_url": "https://raw.githubusercontent.com/sbondCo/Watcharr/dev/README.md"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "watcharr",
|
||||
"container_name": "watcharr",
|
||||
"image": {
|
||||
"reference": "ghcr.io/sbondco/watcharr:latest",
|
||||
"registry": "ghcr.io",
|
||||
"repository": "ghcr.io/sbondco/watcharr",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/data",
|
||||
"compose_source_example": "data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 3080,
|
||||
"published_example": 3080,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "services:\n watcharr:\n image: ghcr.io/sbondco/watcharr:latest\n container_name: watcharr\n restart: unless-stopped\n ports:\n - 3080:3080/tcp\n volumes:\n - ./data:/data\n environment: {}\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "watcharr",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "watcharr",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "watcharr",
|
||||
"image": "ghcr.io/sbondco/watcharr:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "ghcr.io/sbondco/watcharr:latest",
|
||||
"ports": [
|
||||
"3080:3080/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"./data:/data"
|
||||
],
|
||||
"container_name": "watcharr",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "watcharr"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "watcharr-volume-0",
|
||||
"service": "watcharr",
|
||||
"container_path": "/data",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"watcharr"
|
||||
],
|
||||
"stop_order": [
|
||||
"watcharr"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": []
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Watcharr",
|
||||
"scheme": "http",
|
||||
"port": 3080,
|
||||
"path": "/",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "First Watcharr account (becomes administrator)",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "Created during first-run setup",
|
||||
"password": null,
|
||||
"change_required": false,
|
||||
"source": "upstream-documentation",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 512,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/data",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-root",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 3080,
|
||||
"path": "/",
|
||||
"timeout_seconds": 180,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false,
|
||||
"accept_any_status": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -419,6 +419,16 @@
|
||||
"zipkin": "monitoring",
|
||||
"znc": "communication",
|
||||
"zoraxy": "web",
|
||||
"zotero": "documents"
|
||||
"zotero": "documents",
|
||||
"campfire": "gaming",
|
||||
"chhoto-url": "tools",
|
||||
"openhabittracker": "productivity",
|
||||
"watcharr": "media",
|
||||
"ech0": "communication",
|
||||
"activepieces": "automation",
|
||||
"bytebase": "databases",
|
||||
"metabase": "monitoring",
|
||||
"kopia": "backup",
|
||||
"restic-rest-server": "backup"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,524 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-activepieces",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Activepieces",
|
||||
"es_ES": "Activepieces"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "Build visual automations for personal and hobby use.",
|
||||
"es_ES": "Crea automatizaciones visuales para uso personal."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Build and run automation flows from a self-hosted visual interface. This single-container profile uses Activepieces’ documented personal mode with embedded storage and an in-memory queue.",
|
||||
"es_ES": "Diseña y ejecuta flujos de automatización desde una interfaz visual autoalojada. Este perfil de un solo contenedor usa el modo personal documentado de Activepieces, con almacenamiento integrado y cola en memoria."
|
||||
},
|
||||
"category": "automation",
|
||||
"category_label": "Automation & Scheduling",
|
||||
"author": "Activepieces",
|
||||
"developer": "Activepieces",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/activepieces.webp",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 80,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://www.activepieces.com/",
|
||||
"documentation": "https://www.activepieces.com/docs/install/options/docker",
|
||||
"repository": "https://github.com/activepieces/activepieces",
|
||||
"tips": [
|
||||
"The first account you create becomes the administrator; Activepieces has no default username or password.",
|
||||
"Use the base URL entered during setup. Webhooks and app triggers need it to be reachable by third parties.",
|
||||
"This single-container mode uses embedded PGLite and an in-memory queue for personal use on one machine. It is not the production or multi-instance setup."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "activepieces",
|
||||
"repository": "https://github.com/activepieces/activepieces",
|
||||
"revision": "bc26934b0a08842ec4fd24d83ecd08907cbaec1e4d7a985d30138e4f67ea6855",
|
||||
"image_repository_url": "https://github.com/activepieces/activepieces/pkgs/container/activepieces",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "bc26934b0a08842ec4fd24d83ecd08907cbaec1e4d7a985d30138e4f67ea6855",
|
||||
"generated_at": "2026-10-26T10:22:17+00:00",
|
||||
"readme_raw_url": "https://raw.githubusercontent.com/activepieces/activepieces/main/README.md"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "activepieces",
|
||||
"container_name": "activepieces",
|
||||
"image": {
|
||||
"reference": "ghcr.io/activepieces/activepieces:latest",
|
||||
"registry": "ghcr.io",
|
||||
"repository": "ghcr.io/activepieces/activepieces",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "AP_DB_TYPE",
|
||||
"example": "PGLITE",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"name": "AP_REDIS_TYPE",
|
||||
"example": "MEMORY",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"name": "AP_FRONTEND_URL",
|
||||
"example": "",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt_user": true,
|
||||
"prompt": "Enter the base URL clients and webhook providers will use to reach this Activepieces instance."
|
||||
},
|
||||
{
|
||||
"name": "AP_ENCRYPTION_KEY",
|
||||
"example": "${GENERATED_AP_ENCRYPTION_KEY}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"name": "AP_JWT_SECRET",
|
||||
"example": "${GENERATED_AP_JWT_SECRET}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/root/.activepieces",
|
||||
"compose_source_example": "./activepieces-data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 80,
|
||||
"published_example": 80,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "name: activepieces\nservices:\n activepieces:\n environment:\n AP_DB_TYPE: PGLITE\n AP_ENCRYPTION_KEY: ${GENERATED_GENERATED_AP_ENCRYPTION_KEY}\n AP_FRONTEND_URL: ''\n AP_JWT_SECRET: ${GENERATED_GENERATED_AP_JWT_SECRET}\n AP_REDIS_TYPE: MEMORY\n image: ghcr.io/activepieces/activepieces:latest\n ports:\n - 80:80\n volumes:\n - ./.activepieces:/root/.activepieces\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "activepieces",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "activepieces",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "activepieces",
|
||||
"image": "ghcr.io/activepieces/activepieces:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"environment": {
|
||||
"AP_DB_TYPE": "PGLITE",
|
||||
"AP_ENCRYPTION_KEY": "${GENERATED_GENERATED_AP_ENCRYPTION_KEY}",
|
||||
"AP_FRONTEND_URL": "",
|
||||
"AP_JWT_SECRET": "${GENERATED_GENERATED_AP_JWT_SECRET}",
|
||||
"AP_REDIS_TYPE": "MEMORY"
|
||||
},
|
||||
"image": "ghcr.io/activepieces/activepieces:latest",
|
||||
"ports": [
|
||||
"80:80"
|
||||
],
|
||||
"volumes": [
|
||||
"./.activepieces:/root/.activepieces"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "activepieces"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "activepieces-volume-0",
|
||||
"service": "activepieces",
|
||||
"container_path": "/root/.activepieces",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": false,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"activepieces"
|
||||
],
|
||||
"stop_order": [
|
||||
"activepieces"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "generated-ap-encryption-key",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "activepieces",
|
||||
"environment_variable": "AP_ENCRYPTION_KEY"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "generated-ap-jwt-secret",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "activepieces",
|
||||
"environment_variable": "AP_JWT_SECRET"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Activepieces",
|
||||
"scheme": "http",
|
||||
"port": 80,
|
||||
"path": "/",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": []
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 2048,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/root/.activepieces",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-application-user",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"generated_sensitive_environment": {
|
||||
"AP_ENCRYPTION_KEY": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 16
|
||||
},
|
||||
"AP_JWT_SECRET": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 32
|
||||
}
|
||||
},
|
||||
"minimum_secret_length": {
|
||||
"AP_ENCRYPTION_KEY": 32,
|
||||
"AP_JWT_SECRET": 32
|
||||
},
|
||||
"volume_owner": {
|
||||
"uid": 0,
|
||||
"gid": 0
|
||||
},
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 80,
|
||||
"path": "/api/v1/health",
|
||||
"timeout_seconds": 300,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 5,
|
||||
"verify_tls": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,445 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-bytebase",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Bytebase",
|
||||
"es_ES": "Bytebase"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "Manage database changes, access and workflows.",
|
||||
"es_ES": "Administra cambios, accesos y flujos de trabajo de bases de datos."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Manage database changes, access and workflows through a browser-based workspace. The image contains its own database, so this profile does not require a second service.",
|
||||
"es_ES": "Gestiona cambios, accesos y flujos de bases de datos desde un espacio de trabajo web. La imagen incluye su propia base de datos, por lo que este perfil no necesita otro servicio."
|
||||
},
|
||||
"category": "databases",
|
||||
"category_label": "Databases",
|
||||
"author": "Bytebase",
|
||||
"developer": "Bytebase",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/bytebase/bytebase@main/frontend/src/assets/logo-icon.svg",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://www.bytebase.com/",
|
||||
"documentation": "https://docs.bytebase.com/get-started/self-host/deploy-with-docker",
|
||||
"repository": "https://github.com/bytebase/bytebase",
|
||||
"tips": [
|
||||
"On first visit, complete the web setup wizard to create the initial administrator and workspace; the image has no default login credentials.",
|
||||
"To use Bytebase for database changes, connect the database instances you want to manage from its web interface.",
|
||||
"En la primera visita, completa el asistente web para crear el administrador y el espacio de trabajo inicial; la imagen no tiene credenciales de acceso predeterminadas.",
|
||||
"Para gestionar cambios de bases de datos, conecta desde la interfaz las instancias que quieras administrar."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "Bytebase",
|
||||
"repository": "https://github.com/bytebase/bytebase",
|
||||
"revision": "e77473a25aa12a669dc15bc33d37c276d7478b47",
|
||||
"image_repository_url": "https://hub.docker.com/r/bytebase/bytebase",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "b3756c0ae20c2a82b17f7cd04f116c4aef1b4a49d6ccf651bd865d74ab865e22",
|
||||
"generated_at": "2026-10-26T09:44:16+00:00",
|
||||
"readme_raw_url": "https://github.com/bytebase/bytebase",
|
||||
"default_branch": "main"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "bytebase",
|
||||
"container_name": "bytebase",
|
||||
"image": {
|
||||
"reference": "bytebase/bytebase:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "bytebase/bytebase",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-selected-tag-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/var/opt/bytebase",
|
||||
"compose_source_example": "bytebase-data-0",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 16
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 8080,
|
||||
"published_example": 8080,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "{\n \"name\": \"bytebase\",\n \"services\": {\n \"bytebase\": {\n \"image\": \"bytebase/bytebase:latest\",\n \"restart\": \"unless-stopped\",\n \"command\": [\n \"--port\",\n \"8080\",\n \"--data\",\n \"/var/opt/bytebase\"\n ],\n \"ports\": [\n \"8080:8080/tcp\"\n ],\n \"volumes\": [\n \"bytebase-data-0:/var/opt/bytebase\"\n ]\n }\n },\n \"volumes\": {\n \"bytebase-data-0\": {}\n }\n}"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "bytebase",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "bytebase",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "bytebase",
|
||||
"image": "bytebase/bytebase:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "bytebase/bytebase:latest",
|
||||
"restart": "unless-stopped",
|
||||
"command": [
|
||||
"--port",
|
||||
"8080",
|
||||
"--data",
|
||||
"/var/opt/bytebase"
|
||||
],
|
||||
"ports": [
|
||||
"8080:8080/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"bytebase-data-0:/var/opt/bytebase"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "bytebase",
|
||||
"volumes": {
|
||||
"bytebase-data-0": {}
|
||||
}
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "bytebase-volume-0",
|
||||
"service": "bytebase",
|
||||
"container_path": "/var/opt/bytebase",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": false,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"bytebase"
|
||||
],
|
||||
"stop_order": [
|
||||
"bytebase"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": []
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Web UI",
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": []
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 2048,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 60
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/healthz",
|
||||
"timeout_seconds": 180,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false
|
||||
},
|
||||
"generated_sensitive_environment": {}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "pending",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,457 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-campfire",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Campfire",
|
||||
"es_ES": "Campfire"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "A self-hosted app for organizing tabletop role-playing campaigns.",
|
||||
"es_ES": "Aplicación autoalojada para organizar partidas de rol de mesa."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "A self-hosted web application for organizing tabletop role-playing games.",
|
||||
"es_ES": "Una aplicación web autoalojada para organizar campañas y sesiones de juegos de rol."
|
||||
},
|
||||
"category": "gaming",
|
||||
"category_label": "Gaming & Leisure",
|
||||
"author": "AwsomeFox",
|
||||
"developer": "AwsomeFox",
|
||||
"icon": "https://raw.githubusercontent.com/AwsomeFox/campfire/main/apps/web/public/pwa-512x512.png",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/auth/setup"
|
||||
},
|
||||
"website": "https://github.com/AwsomeFox/campfire",
|
||||
"documentation": "https://github.com/AwsomeFox/campfire#readme",
|
||||
"repository": "https://github.com/AwsomeFox/campfire",
|
||||
"tips": [
|
||||
"Create the first account at /auth/setup after startup.",
|
||||
"For direct access over plain HTTP on a trusted LAN, set ALLOW_INSECURE_HTTP=1 in advanced settings. Leave it unset when using HTTPS."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "AwsomeFox",
|
||||
"repository": "https://github.com/AwsomeFox/campfire",
|
||||
"revision": "f0dd871f5d2ab0b949db8c8a15a90ec56d40d3dc",
|
||||
"image_repository_url": "https://github.com/AwsomeFox/campfire/pkgs/container/campfire",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "0cb682cac1fd76326b551b057b28256280b7d7a982f6f418526b39bf75f5da45",
|
||||
"generated_at": "2026-10-26T06:55:28+00:00",
|
||||
"readme_raw_url": "https://github.com/AwsomeFox/campfire#readme"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "campfire",
|
||||
"container_name": "campfire",
|
||||
"image": {
|
||||
"reference": "ghcr.io/awsomefox/campfire:latest",
|
||||
"registry": "ghcr.io",
|
||||
"repository": "awsomefox/campfire",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-selected-tag-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "ALLOW_INSECURE_HTTP",
|
||||
"example": null,
|
||||
"required": false,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt": "Set to 1 only for a private HTTP-only LAN; use HTTPS otherwise."
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/data",
|
||||
"compose_source_example": "./data-0",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 8080,
|
||||
"published_example": 8080,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "{\n \"name\": \"campfire\",\n \"services\": {\n \"campfire\": {\n \"image\": \"ghcr.io/awsomefox/campfire:latest\",\n \"restart\": \"unless-stopped\",\n \"ports\": [\n \"8080:8080/tcp\"\n ],\n \"volumes\": [\n \"./data-0:/data\"\n ]\n }\n }\n}"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "campfire",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "campfire",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "campfire",
|
||||
"image": "ghcr.io/awsomefox/campfire:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "ghcr.io/awsomefox/campfire:latest",
|
||||
"restart": "unless-stopped",
|
||||
"ports": [
|
||||
"8080:8080/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"./data-0:/data"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "campfire"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "campfire-volume-0",
|
||||
"service": "campfire",
|
||||
"container_path": "/data",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"campfire"
|
||||
],
|
||||
"stop_order": [
|
||||
"campfire"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": []
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Campfire first-run setup",
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/auth/setup",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": []
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 1024,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 120
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/readyz",
|
||||
"timeout_seconds": 240,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 4,
|
||||
"verify_tls": false
|
||||
},
|
||||
"volume_owner": {
|
||||
"uid": 1000,
|
||||
"gid": 1000
|
||||
},
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/data",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-application-user",
|
||||
"mode": "2775",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
]
|
||||
},
|
||||
"catalog": {
|
||||
"replaces_discovered_ids": []
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,500 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-chhoto-url",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Chhoto URL",
|
||||
"es_ES": "Chhoto URL"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "A lightweight self-hosted URL shortener with SQLite storage.",
|
||||
"es_ES": "Un acortador de enlaces ligero y autoalojado con almacenamiento SQLite."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Create and manage short links from a small web interface. Chhoto URL stores its link database in SQLite and supports password-protected administration without a separate database service.",
|
||||
"es_ES": "Crea y administra enlaces cortos desde una interfaz web sencilla. Chhoto URL guarda los enlaces en SQLite y protege la administración con contraseña, sin necesitar otra base de datos."
|
||||
},
|
||||
"category": "tools",
|
||||
"category_label": "Tools",
|
||||
"author": "sintan1729",
|
||||
"developer": "sintan1729",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/chhoto-url.webp",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 4567,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://github.com/SinTan1729/chhoto-url",
|
||||
"documentation": "https://github.com/SinTan1729/chhoto-url/blob/main/docs/INSTALLATION.md",
|
||||
"repository": "https://github.com/SinTan1729/chhoto-url",
|
||||
"tips": [
|
||||
"The installer generates the required administrator password. Use HTTPS through a reverse proxy when sending the password over a network; upstream notes that it is not encrypted in plain HTTP."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "sintan1729",
|
||||
"repository": "https://github.com/SinTan1729/chhoto-url",
|
||||
"revision": "611ac292c2dc998fac78a3f726afc3c61a344991",
|
||||
"image_repository_url": "https://hub.docker.com/r/sintan1729/chhoto-url",
|
||||
"readme_pushed_at": "",
|
||||
"default_branch": "main",
|
||||
"compose_sha256": "ccfc1092edaa68277222f013a8c42a4f33c01f0e70bfffb78188c33643f28a87",
|
||||
"generated_at": "2026-10-26T08:45:03+00:00",
|
||||
"readme_raw_url": "https://raw.githubusercontent.com/SinTan1729/chhoto-url/main/README.md"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "chhoto-url",
|
||||
"container_name": "chhoto-url",
|
||||
"image": {
|
||||
"reference": "sintan1729/chhoto-url:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "sintan1729/chhoto-url",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "CHHOTO_PASSWORD",
|
||||
"example": "${GENERATED_CHHOTO_PASSWORD}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"name": "CHHOTO_DB_URL",
|
||||
"example": "/data/urls.sqlite",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt_user": false
|
||||
},
|
||||
{
|
||||
"name": "CHHOTO_SQLITE_USE_WAL_MODE",
|
||||
"example": "True",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt_user": false
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/data",
|
||||
"compose_source_example": "data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 4
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 4567,
|
||||
"published_example": 4567,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "services:\n chhoto-url:\n image: sintan1729/chhoto-url:latest\n container_name: chhoto-url\n restart: unless-stopped\n ports:\n - 4567:4567/tcp\n volumes:\n - ./data:/data\n environment:\n CHHOTO_PASSWORD: ${GENERATED_CHHOTO_PASSWORD}\n CHHOTO_DB_URL: /data/urls.sqlite\n CHHOTO_SQLITE_USE_WAL_MODE: 'True'\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "chhoto-url",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "chhoto-url",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "chhoto-url",
|
||||
"image": "sintan1729/chhoto-url:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"environment": {
|
||||
"CHHOTO_PASSWORD": "${GENERATED_CHHOTO_PASSWORD}",
|
||||
"CHHOTO_DB_URL": "/data/urls.sqlite",
|
||||
"CHHOTO_SQLITE_USE_WAL_MODE": "True"
|
||||
},
|
||||
"image": "sintan1729/chhoto-url:latest",
|
||||
"ports": [
|
||||
"4567:4567/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"./data:/data"
|
||||
],
|
||||
"container_name": "chhoto-url",
|
||||
"restart": "unless-stopped"
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "chhoto-url"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "chhoto-url-volume-0",
|
||||
"service": "chhoto-url",
|
||||
"container_path": "/data",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"chhoto-url"
|
||||
],
|
||||
"stop_order": [
|
||||
"chhoto-url"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "generated-chhoto-password",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "chhoto-url",
|
||||
"environment_variable": "CHHOTO_PASSWORD"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Chhoto URL",
|
||||
"scheme": "http",
|
||||
"port": 4567,
|
||||
"path": "/",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "Chhoto URL administrator password",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "Not required (password only)",
|
||||
"password": null,
|
||||
"password_environment": "CHHOTO_PASSWORD",
|
||||
"change_required": false,
|
||||
"source": "proxmenux-installer-generated",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 512,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/data",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-root",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"generated_sensitive_environment": {
|
||||
"CHHOTO_PASSWORD": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 24,
|
||||
"prompt": false
|
||||
}
|
||||
},
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 4567,
|
||||
"path": "/",
|
||||
"timeout_seconds": 180,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false,
|
||||
"accept_any_status": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,482 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-ech0",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Ech0",
|
||||
"es_ES": "Ech0"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "A personal, self-hosted microblog and timeline.",
|
||||
"es_ES": "Un microblog y una cronología personal que alojas en tu propio servidor."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Publish short posts, links and media on a personal timeline that you control. Ech0 includes accounts, comments, RSS and local data storage in one lightweight service.",
|
||||
"es_ES": "Publica textos breves, enlaces y contenido multimedia en una cronología propia. Ech0 incluye cuentas, comentarios, RSS y almacenamiento local en un único servicio."
|
||||
},
|
||||
"category": "communication",
|
||||
"category_label": "Communication & Community",
|
||||
"author": "lin-snow",
|
||||
"developer": "lin-snow",
|
||||
"icon": "https://raw.githubusercontent.com/lin-snow/Ech0/main/docs/imgs/logo.svg",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 6277,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://www.ech0.app/",
|
||||
"documentation": "https://github.com/lin-snow/Ech0/blob/main/DEPLOYMENT.md",
|
||||
"repository": "https://github.com/lin-snow/Ech0",
|
||||
"tips": [
|
||||
"The first registered account becomes the Owner. Publishing is restricted to privileged accounts by default.",
|
||||
"Keep the generated JWT secret and the /app/data volume persistent; back up the data volume and retain the same secret across restarts."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "lin-snow",
|
||||
"repository": "https://github.com/lin-snow/Ech0",
|
||||
"revision": "f2da207f4ab7bd89053898dd1e18ffb4ded1204d",
|
||||
"image_repository_url": "https://hub.docker.com/r/sn0wl1n/ech0",
|
||||
"readme_pushed_at": "",
|
||||
"default_branch": "main",
|
||||
"compose_sha256": "3ccb02dfdb7cd5198b2181a1a2f78e0b3a7e205efaf6920c1ca1257a4416b0bd",
|
||||
"generated_at": "2026-10-26T09:32:51+00:00",
|
||||
"readme_raw_url": "https://raw.githubusercontent.com/lin-snow/Ech0/main/README.md"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "ech0",
|
||||
"container_name": "ech0",
|
||||
"image": {
|
||||
"reference": "sn0wl1n/ech0:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "sn0wl1n/ech0",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "JWT_SECRET",
|
||||
"example": "${GENERATED_JWT_SECRET}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/app/data",
|
||||
"compose_source_example": "data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 6277,
|
||||
"published_example": 6277,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "services:\n ech0:\n image: sn0wl1n/ech0:latest\n container_name: ech0\n restart: unless-stopped\n ports:\n - 6277:6277/tcp\n volumes:\n - ./data:/app/data\n environment:\n JWT_SECRET: ${GENERATED_JWT_SECRET}\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "ech0",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "ech0",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "ech0",
|
||||
"image": "sn0wl1n/ech0:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "sn0wl1n/ech0:latest",
|
||||
"ports": [
|
||||
"6277:6277/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"./data:/app/data"
|
||||
],
|
||||
"container_name": "ech0",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {
|
||||
"JWT_SECRET": "${GENERATED_JWT_SECRET}"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "ech0"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "ech0-volume-0",
|
||||
"service": "ech0",
|
||||
"container_path": "/app/data",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"ech0"
|
||||
],
|
||||
"stop_order": [
|
||||
"ech0"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "generated-jwt-secret",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "ech0",
|
||||
"environment_variable": "JWT_SECRET"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Ech0",
|
||||
"scheme": "http",
|
||||
"port": 6277,
|
||||
"path": "/",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "First Ech0 account (becomes Owner)",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "Created during first-run setup",
|
||||
"password": null,
|
||||
"change_required": false,
|
||||
"source": "upstream-documentation",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 512,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/app/data",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-root",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"generated_sensitive_environment": {
|
||||
"JWT_SECRET": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 32,
|
||||
"prompt": false
|
||||
}
|
||||
},
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 6277,
|
||||
"path": "/",
|
||||
"timeout_seconds": 180,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false,
|
||||
"accept_any_status": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,540 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-kopia",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Kopia",
|
||||
"es_ES": "Kopia"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "Create encrypted, deduplicated backups and restore files.",
|
||||
"es_ES": "Crea copias cifradas y deduplicadas y restaura archivos."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Kopia provides encrypted, deduplicated backups with a web interface for repositories, policies, snapshots and restores. This profile supports browsing and restoring files through the UI; mounting snapshots with FUSE is not enabled.",
|
||||
"es_ES": "Kopia ofrece copias cifradas y deduplicadas, con una interfaz web para repositorios, políticas, snapshots y restauraciones. Este perfil permite explorar y restaurar archivos desde la interfaz; no habilita el montaje de snapshots mediante FUSE."
|
||||
},
|
||||
"category": "backup",
|
||||
"category_label": "Backup & Recovery",
|
||||
"author": "kopia",
|
||||
"developer": "kopia",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/kopia.webp",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 51515,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://github.com/kopia/kopia",
|
||||
"documentation": "https://kopia.io/docs/installation/",
|
||||
"repository": "https://github.com/kopia/kopia",
|
||||
"tips": [
|
||||
"The installer generates a web UI password and a separate repository encryption password. Keep the Proxmox LXC configuration and /app/config volume in backups; without the repository password, encrypted snapshots cannot be opened.",
|
||||
"On first visit, create a repository in Kopia UI at /repository, then add /data as a read-only source and choose /restore for restores. Choose a host bind for /data and for /repository if you want to back up a NAS or other host directory.",
|
||||
"The recipe keeps the LXC unprivileged and does not configure FUSE snapshot mounting. Use Kopia UI restore workflows rather than mounting snapshots into the host.",
|
||||
"The server uses HTTP on its LXC address. Keep it on a trusted LAN or put it behind an HTTPS reverse proxy before allowing access from untrusted networks.",
|
||||
"This profile uses the web interface to browse and restore files. It does not enable mounting snapshots with FUSE or shared mount propagation.",
|
||||
"Este perfil usa la interfaz web para explorar y restaurar archivos. No habilita el montaje de snapshots con FUSE ni la propagación compartida de montajes."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "kopia",
|
||||
"repository": "https://github.com/kopia/kopia",
|
||||
"revision": "0835005737025dc3e5203df0138c8265686cb4b3",
|
||||
"image_repository_url": "https://hub.docker.com/r/kopia/kopia",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "e17828b2fb52ceea822dc412d87549dabe2fb0f404ba16b21272e01d8a78b5c8",
|
||||
"generated_at": "2026-10-26T06:50:27+00:00",
|
||||
"readme_raw_url": "https://kopia.io/docs/installation/"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "kopia",
|
||||
"container_name": "kopia",
|
||||
"image": {
|
||||
"reference": "kopia/kopia:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "kopia/kopia",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "KOPIA_PASSWORD",
|
||||
"example": "${GENERATED_KOPIA_PASSWORD}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "official-docker-documentation"
|
||||
},
|
||||
{
|
||||
"name": "KOPIA_SERVER_USERNAME",
|
||||
"example": "kopia",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "official-kopia-cli",
|
||||
"prompt_user": false
|
||||
},
|
||||
{
|
||||
"name": "KOPIA_SERVER_PASSWORD",
|
||||
"example": "${GENERATED_KOPIA_SERVER_PASSWORD}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "official-kopia-cli"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/app/config",
|
||||
"compose_source_example": "kopia-config",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "volume-1",
|
||||
"container_path": "/app/cache",
|
||||
"compose_source_example": "kopia-cache",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "volume-2",
|
||||
"container_path": "/app/logs",
|
||||
"compose_source_example": "kopia-logs",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "volume-3",
|
||||
"container_path": "/data",
|
||||
"compose_source_example": "./backup-source",
|
||||
"read_only": true,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"host-bind"
|
||||
],
|
||||
"default": "host-bind",
|
||||
"managed_volume": {
|
||||
"backup": false,
|
||||
"default_size_gb": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "volume-4",
|
||||
"container_path": "/repository",
|
||||
"compose_source_example": "./kopia-repository",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 16
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "volume-5",
|
||||
"container_path": "/restore",
|
||||
"compose_source_example": "kopia-restore",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 51515,
|
||||
"published_example": 51515,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "{\n \"name\": \"kopia\",\n \"services\": {\n \"kopia\": {\n \"image\": \"kopia/kopia:latest\",\n \"container_name\": \"kopia\",\n \"hostname\": \"kopia\",\n \"restart\": \"unless-stopped\",\n \"command\": [\n \"server\",\n \"start\",\n \"--async-repo-connect\",\n \"--address=0.0.0.0:51515\",\n \"--server-username=kopia\"\n ],\n \"environment\": {\n \"KOPIA_PASSWORD\": \"${GENERATED_KOPIA_PASSWORD}\",\n \"KOPIA_SERVER_USERNAME\": \"kopia\",\n \"KOPIA_SERVER_PASSWORD\": \"${GENERATED_KOPIA_SERVER_PASSWORD}\"\n },\n \"ports\": [\n \"51515:51515/tcp\"\n ],\n \"volumes\": [\n \"kopia-config:/app/config\",\n \"kopia-cache:/app/cache\",\n \"kopia-logs:/app/logs\",\n \"./backup-source:/data:ro\",\n \"kopia-repository:/repository\",\n \"kopia-restore:/restore\"\n ]\n }\n }\n}\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "kopia",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "kopia",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "kopia",
|
||||
"image": "kopia/kopia:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "kopia/kopia:latest",
|
||||
"container_name": "kopia",
|
||||
"hostname": "kopia",
|
||||
"restart": "unless-stopped",
|
||||
"command": [
|
||||
"server",
|
||||
"start",
|
||||
"--async-repo-connect",
|
||||
"--address=0.0.0.0:51515",
|
||||
"--server-username=kopia",
|
||||
"--insecure"
|
||||
],
|
||||
"environment": {
|
||||
"KOPIA_PASSWORD": "${GENERATED_KOPIA_PASSWORD}",
|
||||
"KOPIA_SERVER_USERNAME": "kopia",
|
||||
"KOPIA_SERVER_PASSWORD": "${GENERATED_KOPIA_SERVER_PASSWORD}"
|
||||
},
|
||||
"ports": [
|
||||
"51515:51515/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"kopia-config:/app/config",
|
||||
"kopia-cache:/app/cache",
|
||||
"kopia-logs:/app/logs",
|
||||
"./backup-source:/data:ro",
|
||||
"kopia-repository:/repository",
|
||||
"kopia-restore:/restore"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "kopia"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "kopia-volume-0",
|
||||
"service": "kopia",
|
||||
"container_path": "/app/config",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "kopia-volume-1",
|
||||
"service": "kopia",
|
||||
"container_path": "/app/cache",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "kopia-volume-2",
|
||||
"service": "kopia",
|
||||
"container_path": "/app/logs",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "kopia-volume-3",
|
||||
"service": "kopia",
|
||||
"container_path": "/data",
|
||||
"mode": "host-bind",
|
||||
"user_selectable": false,
|
||||
"backup": false,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "kopia-volume-4",
|
||||
"service": "kopia",
|
||||
"container_path": "/repository",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
},
|
||||
{
|
||||
"id": "kopia-volume-5",
|
||||
"service": "kopia",
|
||||
"container_path": "/restore",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"kopia"
|
||||
],
|
||||
"stop_order": [
|
||||
"kopia"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "kopia-password",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "kopia",
|
||||
"environment_variable": "KOPIA_PASSWORD"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "kopia-server-password",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "kopia",
|
||||
"environment_variable": "KOPIA_SERVER_PASSWORD"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Kopia Web UI",
|
||||
"scheme": "http",
|
||||
"port": 51515,
|
||||
"path": "/",
|
||||
"source": "official-docker-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "Kopia Web UI login",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "kopia",
|
||||
"password": null,
|
||||
"password_environment": "KOPIA_SERVER_PASSWORD",
|
||||
"change_required": false,
|
||||
"source": "official-kopia-cli",
|
||||
"retrieval": null
|
||||
},
|
||||
{
|
||||
"label": "Repository encryption password",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "Not applicable",
|
||||
"password": null,
|
||||
"password_environment": "KOPIA_PASSWORD",
|
||||
"change_required": false,
|
||||
"source": "official-docker-documentation",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 2048,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 120
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "The Compose definition publishes service ports on its Docker host.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the image service ports and exposes them on this LXC address without Docker port NAT.",
|
||||
"reason": "The application runs in its own Proxmox LXC network namespace.",
|
||||
"behavioral_impact": "Connect to the LXC address and the service port shown in the install summary.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose provides the command that starts the service.",
|
||||
"native_lxc_behavior": "ProxMenux imports the image entrypoint and applies the reviewed command as the native OCI process.",
|
||||
"reason": "The image runs directly as a native OCI LXC process.",
|
||||
"behavioral_impact": "The process starts with the upstream server command.",
|
||||
"validation": "pending-per-application"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"generated_sensitive_environment": {
|
||||
"KOPIA_PASSWORD": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 32,
|
||||
"prompt": false
|
||||
},
|
||||
"KOPIA_SERVER_PASSWORD": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 24,
|
||||
"prompt": true
|
||||
}
|
||||
},
|
||||
"runtime": {
|
||||
"command": [
|
||||
"server",
|
||||
"start",
|
||||
"--async-repo-connect",
|
||||
"--address=0.0.0.0:51515",
|
||||
"--server-username=kopia",
|
||||
"--insecure"
|
||||
],
|
||||
"hostname": "kopia"
|
||||
},
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 51515,
|
||||
"path": "/",
|
||||
"timeout_seconds": 240,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false,
|
||||
"accept_any_status": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"command",
|
||||
"container_name",
|
||||
"environment",
|
||||
"hostname",
|
||||
"image",
|
||||
"ports",
|
||||
"restart",
|
||||
"volumes"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "The single upstream image runs as a native Proxmox OCI LXC. Only the documented image command, environment, ports and persistent paths are translated."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-metabase",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Metabase",
|
||||
"es_ES": "Metabase"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "Build reports and dashboards from your data.",
|
||||
"es_ES": "Crea informes y paneles a partir de tus datos."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "An open-source business intelligence platform for querying data and building dashboards. This single-container profile uses embedded H2 for a home-lab trial or small instance; PostgreSQL is recommended for production.",
|
||||
"es_ES": "Plataforma de inteligencia de negocio de código abierto para consultar datos y crear paneles. Este perfil de un solo contenedor usa H2 integrada para pruebas o instalaciones pequeñas; para producción se recomienda PostgreSQL."
|
||||
},
|
||||
"category": "monitoring",
|
||||
"category_label": "Monitoring & Analytics",
|
||||
"author": "Metabase",
|
||||
"developer": "Metabase",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/metabase.webp",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 3000,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://www.metabase.com/",
|
||||
"documentation": "https://www.metabase.com/docs/latest/installation-and-operation/running-metabase-on-docker",
|
||||
"repository": "https://github.com/metabase/metabase",
|
||||
"tips": [
|
||||
"This profile uses the built-in H2 application database for a simple single-container home-lab setup. Metabase recommends PostgreSQL for production; its application database stores users, questions, dashboards and settings.",
|
||||
"On first visit, complete the setup wizard and create the administrator account. Keep the service on a trusted LAN until setup and authentication are complete.",
|
||||
"The H2 database is stored at /metabase-data/metabase.db. Keep the managed volume persistent and back it up before upgrades or migration.",
|
||||
"ProxMenux generates MB_ENCRYPTION_SECRET_KEY at installation. Keep that key with your backups; losing it can prevent Metabase from decrypting saved database connection credentials.",
|
||||
"The image follows the v0.64 LTS release track. The installer gives it 2 GiB RAM and caps the Java heap at 1 GiB, leaving memory for the rest of the JVM.",
|
||||
"The embedded H2 application database is suitable for a trial or small instance. Metabase recommends PostgreSQL for production; this profile does not add a separate database service.",
|
||||
"La base de datos H2 integrada sirve para pruebas o instalaciones pequeñas. Metabase recomienda PostgreSQL para producción; este perfil no añade una base de datos aparte."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "metabase",
|
||||
"repository": "https://github.com/metabase/metabase",
|
||||
"revision": "9fe55abf5c14d7b4a585be9736affcdd0890be36",
|
||||
"image_repository_url": "https://hub.docker.com/r/metabase/metabase",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "eb8044f4c7c178e640b24d7cd0e6ce2edf51aafcf4f30ee112f5f1e37b4a2dd3",
|
||||
"generated_at": "2026-10-26T07:19:57+00:00",
|
||||
"readme_raw_url": "https://www.metabase.com/docs/latest/installation-and-operation/running-metabase-on-docker"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "metabase",
|
||||
"container_name": "metabase",
|
||||
"image": {
|
||||
"reference": "metabase/metabase:v0.64-lts",
|
||||
"registry": "docker.io",
|
||||
"repository": "metabase/metabase",
|
||||
"tag": "v0.64-lts",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "MB_DB_TYPE",
|
||||
"example": "h2",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "MB_DB_FILE",
|
||||
"example": "/metabase-data/metabase.db",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "MB_ENCRYPTION_SECRET_KEY",
|
||||
"example": "${GENERATED_MB_ENCRYPTION_SECRET_KEY}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "MUID",
|
||||
"example": "2000",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "MGID",
|
||||
"example": "2000",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
},
|
||||
{
|
||||
"name": "JAVA_OPTS",
|
||||
"example": "-Xmx1g",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "docker-compose"
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/metabase-data",
|
||||
"compose_source_example": "metabase-data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 3000,
|
||||
"published_example": 3000,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "name: metabase\nservices:\n metabase:\n image: metabase/metabase:v0.64-lts\n restart: unless-stopped\n ports:\n - 3000:3000/tcp\n volumes:\n - metabase-data:/metabase-data\n environment:\n MB_DB_TYPE: h2\n MB_DB_FILE: /metabase-data/metabase.db\n MB_ENCRYPTION_SECRET_KEY: ${GENERATED_MB_ENCRYPTION_SECRET_KEY}\n MUID: '2000'\n MGID: '2000'\n JAVA_OPTS: -Xmx1g\n healthcheck:\n test:\n - CMD-SHELL\n - curl --fail -I http://localhost:3000/api/health || exit 1\n interval: 15s\n timeout: 5s\n retries: 5\n start_period: 180s\nvolumes:\n metabase-data: {}\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "metabase",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "metabase",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "metabase",
|
||||
"image": "metabase/metabase:v0.64-lts",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "metabase/metabase:v0.64-lts",
|
||||
"restart": "unless-stopped",
|
||||
"ports": [
|
||||
"3000:3000/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"metabase-data:/metabase-data"
|
||||
],
|
||||
"environment": {
|
||||
"MB_DB_TYPE": "h2",
|
||||
"MB_DB_FILE": "/metabase-data/metabase.db",
|
||||
"MB_ENCRYPTION_SECRET_KEY": "${GENERATED_MB_ENCRYPTION_SECRET_KEY}",
|
||||
"MUID": "2000",
|
||||
"MGID": "2000",
|
||||
"JAVA_OPTS": "-Xmx1g"
|
||||
},
|
||||
"healthcheck": {
|
||||
"test": [
|
||||
"CMD-SHELL",
|
||||
"curl --fail -I http://localhost:3000/api/health || exit 1"
|
||||
],
|
||||
"interval": "15s",
|
||||
"timeout": "5s",
|
||||
"retries": 5,
|
||||
"start_period": "180s"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "metabase",
|
||||
"volumes": {
|
||||
"metabase-data": {}
|
||||
}
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "metabase-volume-0",
|
||||
"service": "metabase",
|
||||
"container_path": "/metabase-data",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": false,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"metabase"
|
||||
],
|
||||
"stop_order": [
|
||||
"metabase"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "mb-encryption-secret-key",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "metabase",
|
||||
"environment_variable": "MB_ENCRYPTION_SECRET_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Web UI",
|
||||
"scheme": "http",
|
||||
"port": 3000,
|
||||
"path": "/",
|
||||
"source": "compose-metadata"
|
||||
}
|
||||
],
|
||||
"credentials": []
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 2048,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"installer_profile": {
|
||||
"startup_healthcheck": {
|
||||
"type": "http",
|
||||
"scheme": "http",
|
||||
"port": 3000,
|
||||
"path": "/api/health",
|
||||
"timeout_seconds": 300,
|
||||
"request_timeout_seconds": 5,
|
||||
"stability_seconds": 0,
|
||||
"verify_tls": false,
|
||||
"required": true,
|
||||
"source": "compose-healthcheck"
|
||||
},
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/metabase-data",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-application-user",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"volume_owner": {
|
||||
"uid": 2000,
|
||||
"gid": 2000
|
||||
},
|
||||
"generated_sensitive_environment": {
|
||||
"MB_ENCRYPTION_SECRET_KEY": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 32,
|
||||
"prompt": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
]
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,533 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-openhabittracker",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "OpenHabitTracker",
|
||||
"es_ES": "OpenHabitTracker"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "A self-hosted tracker for habits, tasks, notes and goals.",
|
||||
"es_ES": "Seguimiento autoalojado de hábitos, tareas, notas y objetivos."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "The official image includes the Blazor Server application for one user. It persists application data and backups in /app/.OpenHabitTracker.",
|
||||
"es_ES": "La imagen oficial incluye la aplicación Blazor Server para una persona. Guarda los datos y las copias de seguridad en /app/.OpenHabitTracker."
|
||||
},
|
||||
"category": "productivity",
|
||||
"category_label": "Productivity & Workflows",
|
||||
"author": "Jinjinov",
|
||||
"developer": "Jinjinov",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/Jinjinov/OpenHabitTracker@main/OpenHabitTracker.Web/icons/icon-512.png",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/login"
|
||||
},
|
||||
"website": "https://github.com/Jinjinov/OpenHabitTracker",
|
||||
"documentation": "https://github.com/Jinjinov/OpenHabitTracker/blob/main/README.md",
|
||||
"repository": "https://github.com/Jinjinov/OpenHabitTracker",
|
||||
"tips": [
|
||||
"The installer sets the initial username, email and password. Sign in at /login after startup."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "Jinjinov",
|
||||
"repository": "https://github.com/Jinjinov/OpenHabitTracker",
|
||||
"revision": "a285bf78c04ecebf3b3acc701f1776d4da326905",
|
||||
"image_repository_url": "https://hub.docker.com/r/jinjinov/openhabittracker",
|
||||
"readme_pushed_at": "",
|
||||
"default_branch": "main",
|
||||
"compose_sha256": "1405f9aea98cdf7cc414b9c00a13a1b5086cba2de51f3ba6d1d607e48c94a5d8",
|
||||
"generated_at": "2026-10-26T08:45:03+00:00",
|
||||
"readme_raw_url": "https://raw.githubusercontent.com/Jinjinov/OpenHabitTracker/main/README.md"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "openhabittracker",
|
||||
"container_name": "openhabittracker",
|
||||
"image": {
|
||||
"reference": "jinjinov/openhabittracker:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "jinjinov/openhabittracker",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "AppSettings__UserName",
|
||||
"example": "",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt": "OpenHabitTracker initial username"
|
||||
},
|
||||
{
|
||||
"name": "AppSettings__Email",
|
||||
"example": "",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt": "Email address for the OpenHabitTracker account"
|
||||
},
|
||||
{
|
||||
"name": "AppSettings__Password",
|
||||
"example": "${GENERATED_APPSETTINGS_PASSWORD}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"name": "AppSettings__JwtSecret",
|
||||
"example": "${GENERATED_APPSETTINGS_JWT_SECRET}",
|
||||
"required": true,
|
||||
"sensitive": true,
|
||||
"source": "upstream-documentation"
|
||||
},
|
||||
{
|
||||
"name": "TZ",
|
||||
"example": "Europe/Madrid",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "upstream-documentation",
|
||||
"prompt_user": false
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/app/.OpenHabitTracker",
|
||||
"compose_source_example": "data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 8080,
|
||||
"published_example": 8080,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "services:\n openhabittracker:\n image: jinjinov/openhabittracker:latest\n container_name: openhabittracker\n restart: unless-stopped\n ports:\n - 8080:8080/tcp\n volumes:\n - ./data:/app/.OpenHabitTracker\n environment:\n AppSettings__UserName: ${AppSettings__UserName}\n AppSettings__Email: ${AppSettings__Email}\n AppSettings__Password: ${GENERATED_APPSETTINGS_PASSWORD}\n AppSettings__JwtSecret: ${GENERATED_APPSETTINGS_JWT_SECRET}\n TZ: Europe/Madrid\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "openhabittracker",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "openhabittracker",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "openhabittracker",
|
||||
"image": "jinjinov/openhabittracker:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"environment": {
|
||||
"AppSettings__UserName": "${AppSettings__UserName}",
|
||||
"AppSettings__Email": "${AppSettings__Email}",
|
||||
"AppSettings__Password": "${GENERATED_APPSETTINGS_PASSWORD}",
|
||||
"AppSettings__JwtSecret": "${GENERATED_APPSETTINGS_JWT_SECRET}",
|
||||
"TZ": "Europe/Madrid"
|
||||
},
|
||||
"image": "jinjinov/openhabittracker:latest",
|
||||
"ports": [
|
||||
"8080:8080/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"./data:/app/.OpenHabitTracker"
|
||||
],
|
||||
"container_name": "openhabittracker",
|
||||
"restart": "unless-stopped"
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "openhabittracker"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "openhabittracker-volume-0",
|
||||
"service": "openhabittracker",
|
||||
"container_path": "/app/.OpenHabitTracker",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"openhabittracker"
|
||||
],
|
||||
"stop_order": [
|
||||
"openhabittracker"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": [
|
||||
{
|
||||
"id": "generated-appsettings-password",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "openhabittracker",
|
||||
"environment_variable": "AppSettings__Password"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "generated-appsettings-jwtsecret",
|
||||
"strategy": "generate-cryptographically-random-at-install",
|
||||
"bindings": [
|
||||
{
|
||||
"service": "openhabittracker",
|
||||
"environment_variable": "AppSettings__JwtSecret"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "OpenHabitTracker",
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/login",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "OpenHabitTracker account",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "Configured username",
|
||||
"username_environment": "AppSettings__UserName",
|
||||
"password": null,
|
||||
"password_environment": "AppSettings__Password",
|
||||
"change_required": false,
|
||||
"source": "proxmenux-installer-generated",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 512,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/app/.OpenHabitTracker",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-root",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"generated_sensitive_environment": {
|
||||
"AppSettings__Password": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 24,
|
||||
"prompt": false
|
||||
},
|
||||
"AppSettings__JwtSecret": {
|
||||
"strategy": "token-hex",
|
||||
"bytes": 32,
|
||||
"prompt": false
|
||||
}
|
||||
},
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 8080,
|
||||
"path": "/login",
|
||||
"timeout_seconds": 180,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false,
|
||||
"accept_any_status": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-restic-rest-server",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Restic REST Server",
|
||||
"es_ES": "Restic REST Server"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "A REST backend for restic backups; it has no web interface.",
|
||||
"es_ES": "Un backend REST para copias de Restic, sin interfaz web."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "The official rest-server image provides an authenticated HTTP REST backend for restic clients, with persistent repositories and bcrypt-protected user accounts. It exposes an API, not a browser-based application.",
|
||||
"es_ES": "La imagen oficial rest-server ofrece un backend HTTP REST autenticado para clientes Restic, con repositorios persistentes y cuentas protegidas con bcrypt. Expone una API, no una aplicación web."
|
||||
},
|
||||
"category": "backup",
|
||||
"category_label": "Backup & Recovery",
|
||||
"author": "restic",
|
||||
"developer": "restic",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/restic.webp",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": null,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://github.com/restic/rest-server",
|
||||
"documentation": "https://github.com/restic/rest-server",
|
||||
"repository": "https://github.com/restic/rest-server",
|
||||
"tips": [
|
||||
"Authentication stays enabled. Before connecting any backup client, open the container console and run create_user <username>; enter the password at the hidden prompt. Do not pass the password as a command-line argument. The image stores the bcrypt hash in /data/.htpasswd.",
|
||||
"The API has no web interface. Use a restic client with a repository URL that includes the username-specific path, for example rest:http://USER@HOST:8000/USER when private repositories are enabled.",
|
||||
"The upstream default uses HTTP, which sends Basic Authentication credentials in clear text. Use a trusted LAN or route clients through an HTTPS reverse proxy before remote access.",
|
||||
"With --private-repos enabled, each user can access only a matching repository subdirectory. Keep /data persistent; it contains both backups and the authentication file.",
|
||||
"The upstream endpoint uses HTTP. Use an HTTPS reverse proxy for remote clients; the example API URL shown in this entry is HTTP.",
|
||||
"El endpoint original usa HTTP. Para clientes remotos, coloca un proxy HTTPS delante; la URL de ejemplo de esta ficha usa HTTP."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "restic",
|
||||
"repository": "https://github.com/restic/rest-server",
|
||||
"revision": "cfcf3fea23edb404c860e8708e39306717fe3e85",
|
||||
"image_repository_url": "https://hub.docker.com/r/restic/rest-server",
|
||||
"readme_pushed_at": "",
|
||||
"compose_sha256": "f346e67428e1c6e8e265d607401fe5d5289b5c7ad478170abb4984fa8dcb01ad",
|
||||
"generated_at": "2026-10-26T06:50:27+00:00",
|
||||
"readme_raw_url": "https://github.com/restic/rest-server"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "restic-rest-server",
|
||||
"container_name": "restic-rest-server",
|
||||
"image": {
|
||||
"reference": "restic/rest-server:latest",
|
||||
"registry": "docker.io",
|
||||
"repository": "restic/rest-server",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [
|
||||
{
|
||||
"name": "OPTIONS",
|
||||
"example": "--private-repos",
|
||||
"required": true,
|
||||
"sensitive": false,
|
||||
"source": "official-rest-server-documentation",
|
||||
"prompt_user": false
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/data",
|
||||
"compose_source_example": "restic-data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 16
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 8000,
|
||||
"published_example": 8000,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "{\n \"name\": \"restic-rest-server\",\n \"services\": {\n \"restic-rest-server\": {\n \"image\": \"restic/rest-server:latest\",\n \"container_name\": \"restic-rest-server\",\n \"restart\": \"unless-stopped\",\n \"ports\": [\n \"8000:8000/tcp\"\n ],\n \"volumes\": [\n \"restic-data:/data\"\n ],\n \"environment\": {\n \"OPTIONS\": \"--private-repos\"\n }\n }\n },\n \"volumes\": {\n \"restic-data\": {}\n }\n}\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "restic-rest-server",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "restic-rest-server",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "restic-rest-server",
|
||||
"image": "restic/rest-server:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "restic/rest-server:latest",
|
||||
"container_name": "restic-rest-server",
|
||||
"restart": "unless-stopped",
|
||||
"ports": [
|
||||
"8000:8000/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"restic-data:/data"
|
||||
],
|
||||
"environment": {
|
||||
"OPTIONS": "--private-repos"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "restic-rest-server",
|
||||
"volumes": {
|
||||
"restic-data": {}
|
||||
}
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "restic-rest-server-volume-0",
|
||||
"service": "restic-rest-server",
|
||||
"container_path": "/data",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"restic-rest-server"
|
||||
],
|
||||
"stop_order": [
|
||||
"restic-rest-server"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": []
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "REST API Basic Authentication user",
|
||||
"username": "Create with create_user in the container console",
|
||||
"password": null,
|
||||
"change_required": false,
|
||||
"source": "official-rest-server-documentation",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 1,
|
||||
"memory_mb": 512,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 120
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "The Compose definition publishes service ports on its Docker host.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the image service ports and exposes them on this LXC address without Docker port NAT.",
|
||||
"reason": "The application runs in its own Proxmox LXC network namespace.",
|
||||
"behavioral_impact": "Connect to the LXC address and the service port shown in the install summary.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose provides the command that starts the service.",
|
||||
"native_lxc_behavior": "ProxMenux imports the image entrypoint and applies the reviewed command as the native OCI process.",
|
||||
"reason": "The image runs directly as a native OCI LXC process.",
|
||||
"behavioral_impact": "The process starts with the upstream server command.",
|
||||
"validation": "pending-per-application"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 8000,
|
||||
"path": "/",
|
||||
"timeout_seconds": 120,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false,
|
||||
"accept_any_status": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"command",
|
||||
"container_name",
|
||||
"environment",
|
||||
"hostname",
|
||||
"image",
|
||||
"ports",
|
||||
"restart",
|
||||
"volumes"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "The single upstream image runs as a native Proxmox OCI LXC. Only the documented image command, environment, ports and persistent paths are translated."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,453 @@
|
||||
{
|
||||
"schema_version": "0.5.0",
|
||||
"kind": "proxmenux.oci-template",
|
||||
"id": "image-watcharr",
|
||||
"status": "generated-unvalidated",
|
||||
"catalog_ui": {
|
||||
"title": {
|
||||
"en_US": "Watcharr",
|
||||
"es_ES": "Watcharr"
|
||||
},
|
||||
"tagline": {
|
||||
"en_US": "Track movies, television, anime and games you want to enjoy.",
|
||||
"es_ES": "Lleva un registro de películas, series, anime y videojuegos."
|
||||
},
|
||||
"description": {
|
||||
"en_US": "Track movies, television shows, anime and games you want to watch or play. The single container stores its database and cache in /data.",
|
||||
"es_ES": "Haz seguimiento de películas, series, anime y juegos que quieres ver o jugar. El contenedor guarda la base de datos y la caché en /data."
|
||||
},
|
||||
"category": "media",
|
||||
"category_label": "Media & Streaming",
|
||||
"author": "sbondCo",
|
||||
"developer": "sbondCo",
|
||||
"icon": "https://raw.githubusercontent.com/sbondCo/Watcharr/dev/doc/static/img/logo-col.png",
|
||||
"thumbnail": null,
|
||||
"screenshots": [],
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"launch": {
|
||||
"scheme": "http",
|
||||
"port": 3080,
|
||||
"path": "/"
|
||||
},
|
||||
"website": "https://watcharr.app/",
|
||||
"documentation": "https://watcharr.app/docs/installation/docker-compose",
|
||||
"repository": "https://github.com/sbondCo/Watcharr",
|
||||
"tips": [
|
||||
"The first account created becomes the administrator. Keep access limited to your trusted network until initial setup is complete."
|
||||
],
|
||||
"mini_changelog": [],
|
||||
"display_version": null,
|
||||
"updated_at": null
|
||||
},
|
||||
"source": {
|
||||
"provider": "sbondCo",
|
||||
"repository": "https://github.com/sbondCo/Watcharr",
|
||||
"revision": "aa2a765788a4d0f6eb607e7f90acb0d89d62fcd7",
|
||||
"image_repository_url": "https://github.com/orgs/sbondco/packages/container/package/watcharr",
|
||||
"readme_pushed_at": "",
|
||||
"default_branch": "dev",
|
||||
"compose_sha256": "8c4aa4fc5f19e33730685e75e89a7d6a79253bc3ea7ebd6ea6e27e0981fe5f54",
|
||||
"generated_at": "2026-10-26T08:45:03+00:00",
|
||||
"readme_raw_url": "https://raw.githubusercontent.com/sbondCo/Watcharr/dev/README.md"
|
||||
},
|
||||
"container_contract": {
|
||||
"service_name": "watcharr",
|
||||
"container_name": "watcharr",
|
||||
"image": {
|
||||
"reference": "ghcr.io/sbondco/watcharr:latest",
|
||||
"registry": "ghcr.io",
|
||||
"repository": "ghcr.io/sbondco/watcharr",
|
||||
"tag": "latest",
|
||||
"digest": null,
|
||||
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
|
||||
},
|
||||
"environment": [],
|
||||
"volumes": [
|
||||
{
|
||||
"id": "volume-0",
|
||||
"container_path": "/data",
|
||||
"compose_source_example": "data",
|
||||
"read_only": false,
|
||||
"required": true,
|
||||
"installation_choice": [
|
||||
"managed-volume",
|
||||
"host-bind"
|
||||
],
|
||||
"default": "managed-volume",
|
||||
"managed_volume": {
|
||||
"backup": true,
|
||||
"default_size_gb": 8
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 3080,
|
||||
"published_example": 3080,
|
||||
"protocol": "tcp",
|
||||
"required": true,
|
||||
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
|
||||
}
|
||||
],
|
||||
"related_services": [],
|
||||
"restart": "unless-stopped",
|
||||
"stop_grace_period": null,
|
||||
"original_compose": "services:\n watcharr:\n image: ghcr.io/sbondco/watcharr:latest\n container_name: watcharr\n restart: unless-stopped\n ports:\n - 3080:3080/tcp\n volumes:\n - ./data:/data\n environment: {}\n"
|
||||
},
|
||||
"compose_stack": {
|
||||
"project_name": "watcharr",
|
||||
"deployment_model": "one-native-oci-lxc-per-compose-service",
|
||||
"user_experience": "single-application-install",
|
||||
"main_service": "watcharr",
|
||||
"service_count": 1,
|
||||
"services": [
|
||||
{
|
||||
"name": "watcharr",
|
||||
"image": "ghcr.io/sbondco/watcharr:latest",
|
||||
"is_main": true,
|
||||
"role": "frontend",
|
||||
"vmid_offset": 0,
|
||||
"depends_on": [],
|
||||
"frontend_network": true,
|
||||
"private_network": false,
|
||||
"compose": {
|
||||
"image": "ghcr.io/sbondco/watcharr:latest",
|
||||
"ports": [
|
||||
"3080:3080/tcp"
|
||||
],
|
||||
"volumes": [
|
||||
"./data:/data"
|
||||
],
|
||||
"container_name": "watcharr",
|
||||
"restart": "unless-stopped",
|
||||
"environment": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"top_level": {
|
||||
"name": "watcharr"
|
||||
},
|
||||
"networking": {
|
||||
"frontend": "selected-proxmox-bridge",
|
||||
"private_required": false,
|
||||
"private_creation": "automatic-create-if-missing",
|
||||
"private_address_allocation": "automatic-static-address-per-service",
|
||||
"service_discovery": "private-addresses-with-compose-service-host-aliases",
|
||||
"dependency_external_access": "disabled-unless-service-publishes-ports",
|
||||
"prompt_user_for_private_network": false
|
||||
},
|
||||
"storage": [
|
||||
{
|
||||
"id": "watcharr-volume-0",
|
||||
"service": "watcharr",
|
||||
"container_path": "/data",
|
||||
"mode": "managed-volume",
|
||||
"user_selectable": true,
|
||||
"backup": true,
|
||||
"shared_with_other_lxc": false,
|
||||
"source_path": null,
|
||||
"source_path_prompt": null
|
||||
}
|
||||
],
|
||||
"orchestration": {
|
||||
"reserve_vmids_atomically": 1,
|
||||
"start_order": [
|
||||
"watcharr"
|
||||
],
|
||||
"stop_order": [
|
||||
"watcharr"
|
||||
],
|
||||
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
|
||||
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
|
||||
},
|
||||
"installer_inputs": {
|
||||
"prompted": [
|
||||
"stack_name",
|
||||
"base_vmid",
|
||||
"rootfs_storage",
|
||||
"persistent_data_destinations",
|
||||
"frontend_bridge",
|
||||
"frontend_ipv4_mode"
|
||||
],
|
||||
"automatic": [
|
||||
"dependent_vmids",
|
||||
"private_bridge",
|
||||
"private_subnet",
|
||||
"private_service_addresses",
|
||||
"compose_service_aliases",
|
||||
"generated_secrets",
|
||||
"dependency_start_and_stop_order"
|
||||
],
|
||||
"generated_secrets": []
|
||||
}
|
||||
},
|
||||
"first_run": {
|
||||
"endpoints": [
|
||||
{
|
||||
"label": "Watcharr",
|
||||
"scheme": "http",
|
||||
"port": 3080,
|
||||
"path": "/",
|
||||
"source": "upstream-documentation"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"label": "First Watcharr account (becomes administrator)",
|
||||
"type": "configured-or-installer-generated",
|
||||
"username": "Created during first-run setup",
|
||||
"password": null,
|
||||
"change_required": false,
|
||||
"source": "upstream-documentation",
|
||||
"retrieval": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"proxmox": {
|
||||
"runtime": "native-oci-lxc",
|
||||
"technology_status": "proxmox-technology-preview",
|
||||
"defaults": {
|
||||
"unprivileged": true,
|
||||
"ostype": "auto-from-image",
|
||||
"cores": 2,
|
||||
"memory_mb": 512,
|
||||
"swap_mb": 512,
|
||||
"rootfs_size_gb": 8,
|
||||
"rootfs_storage": "local-lvm",
|
||||
"volume_storage": "local-lvm",
|
||||
"template_storage": "local",
|
||||
"bridge": "vmbr0",
|
||||
"ipv4": "dhcp",
|
||||
"firewall": true,
|
||||
"host_managed_network": true,
|
||||
"onboot": false,
|
||||
"features": [
|
||||
"nesting=1"
|
||||
],
|
||||
"shutdown_timeout_seconds": 30
|
||||
},
|
||||
"image_metadata_policy": {
|
||||
"entrypoint": "import-from-oci-image",
|
||||
"cmd": "import-from-oci-image",
|
||||
"environment": "import-image-env-then-apply-compose-overrides",
|
||||
"user": "import-from-oci-image",
|
||||
"working_dir": "import-from-oci-image",
|
||||
"stop_signal": "import-from-oci-image"
|
||||
},
|
||||
"adaptations": [
|
||||
{
|
||||
"id": "imported-compose-source",
|
||||
"upstream_behavior": "The source definition deploys the complete Docker Compose application model.",
|
||||
"native_lxc_behavior": "The source model is preserved and remains blocked until every service option has a reviewed native Proxmox mapping.",
|
||||
"reason": "Catalog import must not imply runtime compatibility.",
|
||||
"behavioral_impact": "No automatic installation before review.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "rolling-latest-image",
|
||||
"upstream_behavior": "A discovered Compose may pin a release tag or digest.",
|
||||
"native_lxc_behavior": "ProxMenux selects the same image repository with the latest tag for catalog installations.",
|
||||
"reason": "The automatic catalog intentionally offers rolling latest images; pinned versions belong to the future manual installer.",
|
||||
"behavioral_impact": "The installed release can be newer than the discovered Compose revision.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "dedicated-lxc-network",
|
||||
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
|
||||
"native_lxc_behavior": "A reviewed native application will listen on its original container ports at a dedicated LXC address.",
|
||||
"reason": "A native LXC has its own address and does not require Docker port NAT.",
|
||||
"behavioral_impact": "Published ports are metadata; ProxMenux URLs use the matching container target port.",
|
||||
"validation": "pending-per-application"
|
||||
},
|
||||
{
|
||||
"id": "compose-shm-size",
|
||||
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
|
||||
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
|
||||
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-command",
|
||||
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
|
||||
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
|
||||
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
|
||||
"behavioral_impact": "None expected.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-privileged-mode",
|
||||
"upstream_behavior": "Compose selects whether the container runs in privileged mode.",
|
||||
"native_lxc_behavior": "ProxMenux keeps the LXC unprivileged by default and exposes the broad Compose privilege request only as an explicit compatibility option.",
|
||||
"reason": "A Compose privilege request is source metadata, not proof that the image technically requires a privileged LXC.",
|
||||
"behavioral_impact": "A privileged LXC has weaker isolation from the Proxmox host.",
|
||||
"validation": "native-equivalent"
|
||||
},
|
||||
{
|
||||
"id": "compose-process-runtime",
|
||||
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
|
||||
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
|
||||
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
|
||||
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-healthcheck",
|
||||
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
|
||||
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
|
||||
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
|
||||
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-cpu-priority",
|
||||
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
|
||||
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
|
||||
"reason": "Both settings express relative CPU priority on different scales.",
|
||||
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-resource-limits",
|
||||
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
|
||||
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
|
||||
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
|
||||
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-identity",
|
||||
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
|
||||
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
|
||||
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
|
||||
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-network-mode",
|
||||
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
|
||||
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
|
||||
"reason": "The LXC is the application host and already has its own address and port namespace.",
|
||||
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-capabilities-and-sysctls",
|
||||
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
|
||||
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
|
||||
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
|
||||
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "docker-engine-metadata",
|
||||
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
|
||||
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
|
||||
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
|
||||
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-device-passthrough",
|
||||
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
|
||||
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
|
||||
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
|
||||
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
|
||||
"validation": "not-requested-by-compose"
|
||||
},
|
||||
{
|
||||
"id": "compose-host-ipc",
|
||||
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
|
||||
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
|
||||
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
|
||||
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
|
||||
"validation": "not-requested-by-compose"
|
||||
}
|
||||
],
|
||||
"installer_profile": {
|
||||
"volume_preparations": [
|
||||
{
|
||||
"container_path": "/data",
|
||||
"remove_lost_found": true,
|
||||
"owner_strategy": "mapped-root",
|
||||
"only_when_mount_type": "managed-volume"
|
||||
}
|
||||
],
|
||||
"startup_healthcheck": {
|
||||
"scheme": "http",
|
||||
"port": 3080,
|
||||
"path": "/",
|
||||
"timeout_seconds": 180,
|
||||
"request_timeout_seconds": 10,
|
||||
"stability_seconds": 3,
|
||||
"verify_tls": false,
|
||||
"accept_any_status": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"automatic_install_candidate": true,
|
||||
"validated": false,
|
||||
"supported_compose_keys": [
|
||||
"cap_add",
|
||||
"command",
|
||||
"container_name",
|
||||
"cpu_shares",
|
||||
"deploy",
|
||||
"devices",
|
||||
"entrypoint",
|
||||
"environment",
|
||||
"extra_hosts",
|
||||
"group_add",
|
||||
"healthcheck",
|
||||
"hostname",
|
||||
"image",
|
||||
"init",
|
||||
"ipc",
|
||||
"labels",
|
||||
"logging",
|
||||
"mac_address",
|
||||
"mem_limit",
|
||||
"network_mode",
|
||||
"networks",
|
||||
"ports",
|
||||
"privileged",
|
||||
"restart",
|
||||
"runtime",
|
||||
"security_opt",
|
||||
"shm_size",
|
||||
"stdin_open",
|
||||
"stop_grace_period",
|
||||
"sysctls",
|
||||
"tty",
|
||||
"ulimits",
|
||||
"user",
|
||||
"volumes",
|
||||
"working_dir"
|
||||
],
|
||||
"untranslated_blockers": [],
|
||||
"policy": "Single-image definitions are installable when every declared Compose option has a native Proxmox translation. Multi-image and unsupported runtime features remain blocked until their orchestrator or mapping is available."
|
||||
},
|
||||
"validation": {
|
||||
"schema": "passed-at-generation",
|
||||
"clean_install": "pending",
|
||||
"service_health": "pending",
|
||||
"restart_persistence": "pending",
|
||||
"backup_restore": "pending",
|
||||
"update_preserves_data": "pending"
|
||||
},
|
||||
"lifecycle": {
|
||||
"update_strategy": "resolve-latest-image-then-apply-reviewed-native-lxc-update",
|
||||
"registry_state": {
|
||||
"resolved_architecture": null,
|
||||
"resolved_digest": null,
|
||||
"image_version_label": null,
|
||||
"image_created": null
|
||||
},
|
||||
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
|
||||
"automatic_unattended_updates": false
|
||||
}
|
||||
}
|
||||
@@ -71,6 +71,37 @@
|
||||
"hidden": false,
|
||||
"template_id": "image-acestream-http-proxy"
|
||||
},
|
||||
{
|
||||
"id": "activepieces",
|
||||
"provider": "activepieces",
|
||||
"template_family": "curated-profile",
|
||||
"title": "Activepieces",
|
||||
"repository": "https://github.com/activepieces/activepieces",
|
||||
"description": "Build and run automation flows from a self-hosted visual interface. This single-container profile uses Activepieces\u2019 documented personal mode with embedded storage and an in-memory queue.",
|
||||
"website": "https://www.activepieces.com/",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/activepieces.webp",
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"updated_at": null,
|
||||
"main_image": "ghcr.io/activepieces/activepieces:latest",
|
||||
"category": "automation",
|
||||
"category_label": "Automation & Scheduling",
|
||||
"replaces_discovered_ids": [],
|
||||
"curated_path": "catalog/curated/activepieces.json",
|
||||
"template_id": "image-activepieces",
|
||||
"template": "apps/activepieces.json",
|
||||
"template_status": "generated-unvalidated",
|
||||
"automatic_install_candidate": true,
|
||||
"requires_privileged_lxc": false,
|
||||
"optional_privileged_lxc": false,
|
||||
"requires_host_pid_namespace": false,
|
||||
"requires_relaxed_confinement": false,
|
||||
"requires_security_confirmation": false,
|
||||
"hidden": false,
|
||||
"untranslated_blockers": []
|
||||
},
|
||||
{
|
||||
"id": "actualbudget",
|
||||
"source_app_id": "actualbudget",
|
||||
@@ -1439,6 +1470,38 @@
|
||||
"hidden": false,
|
||||
"template_id": "linuxserver-budge"
|
||||
},
|
||||
{
|
||||
"id": "bytebase",
|
||||
"provider": "Bytebase",
|
||||
"template_family": "curated-profile",
|
||||
"title": "Bytebase",
|
||||
"repository": "https://github.com/bytebase/bytebase",
|
||||
"description": "Manage database changes, access and workflows through a browser-based workspace. The image contains its own database, so this profile does not require a second service.",
|
||||
"website": "https://www.bytebase.com/",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/bytebase/bytebase@main/frontend/src/assets/logo-icon.svg",
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"updated_at": null,
|
||||
"main_image": "bytebase/bytebase:latest",
|
||||
"category": "databases",
|
||||
"category_label": "Databases",
|
||||
"replaces_discovered_ids": [],
|
||||
"curated_path": "catalog/curated/bytebase.json",
|
||||
"template": "apps/bytebase.json",
|
||||
"template_status": "generated-unvalidated",
|
||||
"automatic_install_candidate": true,
|
||||
"untranslated_blockers": [],
|
||||
"requires_privileged_lxc": false,
|
||||
"optional_privileged_lxc": false,
|
||||
"requires_host_pid_namespace": false,
|
||||
"requires_relaxed_confinement": false,
|
||||
"optional_relaxed_confinement": false,
|
||||
"requires_security_confirmation": false,
|
||||
"hidden": false,
|
||||
"template_id": "image-bytebase"
|
||||
},
|
||||
{
|
||||
"id": "caddy",
|
||||
"provider": "caddyserver",
|
||||
@@ -1599,6 +1662,39 @@
|
||||
"hidden": false,
|
||||
"template_id": "image-calnode"
|
||||
},
|
||||
{
|
||||
"id": "campfire",
|
||||
"provider": "AwsomeFox",
|
||||
"template_family": "curated-profile",
|
||||
"title": "Campfire",
|
||||
"repository": "https://github.com/AwsomeFox/campfire",
|
||||
"description": "A self-hosted web application for organizing tabletop role-playing games.",
|
||||
"website": "https://github.com/AwsomeFox/campfire",
|
||||
"icon": "https://raw.githubusercontent.com/AwsomeFox/campfire/main/apps/web/public/pwa-512x512.png",
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"updated_at": null,
|
||||
"main_image": "ghcr.io/awsomefox/campfire:latest",
|
||||
"category": "gaming",
|
||||
"category_label": "Gaming & Leisure",
|
||||
"replaces_discovered_ids": [],
|
||||
"curated_path": "catalog/curated/campfire.json",
|
||||
"template": "apps/campfire.json",
|
||||
"template_status": "generated-unvalidated",
|
||||
"hidden": false,
|
||||
"automatic_install_candidate": true,
|
||||
"untranslated_blockers": [],
|
||||
"requires_privileged_lxc": false,
|
||||
"optional_privileged_lxc": false,
|
||||
"requires_host_pid_namespace": false,
|
||||
"requires_relaxed_confinement": false,
|
||||
"optional_relaxed_confinement": false,
|
||||
"requires_security_confirmation": false,
|
||||
"multi_container": false,
|
||||
"template_id": "image-campfire"
|
||||
},
|
||||
{
|
||||
"id": "changedetection.io",
|
||||
"provider": "linuxserver.io",
|
||||
@@ -1735,6 +1831,38 @@
|
||||
"hidden": false,
|
||||
"template_id": "image-chatgpt-next-web"
|
||||
},
|
||||
{
|
||||
"id": "chhoto-url",
|
||||
"provider": "sintan1729",
|
||||
"template_family": "curated-profile",
|
||||
"title": "Chhoto URL",
|
||||
"repository": "https://github.com/SinTan1729/chhoto-url",
|
||||
"description": "Create and manage short links from a small web interface. Chhoto URL stores its link database in SQLite and supports password-protected administration without a separate database service.",
|
||||
"website": "https://github.com/SinTan1729/chhoto-url",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/chhoto-url.webp",
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"updated_at": null,
|
||||
"main_image": "sintan1729/chhoto-url:latest",
|
||||
"category": "tools",
|
||||
"category_label": "Tools",
|
||||
"replaces_discovered_ids": [],
|
||||
"curated_path": "catalog/curated/chhoto-url.json",
|
||||
"template": "apps/chhoto-url.json",
|
||||
"template_status": "generated-unvalidated",
|
||||
"automatic_install_candidate": true,
|
||||
"untranslated_blockers": [],
|
||||
"requires_privileged_lxc": false,
|
||||
"optional_privileged_lxc": false,
|
||||
"requires_host_pid_namespace": false,
|
||||
"requires_relaxed_confinement": false,
|
||||
"optional_relaxed_confinement": false,
|
||||
"requires_security_confirmation": false,
|
||||
"multi_container": false,
|
||||
"template_id": "image-chhoto-url"
|
||||
},
|
||||
{
|
||||
"id": "chrome",
|
||||
"provider": "linuxserver.io",
|
||||
@@ -3668,6 +3796,38 @@
|
||||
"hidden": false,
|
||||
"template_id": "image-duplicati-official"
|
||||
},
|
||||
{
|
||||
"id": "ech0",
|
||||
"provider": "lin-snow",
|
||||
"template_family": "curated-profile",
|
||||
"title": "Ech0",
|
||||
"repository": "https://github.com/lin-snow/Ech0",
|
||||
"description": "Publish short posts, links and media on a personal timeline that you control. Ech0 includes accounts, comments, RSS and local data storage in one lightweight service.",
|
||||
"website": "https://www.ech0.app/",
|
||||
"icon": "https://raw.githubusercontent.com/lin-snow/Ech0/main/docs/imgs/logo.svg",
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"updated_at": null,
|
||||
"main_image": "sn0wl1n/ech0:latest",
|
||||
"category": "communication",
|
||||
"category_label": "Communication & Community",
|
||||
"replaces_discovered_ids": [],
|
||||
"curated_path": "catalog/curated/ech0.json",
|
||||
"template": "apps/ech0.json",
|
||||
"template_status": "generated-unvalidated",
|
||||
"automatic_install_candidate": true,
|
||||
"untranslated_blockers": [],
|
||||
"requires_privileged_lxc": false,
|
||||
"optional_privileged_lxc": false,
|
||||
"requires_host_pid_namespace": false,
|
||||
"requires_relaxed_confinement": false,
|
||||
"optional_relaxed_confinement": false,
|
||||
"requires_security_confirmation": false,
|
||||
"multi_container": false,
|
||||
"template_id": "image-ech0"
|
||||
},
|
||||
{
|
||||
"id": "eden",
|
||||
"provider": "linuxserver.io",
|
||||
@@ -7629,6 +7789,38 @@
|
||||
"hidden": false,
|
||||
"template_id": "image-komga"
|
||||
},
|
||||
{
|
||||
"id": "kopia",
|
||||
"provider": "kopia",
|
||||
"template_family": "curated-profile",
|
||||
"title": "Kopia",
|
||||
"repository": "https://github.com/kopia/kopia",
|
||||
"description": "Kopia provides encrypted, deduplicated backups with a web interface for repositories, policies, snapshots and restores. This profile supports browsing and restoring files through the UI; mounting snapshots with FUSE is not enabled.",
|
||||
"website": "https://github.com/kopia/kopia",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/kopia.webp",
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"updated_at": null,
|
||||
"main_image": "kopia/kopia:latest",
|
||||
"category": "backup",
|
||||
"category_label": "Backup & Recovery",
|
||||
"replaces_discovered_ids": [],
|
||||
"curated_path": "catalog/curated/kopia.json",
|
||||
"template": "apps/kopia.json",
|
||||
"template_status": "generated-unvalidated",
|
||||
"automatic_install_candidate": true,
|
||||
"untranslated_blockers": [],
|
||||
"requires_privileged_lxc": false,
|
||||
"optional_privileged_lxc": false,
|
||||
"requires_host_pid_namespace": false,
|
||||
"requires_relaxed_confinement": false,
|
||||
"optional_relaxed_confinement": false,
|
||||
"requires_security_confirmation": false,
|
||||
"hidden": false,
|
||||
"template_id": "image-kopia"
|
||||
},
|
||||
{
|
||||
"id": "krita",
|
||||
"provider": "linuxserver.io",
|
||||
@@ -9320,6 +9512,38 @@
|
||||
"multi_container": false,
|
||||
"template_id": "image-meshcentral"
|
||||
},
|
||||
{
|
||||
"id": "metabase",
|
||||
"provider": "metabase",
|
||||
"template_family": "curated-profile",
|
||||
"title": "Metabase",
|
||||
"repository": "https://github.com/metabase/metabase",
|
||||
"description": "An open-source business intelligence platform for querying data and building dashboards. This single-container profile uses embedded H2 for a home-lab trial or small instance; PostgreSQL is recommended for production.",
|
||||
"website": "https://www.metabase.com/",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/metabase.webp",
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"updated_at": null,
|
||||
"main_image": "metabase/metabase:v0.64-lts",
|
||||
"category": "monitoring",
|
||||
"category_label": "Monitoring & Analytics",
|
||||
"replaces_discovered_ids": [],
|
||||
"curated_path": "catalog/curated/metabase.json",
|
||||
"template": "apps/metabase.json",
|
||||
"template_status": "generated-unvalidated",
|
||||
"automatic_install_candidate": true,
|
||||
"untranslated_blockers": [],
|
||||
"requires_privileged_lxc": false,
|
||||
"optional_privileged_lxc": false,
|
||||
"requires_host_pid_namespace": false,
|
||||
"requires_relaxed_confinement": false,
|
||||
"optional_relaxed_confinement": false,
|
||||
"requires_security_confirmation": false,
|
||||
"hidden": false,
|
||||
"template_id": "image-metabase"
|
||||
},
|
||||
{
|
||||
"id": "metube",
|
||||
"provider": "alexta69",
|
||||
@@ -11210,6 +11434,38 @@
|
||||
"hidden": false,
|
||||
"template_id": "image-openhab"
|
||||
},
|
||||
{
|
||||
"id": "openhabittracker",
|
||||
"provider": "Jinjinov",
|
||||
"template_family": "curated-profile",
|
||||
"title": "OpenHabitTracker",
|
||||
"repository": "https://github.com/Jinjinov/OpenHabitTracker",
|
||||
"description": "The official image includes the Blazor Server application for one user. It persists application data and backups in /app/.OpenHabitTracker.",
|
||||
"website": "https://github.com/Jinjinov/OpenHabitTracker",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/Jinjinov/OpenHabitTracker@main/OpenHabitTracker.Web/icons/icon-512.png",
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"updated_at": null,
|
||||
"main_image": "jinjinov/openhabittracker:latest",
|
||||
"category": "productivity",
|
||||
"category_label": "Productivity & Workflows",
|
||||
"replaces_discovered_ids": [],
|
||||
"curated_path": "catalog/curated/openhabittracker.json",
|
||||
"template": "apps/openhabittracker.json",
|
||||
"template_status": "generated-unvalidated",
|
||||
"automatic_install_candidate": true,
|
||||
"untranslated_blockers": [],
|
||||
"requires_privileged_lxc": false,
|
||||
"optional_privileged_lxc": false,
|
||||
"requires_host_pid_namespace": false,
|
||||
"requires_relaxed_confinement": false,
|
||||
"optional_relaxed_confinement": false,
|
||||
"requires_security_confirmation": false,
|
||||
"multi_container": false,
|
||||
"template_id": "image-openhabittracker"
|
||||
},
|
||||
{
|
||||
"id": "openhands",
|
||||
"source_app_id": "openhands",
|
||||
@@ -13732,6 +13988,38 @@
|
||||
"hidden": false,
|
||||
"template_id": "linuxserver-resilio-sync"
|
||||
},
|
||||
{
|
||||
"id": "restic-rest-server",
|
||||
"provider": "restic",
|
||||
"template_family": "curated-profile",
|
||||
"title": "Restic REST Server",
|
||||
"repository": "https://github.com/restic/rest-server",
|
||||
"description": "The official rest-server image provides an authenticated HTTP REST backend for restic clients, with persistent repositories and bcrypt-protected user accounts. It exposes an API, not a browser-based application.",
|
||||
"website": "https://github.com/restic/rest-server",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/restic.webp",
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"updated_at": null,
|
||||
"main_image": "restic/rest-server:latest",
|
||||
"category": "backup",
|
||||
"category_label": "Backup & Recovery",
|
||||
"replaces_discovered_ids": [],
|
||||
"curated_path": "catalog/curated/restic-rest-server.json",
|
||||
"template": "apps/restic-rest-server.json",
|
||||
"template_status": "generated-unvalidated",
|
||||
"automatic_install_candidate": true,
|
||||
"untranslated_blockers": [],
|
||||
"requires_privileged_lxc": false,
|
||||
"optional_privileged_lxc": false,
|
||||
"requires_host_pid_namespace": false,
|
||||
"requires_relaxed_confinement": false,
|
||||
"optional_relaxed_confinement": false,
|
||||
"requires_security_confirmation": false,
|
||||
"hidden": false,
|
||||
"template_id": "image-restic-rest-server"
|
||||
},
|
||||
{
|
||||
"id": "retroarch",
|
||||
"provider": "linuxserver.io",
|
||||
@@ -17233,6 +17521,38 @@
|
||||
"hidden": false,
|
||||
"template_id": "image-wallos"
|
||||
},
|
||||
{
|
||||
"id": "watcharr",
|
||||
"provider": "sbondCo",
|
||||
"template_family": "curated-profile",
|
||||
"title": "Watcharr",
|
||||
"repository": "https://github.com/sbondCo/Watcharr",
|
||||
"description": "Track movies, television shows, anime and games you want to watch or play. The single container stores its database and cache in /data.",
|
||||
"website": "https://watcharr.app/",
|
||||
"icon": "https://raw.githubusercontent.com/sbondCo/Watcharr/dev/doc/static/img/logo-col.png",
|
||||
"architectures": [
|
||||
"amd64",
|
||||
"arm64"
|
||||
],
|
||||
"updated_at": null,
|
||||
"main_image": "ghcr.io/sbondco/watcharr:latest",
|
||||
"category": "media",
|
||||
"category_label": "Media & Streaming",
|
||||
"replaces_discovered_ids": [],
|
||||
"curated_path": "catalog/curated/watcharr.json",
|
||||
"template": "apps/watcharr.json",
|
||||
"template_status": "generated-unvalidated",
|
||||
"automatic_install_candidate": true,
|
||||
"untranslated_blockers": [],
|
||||
"requires_privileged_lxc": false,
|
||||
"optional_privileged_lxc": false,
|
||||
"requires_host_pid_namespace": false,
|
||||
"requires_relaxed_confinement": false,
|
||||
"optional_relaxed_confinement": false,
|
||||
"requires_security_confirmation": false,
|
||||
"multi_container": false,
|
||||
"template_id": "image-watcharr"
|
||||
},
|
||||
{
|
||||
"id": "wbo",
|
||||
"provider": "lovasoa",
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
"""Guard the Campfire recipe contract in the next-10 catalog profiles."""
|
||||
import json
|
||||
from pathlib import Path
|
||||
import unittest
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
EXPECTED_IMAGE = "ghcr.io/awsomefox/campfire:latest"
|
||||
EXPECTED_ICON = (
|
||||
"https://raw.githubusercontent.com/AwsomeFox/campfire/main/"
|
||||
"apps/web/public/pwa-512x512.png"
|
||||
)
|
||||
|
||||
|
||||
class CampfireProfileTests(unittest.TestCase):
|
||||
def test_app_and_curated_profiles_match_the_single_service_contract(self):
|
||||
for family in ("apps", "curated"):
|
||||
with self.subTest(family=family):
|
||||
template = json.loads(
|
||||
(ROOT / "catalog" / family / "campfire.json")
|
||||
.read_text(encoding="utf-8")
|
||||
)
|
||||
|
||||
contract = template["container_contract"]
|
||||
stack = template["compose_stack"]
|
||||
self.assertEqual(contract["image"]["reference"], EXPECTED_IMAGE)
|
||||
self.assertEqual(stack["service_count"], 1)
|
||||
self.assertEqual(len(stack["services"]), 1)
|
||||
service = stack["services"][0]
|
||||
self.assertEqual(service["image"], EXPECTED_IMAGE)
|
||||
self.assertEqual(service["compose"]["image"], EXPECTED_IMAGE)
|
||||
|
||||
volume_paths = {
|
||||
volume["container_path"] for volume in contract["volumes"]
|
||||
}
|
||||
self.assertIn("/data", volume_paths)
|
||||
self.assertIn("./data-0:/data", service["compose"]["volumes"])
|
||||
|
||||
setup = next(
|
||||
endpoint for endpoint in template["first_run"]["endpoints"]
|
||||
if endpoint["label"] == "Campfire first-run setup"
|
||||
)
|
||||
self.assertEqual(setup["path"], "/auth/setup")
|
||||
|
||||
healthcheck = template["proxmox"]["installer_profile"][
|
||||
"startup_healthcheck"
|
||||
]
|
||||
self.assertEqual(healthcheck["path"], "/readyz")
|
||||
|
||||
self.assertEqual(template["catalog_ui"]["icon"], EXPECTED_ICON)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,156 @@
|
||||
"""Static install contracts for the next OCI catalog profiles."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
import unittest
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
PROFILES = {
|
||||
"chhoto-url": {
|
||||
"image": "sintan1729/chhoto-url:latest",
|
||||
"data_path": "/data",
|
||||
"port": 4567,
|
||||
"health_path": "/",
|
||||
},
|
||||
"openhabittracker": {
|
||||
"image": "jinjinov/openhabittracker:latest",
|
||||
"data_path": "/app/.OpenHabitTracker",
|
||||
"port": 8080,
|
||||
"health_path": "/login",
|
||||
},
|
||||
"watcharr": {
|
||||
"image": "ghcr.io/sbondco/watcharr:latest",
|
||||
"data_path": "/data",
|
||||
"port": 3080,
|
||||
"health_path": "/",
|
||||
},
|
||||
"ech0": {
|
||||
"image": "sn0wl1n/ech0:latest",
|
||||
"data_path": "/app/data",
|
||||
"port": 6277,
|
||||
"health_path": "/",
|
||||
},
|
||||
"restic-rest-server": {
|
||||
"image": "restic/rest-server:latest",
|
||||
"data_path": "/data",
|
||||
"port": 8000,
|
||||
"health_path": "/",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def load_profile(app_id):
|
||||
path = ROOT / "catalog" / "apps" / f"{app_id}.json"
|
||||
return json.loads(path.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
class Next10BProfiles(unittest.TestCase):
|
||||
def test_each_profile_is_one_image_with_an_icon_and_persistent_data(self):
|
||||
for app_id, expected in PROFILES.items():
|
||||
with self.subTest(app=app_id):
|
||||
profile = load_profile(app_id)
|
||||
services = profile["compose_stack"]["services"]
|
||||
image = profile["container_contract"]["image"]["reference"]
|
||||
|
||||
self.assertEqual(profile["compose_stack"]["service_count"], 1)
|
||||
self.assertEqual(len(services), 1)
|
||||
self.assertEqual(services[0]["image"], expected["image"])
|
||||
self.assertEqual(image, expected["image"])
|
||||
self.assertEqual(services[0]["depends_on"], [])
|
||||
|
||||
icon = profile["catalog_ui"].get("icon")
|
||||
self.assertIsInstance(icon, str)
|
||||
self.assertTrue(icon.startswith("https://"), icon)
|
||||
|
||||
mount_paths = {
|
||||
volume["container_path"]
|
||||
for volume in profile["container_contract"]["volumes"]
|
||||
}
|
||||
self.assertIn(expected["data_path"], mount_paths)
|
||||
|
||||
def test_each_profile_has_a_matching_first_start_check(self):
|
||||
for app_id, expected in PROFILES.items():
|
||||
with self.subTest(app=app_id):
|
||||
profile = load_profile(app_id)
|
||||
check = profile["proxmox"]["installer_profile"]["startup_healthcheck"]
|
||||
|
||||
self.assertEqual(check["scheme"], "http")
|
||||
self.assertEqual(check["port"], expected["port"])
|
||||
self.assertEqual(check["path"], expected["health_path"])
|
||||
self.assertTrue(check["accept_any_status"])
|
||||
|
||||
def test_chhoto_url_uses_generated_password_and_data_database(self):
|
||||
profile = load_profile("chhoto-url")
|
||||
environment = {
|
||||
item["name"]: item
|
||||
for item in profile["container_contract"]["environment"]
|
||||
}
|
||||
generated = profile["proxmox"]["installer_profile"]["generated_sensitive_environment"]
|
||||
credential = profile["first_run"]["credentials"][0]
|
||||
|
||||
self.assertIn("CHHOTO_PASSWORD", environment)
|
||||
self.assertTrue(environment["CHHOTO_PASSWORD"]["sensitive"])
|
||||
self.assertIn("CHHOTO_PASSWORD", generated)
|
||||
self.assertEqual(credential["password_environment"], "CHHOTO_PASSWORD")
|
||||
self.assertEqual(environment["CHHOTO_DB_URL"]["example"], "/data/urls.sqlite")
|
||||
self.assertEqual(environment["CHHOTO_SQLITE_USE_WAL_MODE"]["example"], "True")
|
||||
|
||||
def test_openhabittracker_prompts_for_user_and_generates_password_and_jwt(self):
|
||||
profile = load_profile("openhabittracker")
|
||||
environment = {
|
||||
item["name"]: item
|
||||
for item in profile["container_contract"]["environment"]
|
||||
}
|
||||
generated = profile["proxmox"]["installer_profile"]["generated_sensitive_environment"]
|
||||
credential = profile["first_run"]["credentials"][0]
|
||||
|
||||
self.assertIn("prompt", environment["AppSettings__UserName"])
|
||||
self.assertIn("prompt", environment["AppSettings__Email"])
|
||||
self.assertIn("AppSettings__Password", generated)
|
||||
self.assertIn("AppSettings__JwtSecret", generated)
|
||||
self.assertEqual(credential["username_environment"], "AppSettings__UserName")
|
||||
self.assertEqual(credential["password_environment"], "AppSettings__Password")
|
||||
|
||||
def test_watcharr_first_registered_user_becomes_admin(self):
|
||||
profile = load_profile("watcharr")
|
||||
credentials = profile["first_run"]["credentials"]
|
||||
|
||||
self.assertEqual(profile["container_contract"]["environment"], [])
|
||||
self.assertEqual(len(credentials), 1)
|
||||
self.assertIn("administrator", credentials[0]["label"].lower())
|
||||
self.assertIn("first-run setup", credentials[0]["username"].lower())
|
||||
|
||||
def test_ech0_generates_jwt_and_marks_first_user_as_owner(self):
|
||||
profile = load_profile("ech0")
|
||||
generated = profile["proxmox"]["installer_profile"]["generated_sensitive_environment"]
|
||||
credentials = profile["first_run"]["credentials"]
|
||||
|
||||
self.assertIn("JWT_SECRET", generated)
|
||||
self.assertEqual(profile["container_contract"]["environment"][0]["name"], "JWT_SECRET")
|
||||
self.assertEqual(len(credentials), 1)
|
||||
self.assertIn("Owner", credentials[0]["label"])
|
||||
self.assertIn("first-run setup", credentials[0]["username"].lower())
|
||||
|
||||
def test_restic_server_is_an_api_without_a_browser_endpoint(self):
|
||||
profile = load_profile("restic-rest-server")
|
||||
credentials = profile["first_run"]["credentials"]
|
||||
ui = profile["catalog_ui"]
|
||||
|
||||
self.assertEqual(profile["first_run"]["endpoints"], [])
|
||||
self.assertIsNone(ui["launch"]["port"])
|
||||
self.assertIn("no web interface", ui["tagline"]["en_US"].lower())
|
||||
self.assertIn("not a browser-based application", ui["description"]["en_US"].lower())
|
||||
self.assertEqual(len(credentials), 1)
|
||||
self.assertIn("create_user", credentials[0]["username"])
|
||||
self.assertIsNone(credentials[0]["password"])
|
||||
self.assertEqual(
|
||||
profile["container_contract"]["environment"][0]["example"],
|
||||
"--private-repos",
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,176 @@
|
||||
"""Guard the Activepieces, Bytebase, Metabase and Kopia OCI recipes."""
|
||||
import json
|
||||
from pathlib import Path
|
||||
import unittest
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
EXPECTED = {
|
||||
"activepieces": {
|
||||
"image": "ghcr.io/activepieces/activepieces:latest",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/activepieces.webp",
|
||||
"health": (80, "/api/v1/health"),
|
||||
"note_terms": ("personal", "memory"),
|
||||
},
|
||||
"bytebase": {
|
||||
"image": "bytebase/bytebase:latest",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/bytebase/bytebase@main/frontend/src/assets/logo-icon.svg",
|
||||
"health": (8080, "/healthz"),
|
||||
"note_terms": (),
|
||||
},
|
||||
"metabase": {
|
||||
"image": "metabase/metabase:v0.64-lts",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/metabase.webp",
|
||||
"health": (3000, "/api/health"),
|
||||
"note_terms": ("h2", "postgres"),
|
||||
},
|
||||
"kopia": {
|
||||
"image": "kopia/kopia:latest",
|
||||
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/kopia.webp",
|
||||
"health": (51515, "/"),
|
||||
"note_terms": ("repository", "password"),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def read_profile(family, app):
|
||||
path = ROOT / "catalog" / family / f"{app}.json"
|
||||
return json.loads(path.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
class Next10CProfileTests(unittest.TestCase):
|
||||
def test_image_single_service_and_icon_match_catalog_contract(self):
|
||||
for app, expected in EXPECTED.items():
|
||||
with self.subTest(app=app):
|
||||
for family in ("apps", "curated"):
|
||||
profile = read_profile(family, app)
|
||||
stack = profile["compose_stack"]
|
||||
service = stack["services"][0]
|
||||
self.assertEqual(
|
||||
profile["container_contract"]["image"]["reference"],
|
||||
expected["image"],
|
||||
)
|
||||
self.assertEqual(stack["service_count"], 1)
|
||||
self.assertEqual(len(stack["services"]), 1)
|
||||
self.assertEqual(service["image"], expected["image"])
|
||||
self.assertEqual(service["compose"]["image"], expected["image"])
|
||||
self.assertEqual(profile["catalog_ui"]["icon"], expected["icon"])
|
||||
self.assertTrue(expected["icon"].startswith("https://"))
|
||||
|
||||
def test_startup_healthcheck_targets_the_documented_service_endpoint(self):
|
||||
for app, expected in EXPECTED.items():
|
||||
with self.subTest(app=app):
|
||||
for family in ("apps", "curated"):
|
||||
profile = read_profile(family, app)
|
||||
health = profile["proxmox"]["installer_profile"][
|
||||
"startup_healthcheck"
|
||||
]
|
||||
self.assertEqual(health["port"], expected["health"][0])
|
||||
self.assertEqual(health["path"], expected["health"][1])
|
||||
self.assertEqual(health["scheme"], "http")
|
||||
|
||||
def test_required_persistent_paths_are_mounted_by_the_single_service(self):
|
||||
for app in EXPECTED:
|
||||
with self.subTest(app=app):
|
||||
for family in ("apps", "curated"):
|
||||
profile = read_profile(family, app)
|
||||
contract_paths = {
|
||||
volume["container_path"]
|
||||
for volume in profile["container_contract"]["volumes"]
|
||||
if volume.get("required", False)
|
||||
}
|
||||
mounts = profile["compose_stack"]["services"][0]["compose"].get(
|
||||
"volumes", []
|
||||
)
|
||||
mounted_paths = {
|
||||
mount.split(":")[1]
|
||||
for mount in mounts
|
||||
if len(mount.split(":")) >= 2
|
||||
}
|
||||
self.assertTrue(contract_paths, "profile must declare persistent data")
|
||||
self.assertTrue(
|
||||
contract_paths.issubset(mounted_paths),
|
||||
f"required paths missing from Compose mounts: "
|
||||
f"{sorted(contract_paths - mounted_paths)}",
|
||||
)
|
||||
|
||||
def test_secret_environment_is_sensitive_generated_and_wired_to_compose(self):
|
||||
for app in EXPECTED:
|
||||
with self.subTest(app=app):
|
||||
for family in ("apps", "curated"):
|
||||
profile = read_profile(family, app)
|
||||
declared_sensitive = {
|
||||
item["name"]
|
||||
for item in profile["container_contract"].get("environment", [])
|
||||
if item.get("sensitive")
|
||||
}
|
||||
runtime_generated = profile["proxmox"]["installer_profile"].get(
|
||||
"generated_sensitive_environment", {}
|
||||
)
|
||||
generated_bindings = {
|
||||
binding["environment_variable"]
|
||||
for secret in profile["compose_stack"]["installer_inputs"].get(
|
||||
"generated_secrets", []
|
||||
)
|
||||
for binding in secret.get("bindings", [])
|
||||
}
|
||||
compose_environment = profile["compose_stack"]["services"][0][
|
||||
"compose"
|
||||
].get("environment", {})
|
||||
|
||||
if app == "bytebase":
|
||||
self.assertEqual(generated_bindings, set())
|
||||
self.assertEqual(runtime_generated, {})
|
||||
self.assertNotIn("HBOX_AUTH_API_KEY_PEPPER", declared_sensitive)
|
||||
self.assertNotIn("HBOX_AUTH_API_KEY_PEPPER", compose_environment)
|
||||
self.assertNotIn("homebox", json.dumps(profile).casefold())
|
||||
continue
|
||||
|
||||
self.assertTrue(
|
||||
generated_bindings,
|
||||
"profile must document generated credentials/secrets",
|
||||
)
|
||||
self.assertEqual(
|
||||
generated_bindings,
|
||||
set(runtime_generated),
|
||||
"generated secret bindings and runtime generators must match",
|
||||
)
|
||||
self.assertTrue(
|
||||
generated_bindings.issubset(declared_sensitive),
|
||||
"every generated secret must be declared sensitive in the contract",
|
||||
)
|
||||
for variable in generated_bindings:
|
||||
self.assertIn(variable, compose_environment)
|
||||
self.assertIn(variable, str(compose_environment[variable]))
|
||||
|
||||
def test_app_notes_explain_the_key_limitations_or_setup_requirements(self):
|
||||
for app, expected in EXPECTED.items():
|
||||
with self.subTest(app=app):
|
||||
for family in ("apps", "curated"):
|
||||
profile = read_profile(family, app)
|
||||
if app == "bytebase":
|
||||
endpoints = profile["first_run"]["endpoints"]
|
||||
web_ui = next(
|
||||
endpoint for endpoint in endpoints
|
||||
if endpoint["label"] == "Web UI"
|
||||
)
|
||||
self.assertEqual(web_ui["scheme"], "http")
|
||||
self.assertEqual(web_ui["port"], 8080)
|
||||
self.assertEqual(web_ui["path"], "/")
|
||||
self.assertEqual(profile["first_run"]["credentials"], [])
|
||||
self.assertEqual(
|
||||
profile["catalog_ui"]["documentation"],
|
||||
"https://docs.bytebase.com/get-started/self-host/deploy-with-docker",
|
||||
)
|
||||
continue
|
||||
|
||||
tips = profile["catalog_ui"].get("tips", [])
|
||||
note = " ".join(tips).casefold()
|
||||
self.assertTrue(tips, "profile must include app-specific notes")
|
||||
for term in expected["note_terms"]:
|
||||
self.assertIn(term, note)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user