mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-02 10:52:22 +00:00
Add ten OCI application profiles
This commit is contained in:
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user