Multi-Context Integration Recipes
Practical implementation recipes for integrating PanOS with web apps, services, edge jobs, CI pipelines, and embedded systems
Multi-Context Integration Recipes
This guide provides concrete recipes you can adapt directly.
Each recipe includes:
- Context and target
- Minimal architecture
- Code sample
- Validation strategy
Recipe A — API Runtime for Internal Tooling
Context
You need a lightweight internal API where reproducible startup matters more than horizontal complexity.
Minimal Architecture
Admin UI -> HTTP API (PanOS guest) -> Local JSON stateImplementation
// /app/internal-api.js
import http from "node:http";
import { readFile, writeFile } from "node:fs/promises";
const dbPath = "/tmp/state.json";
async function loadState() {
try {
return JSON.parse(await readFile(dbPath, "utf8"));
} catch {
return { tickets: [] };
}
}
async function saveState(state) {
await writeFile(dbPath, JSON.stringify(state, null, 2));
}
http
.createServer(async (req, res) => {
if (req.method === "GET" && req.url === "/tickets") {
const state = await loadState();
res.writeHead(200, { "content-type": "application/json" });
res.end(JSON.stringify(state.tickets));
return;
}
if (req.method === "POST" && req.url === "/tickets") {
let body = "";
req.on("data", (chunk) => (body += chunk));
req.on("end", async () => {
const payload = JSON.parse(body || "{}");
const state = await loadState();
const ticket = { id: crypto.randomUUID(), ...payload };
state.tickets.push(ticket);
await saveState(state);
res.writeHead(201, { "content-type": "application/json" });
res.end(JSON.stringify(ticket));
});
return;
}
res.writeHead(404);
res.end("not found");
})
.listen(8080, () => {
console.log("internal-api-ready");
});Validation
curl -s http://127.0.0.1:8080/tickets
curl -s -X POST http://127.0.0.1:8080/tickets -d '{"title":"Boot issue"}'Recipe B — Frontend + Runtime Bridge
Context
Your web app needs host diagnostics from PanOS runtime without exposing full system internals.
Backend Bridge
// /app/bridge.js
import http from "node:http";
import os from "node:os";
http
.createServer((req, res) => {
if (req.url === "/v1/diagnostics") {
res.writeHead(200, { "content-type": "application/json" });
res.end(
JSON.stringify({
node: process.version,
cpus: os.cpus().length,
loadavg: os.loadavg(),
uptime: process.uptime(),
})
);
return;
}
res.writeHead(404);
res.end();
})
.listen(8090);Frontend Client
// web/src/features/runtime/getDiagnostics.ts
export type RuntimeDiagnostics = {
node: string;
cpus: number;
loadavg: [number, number, number];
uptime: number;
};
export async function getDiagnostics(apiBase: string): Promise<RuntimeDiagnostics> {
const response = await fetch(`${apiBase}/v1/diagnostics`, {
headers: { accept: "application/json" },
});
if (!response.ok) {
throw new Error(`Diagnostics request failed: ${response.status}`);
}
return response.json();
}Recipe C — Batch Worker with Artifact Output
Context
You need deterministic batch processing and file artifact output from runtime jobs.
Worker
// /app/batch.js
import { readFile, writeFile } from "node:fs/promises";
const inPath = process.env.INPUT_FILE ?? "/tmp/input.ndjson";
const outPath = process.env.OUTPUT_FILE ?? "/tmp/report.json";
const lines = (await readFile(inPath, "utf8")).trim().split("\n");
const events = lines.map((line) => JSON.parse(line));
const byType = events.reduce((acc, event) => {
acc[event.type] = (acc[event.type] ?? 0) + 1;
return acc;
}, {});
const report = {
generatedAt: new Date().toISOString(),
total: events.length,
byType,
};
await writeFile(outPath, JSON.stringify(report, null, 2));
console.log("report-ready", outPath);Recipe D — CI Smoke Boot + API Assertion
Context
You want to fail CI early if runtime boot or API behavior changes unexpectedly.
Pipeline Script
#!/usr/bin/env bash
set -euo pipefail
./1-build.sh
timeout 80s ./2-run.sh > /tmp/boot.log 2>&1 || true
if ! grep -q "Shell Ready" /tmp/boot.log; then
echo "PanOS failed to boot"
cat /tmp/boot.log
exit 1
fi
echo "PanOS boot smoke passed"Optional Runtime API Contract Test
// tools/assert-runtime-contract.mjs
import assert from "node:assert/strict";
const response = await fetch("http://127.0.0.1:8080/runtime");
assert.equal(response.status, 200);
const body = await response.json();
assert.equal(typeof body.node, "string");
assert.equal(typeof body.uptimeSec, "number");
console.log("runtime-contract-ok");Recipe E — Embedded Gateway Loop
Context
You need a protocol bridge from local hardware reads to upstream cloud publishing.
Pattern
sensor read -> normalize -> buffer -> publish -> ack -> rotate logsGateway Core
// /app/gateway-core.js
import { appendFile } from "node:fs/promises";
function normalize(raw) {
return {
id: raw.id,
ts: Date.now(),
temperatureC: Number(raw.temp),
pressureKpa: Number(raw.pressure),
};
}
async function publish(event) {
await appendFile("/tmp/gateway.log", JSON.stringify(event) + "\n");
return true;
}
export async function processReading(raw) {
const event = normalize(raw);
const ok = await publish(event);
if (!ok) throw new Error("publish-failed");
return event;
}Recipe F — Plugin-Friendly Runtime App
Context
You want feature extensions without hardcoding every integration into core logic.
Plugin Host
// /app/plugin-host.js
import { readdir } from "node:fs/promises";
export async function loadPlugins(pluginDir = "/app/plugins") {
const entries = await readdir(pluginDir);
const plugins = [];
for (const entry of entries) {
if (!entry.endsWith(".mjs")) continue;
const module = await import(`${pluginDir}/${entry}`);
if (typeof module.setup === "function") {
plugins.push(await module.setup());
}
}
return plugins;
}Operational Notes
Resource Budgets
| Mode | Memory | CPU | Typical Use |
|---|---|---|---|
| API runtime | 512 MB–2 GB | 1–2 vCPU | Internal services |
| Batch worker | 256 MB–1 GB | 1 vCPU | Short-lived compute jobs |
| Gateway | 256 MB–512 MB | 1 vCPU | Device bridge |
Reliability Practices
- Keep startup idempotent.
- Use explicit retry budgets.
- Isolate external dependencies behind adapters.
- Emit machine-readable logs (
jsonlines).
Next Read
Proceed to 13-system-design-playbook.mdx for architectural trade-offs and design examples.