Deployment Guide
How to deploy OpenAVC to production hardware for your AV spaces.
For initial setup and testing, see Getting Started. This guide covers deploying to production.
Where OpenAVC Runs
OpenAVC runs on any hardware with Python 3.11+. Choose the deployment mode that fits your environment:
| Mode | Description | Best For |
|---|---|---|
| Windows PC | Install on a rack PC or mini PC using the Windows installer (.exe). Runs as a Windows service with a system tray app. | AV racks with a Windows PC, smaller installations |
| Linux Server | Install via script on any Linux machine. Runs as a system service. | IT-managed infrastructure, dedicated AV servers |
| Docker | One container per space, orchestrated with docker-compose. | Enterprise IT, multi-space servers |
| VM | Install in a virtual machine. One or many instances per VM. | Organizations with virtualization infrastructure |
| Mini PC / SBC | Dedicated hardware (NUC, mini PC, single-board computer). One instance per space. | Permanent installations, spaces needing serial/GPIO |
All modes are functionally identical. Serial port control (RS-232/485) requires physical hardware access or USB adapters. IP-only control works in all modes including Docker and VM.
Installation
See Getting Started for detailed installation steps. The short version:
git clone https://github.com/open-avc/openavc.gitcd openavcpip install -r requirements.txtcd web/programmer && npm install && npm run build && cd ../..Windows installer available: Download
OpenAVC-Setup-{version}.exefrom the GitHub Releases page. A Linux one-line install script is also in development.
Network Configuration
| Port | Protocol | Purpose |
|---|---|---|
| 8080 | HTTP/WS | Web UI, REST API, WebSocket |
Ensure port 8080 is accessible from:
- Touchscreens and tablets (Panel UI)
- Programmer workstations (Programmer IDE)
- Any external integrations using the REST API
For mDNS discovery (ISC), allow multicast traffic on the AV VLAN.
Data Directory
OpenAVC separates application code from user data. The application directory contains server code and built frontends. The data directory contains your projects, drivers, configuration, and backups. Updates replace application files but never touch the data directory.
Data directory locations by platform:
| Platform | Data Directory |
|---|---|
| Linux | /var/lib/openavc |
| Windows | C:\ProgramData\OpenAVC |
| Docker | /data (volume mount) |
| Development | ./data (relative to repo root) |
Override with the OPENAVC_DATA_DIR environment variable.
What lives in the data directory:
{data_dir}/├── projects/ # .avc project files + scripts├── drivers/ # Community and custom drivers├── backups/ # Automatic pre-update backups├── logs/ # Log files (rotated)├── system.json # System configuration└── update-cache/ # Downloaded update packages (temp)System Configuration
System-level configuration controls the server itself: networking, authentication, logging, updates, and cloud connectivity. It is separate from project configuration and stored in the data directory so it persists across updates.
Location: {data_dir}/system.json (created with defaults on first startup if missing).
{ "network": { "http_port": 8080, "bind_address": "127.0.0.1" }, "auth": { "programmer_password": "", "api_key": "", "panel_lock_code": "" }, "isc": { "enabled": true, "discovery_enabled": true, "auth_key": "" }, "logging": { "level": "info", "file_enabled": true, "max_size_mb": 50, "max_files": 5 }, "updates": { "check_enabled": true, "channel": "stable", "auto_check_interval_hours": 24, "auto_backup_before_update": true, "notify_only": false }, "cloud": { "enabled": false, "endpoint": "wss://cloud.openavc.com/agent/v1", "system_key": "", "system_id": "" }, "kiosk": { "enabled": false, "target_url": "http://localhost:8080/panel", "cursor_visible": false }}Configuration priority: Environment variables override system.json values. This lets Docker and CI environments inject config without modifying the file.
| system.json path | Environment Variable | Default |
|---|---|---|
network.http_port | OPENAVC_PORT | 8080 |
network.bind_address | OPENAVC_BIND | 127.0.0.1 |
auth.programmer_password | OPENAVC_PROGRAMMER_PASSWORD | "" |
auth.api_key | OPENAVC_API_KEY | "" |
auth.panel_lock_code | OPENAVC_PANEL_LOCK_CODE | "" |
logging.level | OPENAVC_LOG_LEVEL | info |
updates.check_enabled | OPENAVC_UPDATE_CHECK | true |
updates.channel | OPENAVC_UPDATE_CHANNEL | stable |
cloud.enabled | OPENAVC_CLOUD_ENABLED | false |
cloud.endpoint | OPENAVC_CLOUD_ENDPOINT | wss://cloud.openavc.com/agent/v1 |
You can also read and modify system configuration through the REST API:
GET /api/system/configreturns the current configuration (sensitive fields redacted)PATCH /api/system/configupdates individual sections and saves to disk
Bind address security: The default bind address is
127.0.0.1(localhost only). To allow network access from other devices, setbind_addressto0.0.0.0. When bound to0.0.0.0without authentication configured, the server logs a prominent warning at startup.
Updates
OpenAVC checks for updates automatically (every 24 hours by default) via the GitHub Releases API. No data is sent to GitHub.
Check for updates: GET /api/system/updates/check
When an update is available, the response includes the version, changelog, and whether the installation supports self-update.
Deployment types and update behavior:
| Deployment | Self-Update | What Happens |
|---|---|---|
| Windows installer | Yes | Downloads and runs new installer silently |
| Linux package | Yes | Downloads archive, replaces app directory, restarts service |
| Docker | No | Shows notification with docker compose pull command |
| Git/dev | No | Shows notification with git pull instructions |
Pre-update backups: Before applying any update, OpenAVC automatically backs up your projects, drivers, and system.json to the backups/ directory.
Rollback: If the server fails to start after an update, it automatically rolls back to the previous version. You can also manually rollback via POST /api/system/updates/rollback.
Linux Service
On Linux, OpenAVC runs as a systemd service that starts automatically on boot:
[Unit]Description=OpenAVC Room Control ServerAfter=network-online.targetWants=network-online.target
[Service]Type=execUser=openavcGroup=openavcWorkingDirectory=/opt/openavcExecStart=/opt/openavc/venv/bin/python -m server.mainRestart=alwaysRestartSec=5Environment=OPENAVC_DATA_DIR=/var/lib/openavcEnvironment=OPENAVC_LOG_DIR=/var/log/openavcNoNewPrivileges=trueProtectSystem=strictReadWritePaths=/var/lib/openavc /var/log/openavcProtectHome=truePrivateTmp=true
[Install]WantedBy=multi-user.targetEnable and start the service:
sudo systemctl enable openavcsudo systemctl start openavcDocker
Run OpenAVC in a container with persistent data stored in a named volume:
services: openavc: image: openavc/openavc:latest container_name: openavc ports: - "8080:8080" volumes: - openavc-data:/data restart: unless-stopped # For serial/USB device passthrough: # devices: # - /dev/ttyUSB0:/dev/ttyUSB0
volumes: openavc-data:docker compose up -d # Startdocker compose pull # Update to latestdocker compose up -d # Restart with new imageFor multi-space deployments, use separate containers with different ports and data volumes:
services: room-101: image: openavc/openavc:latest ports: ["8081:8080"] volumes: ["room-101-data:/data"] room-102: image: openavc/openavc:latest ports: ["8082:8080"] volumes: ["room-102-data:/data"]Touchscreen Kiosk Setup
For dedicated touchscreen displays, enable kiosk mode in system.json:
{ "kiosk": { "enabled": true, "target_url": "http://localhost:8080/panel", "cursor_visible": false }}On Linux with a desktop environment, the openavc-panel.service auto-launches Chromium in kiosk mode. The Raspberry Pi image includes this pre-configured. On other Linux installs, create the service manually:
[Unit]Description=OpenAVC Panel Kiosk DisplayAfter=openavc.service graphical.targetWants=openavc.service
[Service]Type=simpleUser=openavcEnvironment=DISPLAY=:0ExecStart=/opt/openavc/scripts/panel-kiosk.shRestart=on-failureRestartSec=10
[Install]WantedBy=graphical.targetThe panel-kiosk.sh script reads the kiosk settings from system.json, waits for the server to be ready, hides the cursor (for touch-only panels), and launches Chromium in fullscreen kiosk mode. Touch input via USB HID (including HDMI monitors with a USB touch cable) is handled by the Linux kernel automatically.
On the Raspberry Pi image, an openavc-info.service also displays the IP address and access URLs on the HDMI console at boot, so you can find the device on the network even without mDNS.
Authentication
OpenAVC supports optional authentication. When no credentials are configured, everything is fully open.
Authentication can be set via system.json or environment variables:
| Setting | Environment Variable | Purpose |
|---|---|---|
auth.programmer_password | OPENAVC_PROGRAMMER_PASSWORD | Password for the Programmer IDE and protected API routes (HTTP Basic auth) |
auth.api_key | OPENAVC_API_KEY | Alternative token-based auth via X-API-Key header |
auth.panel_lock_code | OPENAVC_PANEL_LOCK_CODE | Reserved for future panel lock screen |
When configured:
/api/status,/api/health, and/api/templatesremain open (no auth)- All other REST endpoints require HTTP Basic or
X-API-Key - The
/programmerstatic files require HTTP Basic credentials - Panel WebSocket connections remain open; programmer WebSocket connections require a
?token=query param orX-API-Keyheader - The Panel UI at
/panelis always accessible (it’s a touch screen, not a config tool)
Health Check
GET /api/health returns server health with no authentication required. Use this for monitoring tools, load balancers, and container orchestration health checks.
{ "status": "healthy", "version": "0.1.0", "uptime_seconds": 3600.5, "devices": { "total": 5, "connected": 4, "error": 1 }, "cloud": { "connected": true }}Security Notes
- Communication is HTTP by default, suitable for isolated AV VLANs
- HTTPS can be enabled with a reverse proxy (nginx, caddy) if needed
- ISC (inter-system communication) uses a shared auth key for system-to-system traffic
- The default bind address is localhost only. Change to
0.0.0.0in system.json when you need network access.
See Also
- Getting Started. Installation and first run
- Programmer Overview. IDE walkthrough