diff --git a/lang/de.json b/lang/de.json index 6a5046c5..c0d1f158 100644 --- a/lang/de.json +++ b/lang/de.json @@ -4029,6 +4029,7 @@ "Manage local backup target": "Lokales Backup-Ziel verwalten", "Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Private Bildregister verwalten.\nGespeicherte Anmeldeinformationen ermöglichen ProxMenux den Zugriff auf Ihre privaten Bilder.", "Manage registry accounts as root on the Proxmox node.": "Registrierungskonten als Root auf dem Proxmox-Knoten verwalten.", + "Manage teams of AI agents from a web dashboard.": "Verwalte Teams von KI-Agenten über ein Web-Dashboard.", "Managed disks must have backup enabled and a valid size": "Managed Disks müssen Backup aktiviert und eine gültige Größe haben", "Managed public route include is missing": "Die Konfigurationsdatei für die verwalteten öffentlichen Routen fehlt", "Managed public route installation failed": "Die verwalteten öffentlichen Routen konnten nicht eingerichtet werden", diff --git a/lang/es.json b/lang/es.json index de005560..3ed48dc9 100644 --- a/lang/es.json +++ b/lang/es.json @@ -4024,6 +4024,7 @@ "Manage local backup target": "Configurar el destino del backup local", "Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Gestiona los registros de imágenes privadas.\nCon las credenciales guardadas, ProxMenux puede acceder a tus imágenes privadas.", "Manage registry accounts as root on the Proxmox node.": "Gestiona las cuentas de registro como root en el nodo Proxmox.", + "Manage teams of AI agents from a web dashboard.": "Gestiona equipos de agentes de IA desde un panel web.", "Managed disks must have backup enabled and a valid size": "Los discos gestionados deben tener habilitado backup y un tamaño válido", "Managed public route include is missing": "Falta el archivo de configuración de las rutas públicas gestionadas", "Managed public route installation failed": "No se han podido configurar las rutas públicas gestionadas", diff --git a/lang/fr.json b/lang/fr.json index c5ae697e..a2309009 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -4029,6 +4029,7 @@ "Manage local backup target": "Gérer la cible de sauvegarde locale", "Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Gérer les registres d’images privés.\nLes informations d'identification enregistrées permettent à ProxMenux d'accéder à vos images privées.", "Manage registry accounts as root on the Proxmox node.": "Gérez les comptes de registre en tant que root sur le nœud Proxmox.", + "Manage teams of AI agents from a web dashboard.": "Gérez des équipes d’agents IA depuis un tableau de bord web.", "Managed disks must have backup enabled and a valid size": "Les disques gérés doivent avoir une sauvegarde activée et une taille valide", "Managed public route include is missing": "Le fichier de configuration des routes publiques gérées est manquant", "Managed public route installation failed": "Impossible de configurer les routes publiques gérées", diff --git a/lang/it.json b/lang/it.json index ee4877e4..35b4f10e 100644 --- a/lang/it.json +++ b/lang/it.json @@ -4029,6 +4029,7 @@ "Manage local backup target": "Gestisci la destinazione di backup locale", "Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Gestisci i registri di immagini private.\nLe credenziali salvate consentono a ProxMenux di accedere alle tue immagini private.", "Manage registry accounts as root on the Proxmox node.": "Gestisci gli account del registro come root sul nodo Proxmox.", + "Manage teams of AI agents from a web dashboard.": "Gestisci team di agenti IA da una dashboard web.", "Managed disks must have backup enabled and a valid size": "I dischi gestiti devono avere il backup abilitato e una dimensione valida", "Managed public route include is missing": "Manca la direttiva di inclusione per le rotte pubbliche gestite", "Managed public route installation failed": "Impossibile configurare le rotte pubbliche gestite", diff --git a/lang/pt.json b/lang/pt.json index d6139773..b4ae9acc 100644 --- a/lang/pt.json +++ b/lang/pt.json @@ -4029,6 +4029,7 @@ "Manage local backup target": "Gerenciar destino de backup local", "Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Gerencie registros de imagens privadas.\nAs credenciais salvas permitem que ProxMenux acesse suas imagens privadas.", "Manage registry accounts as root on the Proxmox node.": "Gerencie contas de registro como root no nó Proxmox.", + "Manage teams of AI agents from a web dashboard.": "Gerencie equipes de agentes de IA a partir de um painel web.", "Managed disks must have backup enabled and a valid size": "Os discos gerenciados devem ter backup ativado e um tamanho válido", "Managed public route include is missing": "Falta o ficheiro de configuração das rotas públicas geridas", "Managed public route installation failed": "Não foi possível configurar as rotas públicas geridas", diff --git a/lang/sk.json b/lang/sk.json index fce024a1..28d61ecc 100644 --- a/lang/sk.json +++ b/lang/sk.json @@ -4029,6 +4029,7 @@ "Manage local backup target": "Spravovať lokálny cieľ záloh", "Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Správa súkromných registrov obrazov.\nUložené prihlasovacie údaje umožňujú ProxMenuxu pristupovať k vašim súkromným obrazom.", "Manage registry accounts as root on the Proxmox node.": "Spravujte účty registra ako root na uzle Proxmox.", + "Manage teams of AI agents from a web dashboard.": "Spravujte tímy AI agentov z webového panela.", "Managed disks must have backup enabled and a valid size": "Spravované disky musia mať zapnuté zálohovanie a platnú veľkosť", "Managed public route include is missing": "Chýba konfiguračný súbor spravovaných verejných trás", "Managed public route installation failed": "Nepodarilo sa nastaviť spravované verejné trasy", diff --git a/lang/sv.json b/lang/sv.json index d3f44455..2b66d3ef 100644 --- a/lang/sv.json +++ b/lang/sv.json @@ -4029,6 +4029,7 @@ "Manage local backup target": "Hantera lokalt mål för säkerhetskopiering", "Manage private image registries.\nSaved credentials let ProxMenux access your private images.": "Hantera privata bildregister.\nSparade referenser låter ProxMenux komma åt dina privata bilder.", "Manage registry accounts as root on the Proxmox node.": "Hantera registerkonton som root på Proxmox-noden.", + "Manage teams of AI agents from a web dashboard.": "Hantera team av AI-agenter från en webbpanel.", "Managed disks must have backup enabled and a valid size": "Hanterade diskar måste ha backup aktiverad och en giltig storlek", "Managed public route include is missing": "Konfigurationsfilen för de hanterade publika rutterna saknas", "Managed public route installation failed": "Det gick inte att konfigurera de hanterade publika rutterna", diff --git a/oci/VALIDATION.md b/oci/VALIDATION.md index 1680d3d3..cba69cf7 100644 --- a/oci/VALIDATION.md +++ b/oci/VALIDATION.md @@ -2,7 +2,7 @@ -52 of 532 applications in the OCI catalog have been tested for real: 49 in the ProxMenux lab and 3 by the community. The OCI installer shows them as verified, with a ✓ in the lists. +52 of 533 applications in the OCI catalog have been tested for real: 49 in the ProxMenux lab and 3 by the community. The OCI installer shows them as verified, with a ✓ in the lists. Each test describes the scenario that was run and names the image it ran on. It does not cover every possible configuration of the application, and a newer image has not been tested until someone reports it. diff --git a/oci/catalog/apps/paperclip.json b/oci/catalog/apps/paperclip.json new file mode 100644 index 00000000..c8e1b6a7 --- /dev/null +++ b/oci/catalog/apps/paperclip.json @@ -0,0 +1,505 @@ +{ + "schema_version": "0.5.0", + "kind": "proxmenux.oci-template", + "id": "image-paperclip", + "status": "generated-unvalidated", + "catalog_ui": { + "title": { + "en_US": "Paperclip" + }, + "tagline": { + "en_US": "Manage teams of AI agents from a web dashboard." + }, + "description": { + "en_US": "Official Paperclip image with its embedded PostgreSQL database, persistent agent workspaces and authenticated web interface." + }, + "category": "ai", + "category_label": "AI / Coding & Dev-Tools", + "author": "Paperclip", + "developer": "Paperclip", + "icon": "https://raw.githubusercontent.com/paperclipai/paperclip/master/ui/public/favicon.svg", + "thumbnail": null, + "screenshots": [], + "architectures": [ + "amd64", + "arm64" + ], + "launch": { + "scheme": "http", + "port": 3100, + "path": "/" + }, + "website": "https://paperclip.ing", + "documentation": "https://github.com/paperclipai/paperclip/blob/master/doc/DOCKER.md", + "repository": "https://github.com/paperclipai/paperclip", + "tips": [ + "Create an account and claim the instance from the first-run setup screen.", + "Configure provider credentials or external agents after installation; no API key is required to start the dashboard.", + "For HTTPS access, set PAPERCLIP_PUBLIC_URL to the canonical URL in Advanced settings.", + "Restore with the original network identity, or update PAPERCLIP_PUBLIC_URL in Modify when the address or hostname changes." + ], + "mini_changelog": [], + "display_version": null, + "updated_at": null + }, + "source": { + "provider": "official", + "repository": "https://github.com/paperclipai/paperclip", + "revision": "1b4c803816e82b0265c8422e1a804327a7ed8c54", + "image_repository_url": "https://github.com/paperclipai/paperclip/pkgs/container/paperclip", + "readme_pushed_at": "", + "compose_sha256": "53a71e7d1c6a47fb25ad68d5570140c525df30fcecf33a00cf84bd2b65bd15f4", + "generated_at": "2026-11-02T18:43:18+00:00", + "readme_raw_url": "https://github.com/paperclipai/paperclip/blob/master/doc/DOCKER.md" + }, + "container_contract": { + "service_name": "paperclip", + "container_name": "paperclip", + "image": { + "reference": "ghcr.io/paperclipai/paperclip:latest", + "registry": "ghcr.io", + "repository": "ghcr.io/paperclipai/paperclip", + "tag": "latest", + "digest": null, + "pull_policy": "resolve-written-reference-to-architecture-digest-at-install" + }, + "environment": [ + { + "name": "HOST", + "example": "0.0.0.0", + "required": true, + "sensitive": false, + "source": "docker-compose", + "prompt_user": false + }, + { + "name": "PAPERCLIP_HOME", + "example": "/paperclip", + "required": true, + "sensitive": false, + "source": "docker-compose", + "prompt_user": false + }, + { + "name": "PAPERCLIP_DEPLOYMENT_MODE", + "example": "authenticated", + "required": true, + "sensitive": false, + "source": "docker-compose", + "prompt_user": false + }, + { + "name": "PAPERCLIP_DEPLOYMENT_EXPOSURE", + "example": "private", + "required": true, + "sensitive": false, + "source": "docker-compose", + "prompt_user": false + }, + { + "name": "PAPERCLIP_PUBLIC_URL", + "example": "http://localhost:3100", + "required": true, + "sensitive": false, + "source": "docker-compose", + "container_address": "http://@CONTAINER_ADDRESS@:3100" + }, + { + "name": "BETTER_AUTH_SECRET", + "example": "${GENERATED_BETTER_AUTH_SECRET}", + "required": true, + "sensitive": true, + "source": "docker-compose" + }, + { + "name": "PAPERCLIP_TOOL_ACTION_SIGNING_SECRET", + "example": "${GENERATED_PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}", + "required": true, + "sensitive": true, + "source": "docker-compose" + }, + { + "name": "OPENAI_API_KEY", + "example": "", + "required": false, + "sensitive": true, + "source": "official-documentation" + }, + { + "name": "ANTHROPIC_API_KEY", + "example": "", + "required": false, + "sensitive": true, + "source": "official-documentation" + }, + { + "name": "GEMINI_API_KEY", + "example": "", + "required": false, + "sensitive": true, + "source": "official-documentation" + }, + { + "name": "OPENROUTER_API_KEY", + "example": "", + "required": false, + "sensitive": true, + "source": "official-documentation" + }, + { + "name": "PAPERCLIP_ALLOWED_HOSTNAMES", + "example": "", + "required": false, + "sensitive": false, + "source": "official-documentation" + }, + { + "name": "PAPERCLIP_MIGRATION_AUTO_APPLY", + "example": "true", + "required": true, + "sensitive": false, + "prompt_user": false, + "source": "official-server-startup" + } + ], + "volumes": [ + { + "id": "volume-0", + "container_path": "/paperclip", + "compose_source_example": "paperclip-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": 3100, + "published_example": 3100, + "protocol": "tcp", + "required": true, + "proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat" + } + ], + "related_services": [], + "restart": "unless-stopped", + "stop_grace_period": "90s", + "original_compose": "name: paperclip\nservices:\n paperclip:\n image: ghcr.io/paperclipai/paperclip:latest\n restart: unless-stopped\n stop_grace_period: 90s\n ports:\n - 3100:3100\n environment:\n HOST: 0.0.0.0\n PAPERCLIP_HOME: /paperclip\n PAPERCLIP_MIGRATION_AUTO_APPLY: \"true\"\n PAPERCLIP_DEPLOYMENT_MODE: authenticated\n PAPERCLIP_DEPLOYMENT_EXPOSURE: private\n PAPERCLIP_PUBLIC_URL: http://localhost:3100\n BETTER_AUTH_SECRET: ${GENERATED_BETTER_AUTH_SECRET}\n PAPERCLIP_TOOL_ACTION_SIGNING_SECRET: ${GENERATED_PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}\n volumes:\n - paperclip-data:/paperclip\nvolumes:\n paperclip-data: {}\n" + }, + "compose_stack": { + "project_name": "paperclip", + "deployment_model": "one-native-oci-lxc-per-compose-service", + "user_experience": "single-application-install", + "main_service": "paperclip", + "service_count": 1, + "services": [ + { + "name": "paperclip", + "image": "ghcr.io/paperclipai/paperclip:latest", + "is_main": true, + "role": "frontend", + "vmid_offset": 0, + "depends_on": [], + "frontend_network": true, + "private_network": false, + "compose": { + "image": "ghcr.io/paperclipai/paperclip:latest", + "restart": "unless-stopped", + "stop_grace_period": "90s", + "ports": [ + "3100:3100" + ], + "environment": { + "HOST": "0.0.0.0", + "PAPERCLIP_HOME": "/paperclip", + "PAPERCLIP_DEPLOYMENT_MODE": "authenticated", + "PAPERCLIP_DEPLOYMENT_EXPOSURE": "private", + "PAPERCLIP_PUBLIC_URL": "http://localhost:3100", + "BETTER_AUTH_SECRET": "${GENERATED_BETTER_AUTH_SECRET}", + "PAPERCLIP_TOOL_ACTION_SIGNING_SECRET": "${GENERATED_PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}", + "PAPERCLIP_MIGRATION_AUTO_APPLY": "true" + }, + "volumes": [ + "paperclip-data:/paperclip" + ] + } + } + ], + "top_level": { + "name": "paperclip", + "volumes": { + "paperclip-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": "paperclip-volume-0", + "service": "paperclip", + "container_path": "/paperclip", + "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": [ + "paperclip" + ], + "stop_order": [ + "paperclip" + ], + "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": "better-auth-secret", + "strategy": "generate-cryptographically-random-at-install", + "bindings": [ + { + "service": "paperclip", + "environment_variable": "BETTER_AUTH_SECRET" + } + ] + }, + { + "id": "paperclip-tool-action-signing-secret", + "strategy": "generate-cryptographically-random-at-install", + "bindings": [ + { + "service": "paperclip", + "environment_variable": "PAPERCLIP_TOOL_ACTION_SIGNING_SECRET" + } + ] + } + ] + } + }, + "first_run": { + "endpoints": [ + { + "label": "Web UI", + "scheme": "http", + "port": 3100, + "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": 4096, + "swap_mb": 512, + "rootfs_size_gb": 32, + "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": 90 + }, + "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": "official-embedded-postgresql-image", + "upstream_behavior": "The official image starts Paperclip and its embedded PostgreSQL database.", + "native_lxc_behavior": "Import the original Entrypoint, Cmd and WorkingDir into one unprivileged LXC.", + "reason": "Keep the developer image without Docker Engine or a custom image build.", + "behavioral_impact": "Provider credentials are configured separately after the first account is created.", + "validation": "passed-amd64-web-login-and-api-data" + }, + { + "id": "persistent-application-home", + "upstream_behavior": "The root entrypoint prepares /paperclip and then switches to the node user.", + "native_lxc_behavior": "Prepare the volume for mapped root and let the official entrypoint set application ownership.", + "reason": "Preserve the embedded database, uploads, workspaces and local secrets across image replacement and restore.", + "behavioral_impact": "Managed volumes are backed up; host directories remain outside the LXC backup.", + "validation": "passed-managed-volume-host-bind-restart-and-restore" + }, + { + "id": "noninteractive-database-migrations", + "upstream_behavior": "Existing databases with pending migrations trigger an interactive confirmation during startup.", + "native_lxc_behavior": "Set the upstream PAPERCLIP_MIGRATION_AUTO_APPLY=true option.", + "reason": "An OCI update must finish without waiting for input at a migration prompt.", + "behavioral_impact": "Paperclip applies its schema migrations when starting an updated image; the native update backup protects the previous installation.", + "validation": "passed-real-upgrade-2026.1012.0-to-2026.1023.0" + }, + { + "id": "authenticated-instance-address", + "upstream_behavior": "Paperclip uses its canonical public URL for authentication origins and hostname checks.", + "native_lxc_behavior": "Use the installer container-address placeholder by default and allow a canonical URL in Advanced settings.", + "reason": "Avoid the upstream localhost URL on an LXC with its own address.", + "behavioral_impact": "When restoring under another address, change PAPERCLIP_PUBLIC_URL through Modify. Restoring the original network identity retains the URL.", + "validation": "passed-direct-ip-authenticated-setup-and-original-network-restore" + }, + { + "id": "independent-signing-secrets", + "upstream_behavior": "Session signing and approval-gated tool actions use independent secrets.", + "native_lxc_behavior": "Generate two separate 32-byte hexadecimal secrets and keep their values sensitive.", + "reason": "Do not ship a shared password or regenerate signing keys during an update.", + "behavioral_impact": "The first administrator creates an account in the web interface. Provider API keys are optional and sensitive.", + "validation": "passed-first-admin-claim-and-update-account-persistence" + } + ], + "installer_profile": { + "volume_preparations": [ + { + "container_path": "/paperclip", + "remove_lost_found": true, + "owner_strategy": "mapped-root", + "only_when_mount_type": "managed-volume" + } + ], + "generated_sensitive_environment": { + "BETTER_AUTH_SECRET": { + "strategy": "token-hex", + "bytes": 32, + "prompt": false + }, + "PAPERCLIP_TOOL_ACTION_SIGNING_SECRET": { + "strategy": "token-hex", + "bytes": 32, + "prompt": false + } + }, + "startup_healthcheck": { + "scheme": "http", + "port": 3100, + "path": "/api/health", + "timeout_seconds": 300, + "request_timeout_seconds": 10, + "stability_seconds": 5, + "verify_tls": 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", + "stop_signal", + "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", + "clean_install": "passed-default-resource-profile-and-advanced-settings-amd64", + "service_health": "passed-http-api-health-browser-login-and-first-admin-claim", + "restart_persistence": "passed-host-bind-reboot-and-managed-volume-restore", + "backup_restore": "passed-different-vmid-oci-recovery-with-original-network-identity", + "update_preserves_data": "passed-2026.1012.0-to-2026.1023.0-with-automatic-schema-migrations", + "rollback": "passed-explicit-native-Recover-after-failed-image-not-claimed-automatic", + "modification": "passed-native-cpu-and-ram-change-without-image-download-or-recreation", + "removal": "passed-guests-disks-records-and-test-backups-cleaned-host-data-preserved-by-Remove", + "browser_ui": "passed-account-login-and-company-dashboard", + "runtime_architecture": "amd64-tested-arm64-manifest-only", + "provider_agent_runs": "not-tested-no-real-provider-credentials-used", + "oci_engine_tests": "1158-run-4-skipped", + "offline_i18n_tests": "626-passed" + }, + "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 + } +} diff --git a/oci/catalog/curated/paperclip.json b/oci/catalog/curated/paperclip.json new file mode 100644 index 00000000..c8e1b6a7 --- /dev/null +++ b/oci/catalog/curated/paperclip.json @@ -0,0 +1,505 @@ +{ + "schema_version": "0.5.0", + "kind": "proxmenux.oci-template", + "id": "image-paperclip", + "status": "generated-unvalidated", + "catalog_ui": { + "title": { + "en_US": "Paperclip" + }, + "tagline": { + "en_US": "Manage teams of AI agents from a web dashboard." + }, + "description": { + "en_US": "Official Paperclip image with its embedded PostgreSQL database, persistent agent workspaces and authenticated web interface." + }, + "category": "ai", + "category_label": "AI / Coding & Dev-Tools", + "author": "Paperclip", + "developer": "Paperclip", + "icon": "https://raw.githubusercontent.com/paperclipai/paperclip/master/ui/public/favicon.svg", + "thumbnail": null, + "screenshots": [], + "architectures": [ + "amd64", + "arm64" + ], + "launch": { + "scheme": "http", + "port": 3100, + "path": "/" + }, + "website": "https://paperclip.ing", + "documentation": "https://github.com/paperclipai/paperclip/blob/master/doc/DOCKER.md", + "repository": "https://github.com/paperclipai/paperclip", + "tips": [ + "Create an account and claim the instance from the first-run setup screen.", + "Configure provider credentials or external agents after installation; no API key is required to start the dashboard.", + "For HTTPS access, set PAPERCLIP_PUBLIC_URL to the canonical URL in Advanced settings.", + "Restore with the original network identity, or update PAPERCLIP_PUBLIC_URL in Modify when the address or hostname changes." + ], + "mini_changelog": [], + "display_version": null, + "updated_at": null + }, + "source": { + "provider": "official", + "repository": "https://github.com/paperclipai/paperclip", + "revision": "1b4c803816e82b0265c8422e1a804327a7ed8c54", + "image_repository_url": "https://github.com/paperclipai/paperclip/pkgs/container/paperclip", + "readme_pushed_at": "", + "compose_sha256": "53a71e7d1c6a47fb25ad68d5570140c525df30fcecf33a00cf84bd2b65bd15f4", + "generated_at": "2026-11-02T18:43:18+00:00", + "readme_raw_url": "https://github.com/paperclipai/paperclip/blob/master/doc/DOCKER.md" + }, + "container_contract": { + "service_name": "paperclip", + "container_name": "paperclip", + "image": { + "reference": "ghcr.io/paperclipai/paperclip:latest", + "registry": "ghcr.io", + "repository": "ghcr.io/paperclipai/paperclip", + "tag": "latest", + "digest": null, + "pull_policy": "resolve-written-reference-to-architecture-digest-at-install" + }, + "environment": [ + { + "name": "HOST", + "example": "0.0.0.0", + "required": true, + "sensitive": false, + "source": "docker-compose", + "prompt_user": false + }, + { + "name": "PAPERCLIP_HOME", + "example": "/paperclip", + "required": true, + "sensitive": false, + "source": "docker-compose", + "prompt_user": false + }, + { + "name": "PAPERCLIP_DEPLOYMENT_MODE", + "example": "authenticated", + "required": true, + "sensitive": false, + "source": "docker-compose", + "prompt_user": false + }, + { + "name": "PAPERCLIP_DEPLOYMENT_EXPOSURE", + "example": "private", + "required": true, + "sensitive": false, + "source": "docker-compose", + "prompt_user": false + }, + { + "name": "PAPERCLIP_PUBLIC_URL", + "example": "http://localhost:3100", + "required": true, + "sensitive": false, + "source": "docker-compose", + "container_address": "http://@CONTAINER_ADDRESS@:3100" + }, + { + "name": "BETTER_AUTH_SECRET", + "example": "${GENERATED_BETTER_AUTH_SECRET}", + "required": true, + "sensitive": true, + "source": "docker-compose" + }, + { + "name": "PAPERCLIP_TOOL_ACTION_SIGNING_SECRET", + "example": "${GENERATED_PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}", + "required": true, + "sensitive": true, + "source": "docker-compose" + }, + { + "name": "OPENAI_API_KEY", + "example": "", + "required": false, + "sensitive": true, + "source": "official-documentation" + }, + { + "name": "ANTHROPIC_API_KEY", + "example": "", + "required": false, + "sensitive": true, + "source": "official-documentation" + }, + { + "name": "GEMINI_API_KEY", + "example": "", + "required": false, + "sensitive": true, + "source": "official-documentation" + }, + { + "name": "OPENROUTER_API_KEY", + "example": "", + "required": false, + "sensitive": true, + "source": "official-documentation" + }, + { + "name": "PAPERCLIP_ALLOWED_HOSTNAMES", + "example": "", + "required": false, + "sensitive": false, + "source": "official-documentation" + }, + { + "name": "PAPERCLIP_MIGRATION_AUTO_APPLY", + "example": "true", + "required": true, + "sensitive": false, + "prompt_user": false, + "source": "official-server-startup" + } + ], + "volumes": [ + { + "id": "volume-0", + "container_path": "/paperclip", + "compose_source_example": "paperclip-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": 3100, + "published_example": 3100, + "protocol": "tcp", + "required": true, + "proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat" + } + ], + "related_services": [], + "restart": "unless-stopped", + "stop_grace_period": "90s", + "original_compose": "name: paperclip\nservices:\n paperclip:\n image: ghcr.io/paperclipai/paperclip:latest\n restart: unless-stopped\n stop_grace_period: 90s\n ports:\n - 3100:3100\n environment:\n HOST: 0.0.0.0\n PAPERCLIP_HOME: /paperclip\n PAPERCLIP_MIGRATION_AUTO_APPLY: \"true\"\n PAPERCLIP_DEPLOYMENT_MODE: authenticated\n PAPERCLIP_DEPLOYMENT_EXPOSURE: private\n PAPERCLIP_PUBLIC_URL: http://localhost:3100\n BETTER_AUTH_SECRET: ${GENERATED_BETTER_AUTH_SECRET}\n PAPERCLIP_TOOL_ACTION_SIGNING_SECRET: ${GENERATED_PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}\n volumes:\n - paperclip-data:/paperclip\nvolumes:\n paperclip-data: {}\n" + }, + "compose_stack": { + "project_name": "paperclip", + "deployment_model": "one-native-oci-lxc-per-compose-service", + "user_experience": "single-application-install", + "main_service": "paperclip", + "service_count": 1, + "services": [ + { + "name": "paperclip", + "image": "ghcr.io/paperclipai/paperclip:latest", + "is_main": true, + "role": "frontend", + "vmid_offset": 0, + "depends_on": [], + "frontend_network": true, + "private_network": false, + "compose": { + "image": "ghcr.io/paperclipai/paperclip:latest", + "restart": "unless-stopped", + "stop_grace_period": "90s", + "ports": [ + "3100:3100" + ], + "environment": { + "HOST": "0.0.0.0", + "PAPERCLIP_HOME": "/paperclip", + "PAPERCLIP_DEPLOYMENT_MODE": "authenticated", + "PAPERCLIP_DEPLOYMENT_EXPOSURE": "private", + "PAPERCLIP_PUBLIC_URL": "http://localhost:3100", + "BETTER_AUTH_SECRET": "${GENERATED_BETTER_AUTH_SECRET}", + "PAPERCLIP_TOOL_ACTION_SIGNING_SECRET": "${GENERATED_PAPERCLIP_TOOL_ACTION_SIGNING_SECRET}", + "PAPERCLIP_MIGRATION_AUTO_APPLY": "true" + }, + "volumes": [ + "paperclip-data:/paperclip" + ] + } + } + ], + "top_level": { + "name": "paperclip", + "volumes": { + "paperclip-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": "paperclip-volume-0", + "service": "paperclip", + "container_path": "/paperclip", + "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": [ + "paperclip" + ], + "stop_order": [ + "paperclip" + ], + "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": "better-auth-secret", + "strategy": "generate-cryptographically-random-at-install", + "bindings": [ + { + "service": "paperclip", + "environment_variable": "BETTER_AUTH_SECRET" + } + ] + }, + { + "id": "paperclip-tool-action-signing-secret", + "strategy": "generate-cryptographically-random-at-install", + "bindings": [ + { + "service": "paperclip", + "environment_variable": "PAPERCLIP_TOOL_ACTION_SIGNING_SECRET" + } + ] + } + ] + } + }, + "first_run": { + "endpoints": [ + { + "label": "Web UI", + "scheme": "http", + "port": 3100, + "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": 4096, + "swap_mb": 512, + "rootfs_size_gb": 32, + "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": 90 + }, + "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": "official-embedded-postgresql-image", + "upstream_behavior": "The official image starts Paperclip and its embedded PostgreSQL database.", + "native_lxc_behavior": "Import the original Entrypoint, Cmd and WorkingDir into one unprivileged LXC.", + "reason": "Keep the developer image without Docker Engine or a custom image build.", + "behavioral_impact": "Provider credentials are configured separately after the first account is created.", + "validation": "passed-amd64-web-login-and-api-data" + }, + { + "id": "persistent-application-home", + "upstream_behavior": "The root entrypoint prepares /paperclip and then switches to the node user.", + "native_lxc_behavior": "Prepare the volume for mapped root and let the official entrypoint set application ownership.", + "reason": "Preserve the embedded database, uploads, workspaces and local secrets across image replacement and restore.", + "behavioral_impact": "Managed volumes are backed up; host directories remain outside the LXC backup.", + "validation": "passed-managed-volume-host-bind-restart-and-restore" + }, + { + "id": "noninteractive-database-migrations", + "upstream_behavior": "Existing databases with pending migrations trigger an interactive confirmation during startup.", + "native_lxc_behavior": "Set the upstream PAPERCLIP_MIGRATION_AUTO_APPLY=true option.", + "reason": "An OCI update must finish without waiting for input at a migration prompt.", + "behavioral_impact": "Paperclip applies its schema migrations when starting an updated image; the native update backup protects the previous installation.", + "validation": "passed-real-upgrade-2026.1012.0-to-2026.1023.0" + }, + { + "id": "authenticated-instance-address", + "upstream_behavior": "Paperclip uses its canonical public URL for authentication origins and hostname checks.", + "native_lxc_behavior": "Use the installer container-address placeholder by default and allow a canonical URL in Advanced settings.", + "reason": "Avoid the upstream localhost URL on an LXC with its own address.", + "behavioral_impact": "When restoring under another address, change PAPERCLIP_PUBLIC_URL through Modify. Restoring the original network identity retains the URL.", + "validation": "passed-direct-ip-authenticated-setup-and-original-network-restore" + }, + { + "id": "independent-signing-secrets", + "upstream_behavior": "Session signing and approval-gated tool actions use independent secrets.", + "native_lxc_behavior": "Generate two separate 32-byte hexadecimal secrets and keep their values sensitive.", + "reason": "Do not ship a shared password or regenerate signing keys during an update.", + "behavioral_impact": "The first administrator creates an account in the web interface. Provider API keys are optional and sensitive.", + "validation": "passed-first-admin-claim-and-update-account-persistence" + } + ], + "installer_profile": { + "volume_preparations": [ + { + "container_path": "/paperclip", + "remove_lost_found": true, + "owner_strategy": "mapped-root", + "only_when_mount_type": "managed-volume" + } + ], + "generated_sensitive_environment": { + "BETTER_AUTH_SECRET": { + "strategy": "token-hex", + "bytes": 32, + "prompt": false + }, + "PAPERCLIP_TOOL_ACTION_SIGNING_SECRET": { + "strategy": "token-hex", + "bytes": 32, + "prompt": false + } + }, + "startup_healthcheck": { + "scheme": "http", + "port": 3100, + "path": "/api/health", + "timeout_seconds": 300, + "request_timeout_seconds": 10, + "stability_seconds": 5, + "verify_tls": 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", + "stop_signal", + "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", + "clean_install": "passed-default-resource-profile-and-advanced-settings-amd64", + "service_health": "passed-http-api-health-browser-login-and-first-admin-claim", + "restart_persistence": "passed-host-bind-reboot-and-managed-volume-restore", + "backup_restore": "passed-different-vmid-oci-recovery-with-original-network-identity", + "update_preserves_data": "passed-2026.1012.0-to-2026.1023.0-with-automatic-schema-migrations", + "rollback": "passed-explicit-native-Recover-after-failed-image-not-claimed-automatic", + "modification": "passed-native-cpu-and-ram-change-without-image-download-or-recreation", + "removal": "passed-guests-disks-records-and-test-backups-cleaned-host-data-preserved-by-Remove", + "browser_ui": "passed-account-login-and-company-dashboard", + "runtime_architecture": "amd64-tested-arm64-manifest-only", + "provider_agent_runs": "not-tested-no-real-provider-credentials-used", + "oci_engine_tests": "1158-run-4-skipped", + "offline_i18n_tests": "626-passed" + }, + "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 + } +} diff --git a/oci/catalog/index.json b/oci/catalog/index.json index 0c0f7d9c..9e0f916a 100644 --- a/oci/catalog/index.json +++ b/oci/catalog/index.json @@ -12061,6 +12061,32 @@ "hidden": false, "template_id": "linuxserver-pairdrop" }, + { + "id": "paperclip", + "provider": "official", + "template_family": "curated-profile", + "title": "Paperclip", + "repository": "https://github.com/paperclipai/paperclip", + "description": "Official Paperclip image with its embedded PostgreSQL database, persistent agent workspaces and authenticated web interface.", + "website": "https://paperclip.ing", + "icon": "https://raw.githubusercontent.com/paperclipai/paperclip/master/ui/public/favicon.svg", + "architectures": [ + "amd64", + "arm64" + ], + "updated_at": null, + "main_image": "ghcr.io/paperclipai/paperclip:latest", + "category": "ai", + "category_label": "AI / Coding & Dev-Tools", + "replaces_discovered_ids": [], + "curated_path": "catalog/curated/paperclip.json", + "template_id": "image-paperclip", + "template": "apps/paperclip.json", + "template_status": "generated-unvalidated", + "automatic_install_candidate": true, + "untranslated_blockers": [], + "hidden": false + }, { "id": "paperless-ngx", "provider": "paperless-ngx",