1"use strict";(self.webpackChunkpantavisor_docs=self.webpackChunkpantavisor_docs||[]).push([["14843"],{81041(e,n,t){t.r(n),t.d(n,{metadata:()=>i,default:()=>p,frontMatter:()=>o,contentTitle:()=>s,toc:()=>l,assets:()=>c});var i=JSON.parse('{"id":"meta-pantavisor/getting-started/develop/application/configure","title":"Configure Application Settings","description":"Configure application settings on Pantavisor Linux. Learn to edit manifests, set environment variables, and manage app configurations.","source":"@site/reference_versioned_docs/version-029-rc5/meta-pantavisor/getting-started/develop/application/configure.md","sourceDirName":"meta-pantavisor/getting-started/develop/application","slug":"/meta-pantavisor/getting-started/develop/application/configure","permalink":"/029-rc5/meta-pantavisor/getting-started/develop/application/configure","draft":false,"unlisted":false,"tags":[],"version":"029-rc5","sidebarPosition":41,"frontMatter":{"title":"Configure Application Settings","sidebar_position":41,"description":"Configure application settings on Pantavisor Linux. Learn to edit manifests, set environment variables, and manage app configurations."},"sidebar":"metaPantavisorGettingStartedSidebar","previous":{"title":"Install remotely via Pantahub","permalink":"/029-rc5/meta-pantavisor/getting-started/develop/application/install/remote-pantahub"},"next":{"title":"View Installed Applications","permalink":"/029-rc5/meta-pantavisor/getting-started/develop/application/view"}}'),a=t(74848),r=t(28453);let o={title:"Configure Application Settings",sidebar_position:41,description:"Configure application settings on Pantavisor Linux. Learn to edit manifests, set environment variables, and manage app configurations."},s,c={},l=[{value:"Step 1 \u2014 Clone the Device",id:"step-1--clone-the-device",level:2},{value:"Step 2 \u2014 Make Your Changes",id:"step-2--make-your-changes",level:2},{value:"Edit a configuration file (overlay)",id:"edit-a-configuration-file-overlay",level:3},{value:"Edit a container's run manifest",id:"edit-a-containers-run-manifest",level:3},{value:"Replace the container image",id:"replace-the-container-image",level:3},{value:"Step 3 \u2014 Stage and Commit",id:"step-3--stage-and-commit",level:2},{value:"Step 4 \u2014 Deploy to the Device",id:"step-4--deploy-to-the-device",level:2},{value:"Step 5 \u2014 Verify",id:"step-5--verify",level:2}];function d(e){let n={code:"code",h2:"h2",h3:"h3",hr:"hr",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(n.p,{children:["Each container's root filesystem is a read-only SquashFS image (",(0,a.jsx)(n.code,{children:"root.squashfs"}),"). To change files inside a running container you do not edit the device directly. Instead you make changes in a local ",(0,a.jsx)(n.code,{children:"pvr"})," checkout of the device state, then deploy a new revision. Pantavisor applies the overlay on the next boot."]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"_config/<container-name>/"})," directory in a pvr checkout acts as a writable overlay tree: files placed there are layered on top of the container's read-only rootfs at startup."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.h2,{id:"step-1--clone-the-device",children:"Step 1 \u2014 Clone the Device"}),"\n",(0,a.jsx)(n.p,{children:"Clone the device's current state to your workstation. The device must be reachable on the local network."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"pvr clone http://<device-ip>:12368/cgi-bin my-device\ncd my-device\n"})}),"\n",(0,a.jsx)(n.p,{children:"After cloning, the directory mirrors the device's revision:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"my-device/\n\u251C\u2500\u2500 bsp/ \u2190 BSP component (squashfs files, DTBs)\n\u251C\u2500\u2500 network/ \u2190 network container (root.squashfs, run.json, lxc.container.conf)\n\u251C\u2500\u2500 sensor-app/ \u2190 application container\n\u251C\u2500\u2500 _config/ \u2190 per-container file overlays\n\u251C\u2500\u2500 device.json \u2190 device-level config (groups, auto-recovery policy)\n\u2514\u2500\u2500 _sigs/ \u2190 optional container signatures\n"})}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.h2,{id:"step-2--make-your-changes",children:"Step 2 \u2014 Make Your Changes"}),"\n",(0,a.jsx)(n.h3,{id:"edit-a-configuration-file-overlay",children:"Edit a configuration file (overlay)"}),"\n",(0,a.jsxs)(n.p,{children:["Files under ",(0,a.jsx)(n.code,{children:"_config/<container-name>/"})," are overlaid onto that container's rootfs at runtime. Create the path that matches where the file lives inside the container."]}
1),"\n",(0,a.jsxs)(n.p,{children:["Example \u2014 add your SSH public key to the ",(0,a.jsx)(n.code,{children:"sensor-app"})," container:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"mkdir -p _config/sensor-app/home/root/.ssh\ncat ~/.ssh/id_ed25519.pub >> _config/sensor-app/home/root/.ssh/authorized_keys\n"})}),"\n",(0,a.jsx)(n.h3,{id:"edit-a-containers-run-manifest",children:"Edit a container's run manifest"}),"\n",(0,a.jsxs)(n.p,{children:["Each container directory contains a ",(0,a.jsx)(n.code,{children:"run.json"})," that controls Pantavisor-level behaviour: restart policy, auto-recovery, and pv-xconnect wiring. Edit it directly in the checked-out directory."]}),"\n",(0,a.jsxs)(n.p,{children:["Example \u2014 configure auto-recovery in ",(0,a.jsx)(n.code,{children:"sensor-app/run.json"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "auto_recovery": {\n "policy": "on-failure",\n "max_retries": 5,\n "retry_delay": 5,\n "backoff_factor": 2.0,\n "backoff_policy": "10min"\n }\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"run.json"})," does not control environment variables. Env vars come from the container image's config and are compiled into ",(0,a.jsx)(n.code,{children:"lxc.container.conf"})," when you run ",(0,a.jsx)(n.code,{children:"pvr app add"})," or ",(0,a.jsx)(n.code,{children:"pvr app update"})," \u2014 to change them, update the app's source image (see below) rather than hand-editing ",(0,a.jsx)(n.code,{children:"run.json"}),"."]}),"\n",(0,a.jsx)(n.h3,{id:"replace-the-container-image",children:"Replace the container image"}),"\n",(0,a.jsxs)(n.p,{children:["To update the container rootfs itself, use ",(0,a.jsx)(n.code,{children:"pvr app update"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"pvr app update sensor-app --from registry.example.com/sensor-app:v1.2.0\n"})}),"\n",(0,a.jsxs)(n.p,{children:["This re-pulls the image and replaces ",(0,a.jsx)(n.code,{children:"sensor-app/root.squashfs"}),"."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.h2,{id:"step-3--stage-and-commit",children:"Step 3 \u2014 Stage and Commit"}),"\n",(0,a.jsx)(n.p,{children:"Check what changed:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"pvr status\n"})}),"\n",(0,a.jsx)(n.p,{children:"Example output:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"A _config/sensor-app/home/root/.ssh/authorized_keys\nC sensor-app/run.json\n"})}),"\n",(0,a.jsx)(n.p,{children:"Stage and commit:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'pvr add .\npvr commit -m "add SSH key and configure auto-recovery for sensor-app"\n'})}),"\n",(0,a.jsx)(n.p,{children:"If the container is cryptographically signed, update its signature before committing:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'pvr sig add --part sensor-app\npvr add .\npvr commit -m "add SSH key and configure auto-recovery for sensor-app"\n'})}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.h2,{id:"step-4--deploy-to-the-device",children:"Step 4 \u2014 Deploy to the Device"}),"\n",(0,a.jsx)(n.p,{children:"Post the new revision to the device's pvr endpoint \u2014 the same URL you cloned from:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"pvr post http://<device-ip>:12368\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Pantavisor downloads the changed objects, writes them to a pending revision, and restarts the affected containers (a full reboot only happens when a ",(0,a.jsx)(n.code,{children:"system"})," restart-policy container or the BSP changed). If the new revision starts cleanly and all containers reach their status goal, it is committed as the new permanent state. If it fails, the previous revision is restored automatically."]}),"\n",(0,a.jsx)(n.hr,{}),"\n",(0,a.jsx)(n.h2,{id:"step-5--verify",children:"Step 5 \u2014 Verify"}),"\n",(0,a.jsx)(n.p,{children:"After the update is applied, confirm the changes are live:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# Check the container is running\npvcontrol container ls\n\n# Inspect logs\ntail -f /pantavisor/logs/<revision>/sensor-app/lxc/console.log\n\n# SSH into the device if you added a key\nssh root@<device-ip>\n"})})]})}function p(e={}){let{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453(e,n,t){t.d(n,{R:()=>o,x:()=>s});var i=t(96540);let a={},r=i.createContext(a);function o(e){let n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.