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 covering all four methods:
| Method | Install Command / Action |
|---|---|
| Windows Installer | Download from GitHub Releases and run the .exe |
| Docker | curl -fsSL https://raw.githubusercontent.com/open-avc/openavc/main/installer/docker-compose.yml -o docker-compose.yml && docker compose up -d |
| Linux | curl -sSL https://get.openavc.com | sudo bash |
| From Source | git clone, pip install, npm run build, python -m server.main |
Network Configuration
| Port | Protocol | Purpose | Required? |
|---|---|---|---|
| 8080 | HTTP/WS | Web UI, REST API, WebSocket | Yes |
| 19500 | HTTP/WS | Simulator UI (development/testing only) | No |
| 19872 | UDP | ISC auto-discovery (multi-instance setups only) | No |
Ensure port 8080 is accessible from:
- Touchscreens and tablets (Panel UI)
- Programmer workstations (Programmer IDE)
- Any external integrations using the REST API
For multi-instance setups using ISC auto-discovery, allow UDP broadcast on port 19872 within the same subnet. For cross-subnet ISC, configure peer addresses manually and allow TCP on each instance’s HTTP port.
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", "control_interface": "" }, "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": 1, "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 }, "tls": { "enabled": false, "port": 8443, "auto_generate": true, "cert_file": "", "key_file": "", "redirect_http": true }}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 |
network.control_interface | OPENAVC_CONTROL_INTERFACE | "" |
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 |
cloud.system_key | OPENAVC_CLOUD_SYSTEM_KEY | "" |
cloud.system_id | OPENAVC_CLOUD_SYSTEM_ID | "" |
tls.enabled | OPENAVC_TLS_ENABLED | false |
tls.port | OPENAVC_TLS_PORT | 8443 |
tls.auto_generate | OPENAVC_TLS_AUTO_GENERATE | true |
tls.cert_file | OPENAVC_TLS_CERT_FILE | "" |
tls.key_file | OPENAVC_TLS_KEY_FILE | "" |
tls.redirect_http | OPENAVC_TLS_REDIRECT_HTTP | true |
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) for Linux and from-source installations. The Windows installer and Docker pre-configure0.0.0.0(network-accessible) since these deployments typically serve touch panels on other devices. To allow network access, setbind_addressto0.0.0.0in system.json or via theOPENAVC_BINDenvironment variable. When bound to0.0.0.0without authentication configured, the server logs a prominent warning at startup.
Updates
OpenAVC checks for updates automatically (every hour 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, writes instruction file, restarts. A helper script applies the update before the service starts. |
| 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/openavcEnvironment=OPENAVC_PROJECT=/var/lib/openavc/projects/default/project.avcEnvironment=OPENAVC_BIND=0.0.0.0NoNewPrivileges=trueProtectSystem=strictReadWritePaths=/var/lib/openavc /var/log/openavc /opt/openavc/driver_repo /opt/openavc/plugin_repoProtectHome=truePrivateTmp=true
[Install]WantedBy=multi-user.targetEnable and start the service:
sudo systemctl enable openavcsudo systemctl start openavcDocker
Download the maintained compose file and start the container. This is the supported install path — the compose file pins the network and capability settings discovery needs, so don’t try to translate it back into docker run flags or strip pieces out:
curl -fsSL https://raw.githubusercontent.com/open-avc/openavc/main/installer/docker-compose.yml -o docker-compose.ymldocker compose up -d # Startdocker compose pull # Update to latestdocker compose up -d # Restart with new imageFor serial/USB device passthrough, uncomment the devices: block in the compose file.
Why the compose file uses host networking and NET_RAW
Device discovery, mDNS, and SSDP all need the container to be reachable on, and able to send packets to, the same physical network as your AV equipment. With Docker’s default bridge network the container sits behind NAT on a private 172.x subnet and cannot see your LAN, so scans return zero devices. network_mode: host puts the container directly on the host’s network stack so discovery works. cap_add: NET_RAW lets OpenAVC’s unprivileged user run the ICMP ping sweep that finds live hosts.
Docker Desktop on Windows or Mac
Docker Desktop runs the Linux container inside a WSL2 (Windows) or HyperKit (Mac) virtual machine that does not share the host’s LAN, so device discovery cannot work even with network_mode: host. If you need discovery on Windows or Mac, use the native installer instead. Docker Desktop is fine for evaluating the software or for IP-only deployments where you’ll add devices manually.
Multi-space deployments
For multiple rooms on a single host, use separate containers with different ports and data volumes. Multi-room layouts must use bridge networking (host mode would conflict on port 8080), which means device discovery is not available in multi-room mode and devices must be added manually by IP. If discovery matters, run one OpenAVC container per physical host using the single-room compose above, or set up macvlan networking so each container gets its own LAN IP.
services: room-101: image: ghcr.io/open-avc/openavc:latest ports: ["8081:8080"] volumes: ["room-101-data:/data"] room-102: image: ghcr.io/open-avc/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
Authentication is optional. When the server is only accessible locally (bind address 127.0.0.1), no credentials are needed. When the server is accessible on the network (0.0.0.0), you should set at least a programmer password to prevent unauthorized changes to your project.
The Panel UI is never password-protected. End users can always open the touch panel without logging in.
When to set each credential
| Setting | Environment Variable | When to use it |
|---|---|---|
auth.programmer_password | OPENAVC_PROGRAMMER_PASSWORD | Set this when the server is network-accessible and you want to prevent other people on the network from opening the Programmer IDE and modifying your project. The browser will prompt for a password. This is for humans logging in via a browser. |
auth.api_key | OPENAVC_API_KEY | Set this if you have third-party integrations (control scripts, middleware, or external software) that connect to the OpenAVC REST API or WebSocket. Provide the key to those systems via the X-API-Key header. Not needed unless you are building custom integrations. |
auth.panel_lock_code | OPENAVC_PANEL_LOCK_CODE | Set this if the panel runs on a public-facing display and you want to prevent users from navigating away from the touch panel UI. |
You do not need to set both programmer password and API key. Either one protects the Programmer IDE and API. The password is for humans (browser login), the API key is for machines (HTTP headers). If both are set, either credential is accepted.
What gets protected
When at least one credential is configured:
/api/status,/api/health, and/api/libraryremain 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)
HTTPS
HTTPS is off by default. OpenAVC typically runs on an isolated AV VLAN where plain HTTP is the convention (Crestron and Extron web UIs also default to HTTP). Turn HTTPS on when you need it: corporate or higher-ed networks that block HTTP, public Wi-Fi between the panel and the server, or browser features that require a secure context (clipboard, notifications).
Enabling from the Programmer IDE
The supported path:
- Open the Programmer IDE and go to Settings > Security.
- Toggle Enable HTTPS on.
- Leave Auto-generate (recommended) selected unless your organization has its own CA.
- Click Save.
- Restart the server (the banner tells you a restart is required).
- Reopen the IDE at
https://<host>:8443/programmer. The browser shows a one-time warning the first time it sees the self-signed cert; click through, or install the CA cert on each device that needs warning-free access (see “Installing the CA” below).
The Security card shows live cert details (subject, issuer, fingerprint, SAN list, expiry, warnings) once the TLS listener is running.
Enabling without the IDE
For headless deployments, set the environment variables before starting the server:
export OPENAVC_TLS_ENABLED=trueexport OPENAVC_TLS_PORT=8443 # optional, defaults to 8443Or edit {data_dir}/system.json:
"tls": { "enabled": true, "port": 8443}Then restart the server. On first start with TLS on, OpenAVC generates a self-signed CA and server cert under {data_dir}/tls/. The cert is valid for 10 years and covers localhost, 127.0.0.1, the OS hostname, and every LAN IPv4 the host has at generation time. It is regenerated automatically if the primary local IP changes later.
Providing your own certificate
If your organization has an internal CA and you’d rather use a cert signed by it, switch to Use my own certificate in the IDE (or set tls.auto_generate to false in system.json) and point tls.cert_file / tls.key_file at the PEM files. Both must be absolute paths on the server’s filesystem. Wildcard certs work as long as the SAN matches the hostname clients use.
If the cert is missing, unreadable, malformed, or expired, OpenAVC refuses to start the TLS listener and writes a precise error to the startup log. It does not silently fall back to HTTP. Fix the cert configuration and restart.
HTTP-to-HTTPS redirect
When HTTPS is enabled, OpenAVC also runs a tiny HTTP listener on the original port (8080 by default) that 301/308-redirects every request to the HTTPS URL. This keeps old bookmarks, printed QR codes, and panel apps pointed at http:// working without any user action. Disable it in Settings > Security if you want to take port 8080 down entirely.
Installing the CA on panel devices
Auto-generated certs are signed by an internal CA that no client trusts out of the box. Until you install the CA, browsers and the panel apps show a warning. To install it warning-free:
- From any browser on the same network, visit
https://<server>:8443/api/certificate(no auth required) — or click Download CA certificate in Settings > Security. - Transfer the downloaded
openavc-ca.crtto the panel device (email, AirDrop, USB). - iOS: open the file, then Settings > General > VPN & Device Management > Install Profile. After install, also enable trust under Settings > General > About > Certificate Trust Settings.
- Android: open the file via Settings > Security > Encryption & credentials > Install a certificate > CA certificate (path varies by manufacturer).
- Windows / macOS / Linux: add the cert to the system trust store (or browser trust store, depending on the browser).
Once the CA is trusted, future cert regenerations (e.g., the server gets a new LAN IP) keep working without re-installing trust.
Reverse-proxy deployments
If you front OpenAVC with nginx, Caddy, or another reverse proxy that terminates TLS for you, leave OpenAVC’s tls.enabled at false and let the proxy do the work. Set tls.redirect_http to false if you want OpenAVC to skip its own redirect listener (the proxy will handle that too).
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.5.2", "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 is available as a built-in opt-in (see the HTTPS section above). Auto-generated self-signed cert by default, or supply your own cert/key for environments with an internal CA. Reverse-proxy TLS is still supported for deployments that prefer it.
- ISC (inter-system communication) uses a shared auth key for system-to-system traffic, and switches to
wss://automatically when peers advertise HTTPS. - 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
- System Updates. Update management and rollback
- Network & Security Cut Sheet. IT network requirements and firewall rules
- Device Simulator. Test without real hardware