Deploy an always-on camera.ui server, protect its recordings, and verify remote access one feature at a time
camera.ui is a local-first surveillance platform that combines live viewing, recording, detection, search, notifications, and smart-home integrations on hardware you control. This tutorial installs the camera.ui server with Docker Compose, preserves its configuration and recordings outside the container, completes the guided onboarding process, and verifies that the deployment survives recreation. It then shows how to expose the verified web endpoint through a Localtonet HTTP tunnel. Web access and live-media compatibility are tested separately because camera.ui can use WebRTC, MSE, two-way audio, and other real-time paths that are not proven merely by loading the interface.
๐ What's in this guide
What camera.ui is and where Docker fits
camera.ui is a self-hosted platform for security cameras. One camera.ui server connects to cameras, serves the web interface, runs enabled detection workloads, and handles recording when NVR functionality is configured. There is no mandatory cloud storage service, and camera.ui states that no third party has to hold a copy of your recordings. Remote access is optional.
The installation choices have distinct roles. Docker, Proxmox, and bare-metal Linux are server options intended for always-on deployments. The desktop application for macOS, Windows, and Linux combines a server and viewer in one application. The iOS and Android applications are viewers, not substitutes for the always-on camera.ui server. This tutorial uses Docker Compose on a Linux host because it makes the image, port, environment, and persistent paths explicit.
Free and subscription-backed functionality
The camera.ui core is free and open source under the MIT license. Live view and real-time detection are free. An active camera.ui subscription covers NVR recording and the features built on recorded material, including playback, export, face recognition, semantic search, and AI-generated descriptions. Push notifications are also covered by the subscription.
This boundary matters when planning a deployment. A working live stream does not establish that recording, playback, export, semantic search, face recognition, AI descriptions, or push notifications are available without an active subscription. It also does not prove that sufficient storage or processing capacity exists for those features.
The Docker baseline below uses the camera.ui container layout documented for the current installation flow reviewed in 2026: the camera.ui image, TCP port 8081, a configuration mount at /app/config, a recording mount at /recordings, and the TZ environment value. Before deploying a later release, compare these values with the current camera.ui documentation and release notes.
Prepare the Docker host and camera network
Use a Linux machine that can remain powered on whenever cameras, live viewing, recording, or remote access are expected to work. The current camera.ui documentation presents Docker as an always-on server option. Use a host architecture for which the current camera.ui image publishes a compatible build, and verify compatibility before changing hardware or image tags. Do not assume that an image downloaded for one CPU architecture can run on another.
Install a supported Docker Engine and the Docker Compose plugin so that the command docker compose is available. The available documentation does not establish a permanent minimum CPU, RAM, GPU, Docker Engine, or Compose version that is suitable for every camera count and feature set. Processing requirements vary with stream resolution, frame rate, codec, detection backend, camera count, and recording workload. Confirm release-specific requirements in the current camera.ui installation documentation.
Host prerequisites
- A Linux host with a CPU architecture supported by the selected camera.ui image.
- Docker Engine running successfully and a functional Docker Compose plugin.
- Administrative access to create the deployment and persistent data directories.
- A stable local IP address or local DNS name for the Docker host.
- Network reachability from the host to every camera that will be added.
- Persistent storage sized for configuration, recordings, retention, and temporary operating space.
- A separate backup destination that is not inside the camera.ui container.
- A local browser for guided onboarding and initial testing.
Confirm the Docker installation before creating the service:
docker --version
docker compose version
docker info
The final command may require administrative privileges depending on how Docker is configured. Resolve Docker daemon, permission, and storage-driver problems before installing camera.ui.
Camera prerequisites
Gather each camera's local address, supported connection method, and credentials. camera.ui supports ONVIF and dozens of other protocols, but individual camera capabilities differ. Enable the required protocol on the camera only if the camera manufacturer requires it, and verify that the Docker host can reach the camera over the local network.
Create a dedicated camera account where the camera supports multiple users. Grant only the permissions camera.ui needs. For example, a deployment that only consumes streams should not reuse the camera's unrestricted administrator account if a lower-privilege account can provide the required stream and control functions. PTZ, two-way audio, event retrieval, or camera-side configuration may require additional permissions, so test the intended functions after applying least privilege.
Estimate recording capacity
Continuous video can consume storage quickly. A practical estimate starts with the configured stream bitrate rather than resolution alone:
Approximate bytes per day = bitrate in bits per second ร 86,400 รท 8
Approximate retention capacity = usable recording bytes รท bytes per day
Apply the calculation to every continuously recorded stream and leave operating headroom. Variable-bitrate video, audio, event recording, exports, thumbnails, indexes, and filesystem overhead can change actual consumption. Measure the running installation instead of treating the estimate as a guarantee.
| Area | Requirement | Preflight check |
|---|---|---|
| Container runtime | Docker Engine and the Compose plugin | Run docker info and docker compose version. |
| Persistent configuration | A writable host directory mounted at /app/config |
Create it before startup and confirm it is not inside an ephemeral container layer. |
| Recordings | A writable host directory mounted at /recordings |
Check capacity, filesystem health, backup policy, and physical access controls. |
| Web interface | Host TCP port 8081 available for container TCP port 8081 | Confirm another service is not already using the port. |
| Camera network | Local reachability and dedicated camera credentials | Test from the Docker host and review VLAN or firewall policies. |
| Time zone | A valid TZ value for the deployment location |
Use the correct region and city value so event times are understandable. |
This tutorial publishes only the camera.ui web endpoint. Do not tunnel a camera's administration page, the Docker API, a container-management dashboard, SSH, a database, or the Docker socket as part of this deployment. The Docker socket is a host-level trust boundary and must never be mounted into camera.ui unless current primary documentation explicitly requires it.
Install camera.ui with Docker Compose
The following deployment keeps the Compose file, application configuration, and recordings under one clearly identified project directory. For a production system, the recording directory may instead be placed on a dedicated disk and referenced with an absolute host path. Whatever location you choose, preserve the container destinations exactly.
Create the deployment directories
Create a project directory with separate subdirectories for camera.ui configuration and recordings. These host paths preserve state when the container is replaced.
Create the Compose definition
Use the official camera.ui image, publish TCP port 8081, mount configuration at /app/config, mount recordings at /recordings, and set the deployment time zone.
Validate the resolved configuration
Ask Docker Compose to parse the file before downloading or starting anything. Review the image, port, mounts, restart policy, and time zone in the resolved output.
Pull and start camera.ui
Download the configured image and start the service in detached mode. Keep the initial logs open while camera.ui creates its persistent state.
Open the exact local endpoint
On the Docker host, open http://localhost:8081. From another LAN device, use http://DOCKER-HOST-IP:8081.
1. Create the directories
mkdir -p "$HOME/camera-ui/config"
mkdir -p "$HOME/camera-ui/recordings"
cd "$HOME/camera-ui"
Docker must be able to write to both directories. The camera.ui Docker instructions reviewed for this tutorial do not define portable PUID or PGID environment variables, so do not add LinuxServer-style identity settings by assumption. Start with directories owned by the account administering this Compose project. If the container reports a write failure, inspect the effective container identity and correct only the affected host directory rather than making it world-writable.
ls -ld "$HOME/camera-ui/config" "$HOME/camera-ui/recordings"
2. Create compose.yaml
Replace Europe/Berlin with the valid time-zone value for the server's location:
services:
camera-ui:
image: ghcr.io/cameraui/camera.ui:latest
container_name: camera.ui
restart: always
environment:
TZ: Europe/Berlin
ports:
- "8081:8081"
volumes:
- ./config:/app/config
- ./recordings:/recordings
The left side of each volume mapping is the host path. The right side is the path inside the camera.ui container. Do not reverse them. If recordings belong on another disk, replace only the left side with an absolute host path:
- /srv/camera-ui-recordings:/recordings
Do not place the Compose project or recording directory in a temporary filesystem. If you use network-attached storage, confirm its behavior under disconnects and ensure camera.ui does not begin writing large amounts of data to an unintended local mount point when the remote filesystem is absent.
3. Validate and start the service
docker compose config
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=200 camera-ui
The service should remain running. Read the first meaningful error if it exits or restarts. Repeatedly issuing docker compose up will not repair an invalid mount, occupied port, unsupported image architecture, or unwritable directory.
4. Open camera.ui locally
On the Docker host, open:
http://localhost:8081
From another trusted device on the same LAN, replace the placeholder with the Docker host's local IP address:
http://DOCKER-HOST-IP:8081
Do not substitute a camera's address. Port 8081 belongs to the camera.ui web service in this Compose deployment. If you intentionally change the host side of the mapping, such as 9081:8081, the LAN endpoint becomes http://DOCKER-HOST-IP:9081, while the internal container port remains 8081.
Complete onboarding, camera configuration, authentication, restart testing, and persistence verification before creating a public URL. A tunnel cannot correct an unhealthy container or a broken camera path.
Complete guided onboarding and add a camera
The first browser visit starts camera.ui's guided setup. Follow the prompts shown by the installed release. Create a strong, unique master password and store it in a password manager. Enable two-factor authentication when offered and appropriate for your access model. Do not reuse a camera password, Wi-Fi password, Docker registry credential, or Localtonet device token.
Add the first camera safely
Before adding a camera, confirm that its clock is correct, its firmware is maintained, and its local address is stable. Prepare a dedicated camera account with only the permissions needed for the intended stream, PTZ, audio, or event functions. camera.ui can connect through ONVIF and other protocols, but the camera manufacturer determines which services must be enabled and which stream profiles are available.
In camera.ui, use the guided camera-addition flow or the corresponding camera settings in the installed release. Supply the camera's local address, protocol, and dedicated credentials. Select only streams and functions the camera actually supports. If discovery does not find a camera on a segmented network, that does not necessarily mean the stream is unreachable. Discovery traffic and direct camera traffic can be treated differently by VLANs and firewalls.
Check live and subscription-backed functions separately
- Confirm that the live picture opens and remains stable.
- Test real-time detection separately if it is enabled.
- Test PTZ, snapshots, and two-way audio only on cameras that support those capabilities.
- If an active subscription is configured, verify recording, playback, and export independently.
- Verify face recognition, semantic search, AI descriptions, and push notifications only if those subscription-backed features are configured.
- Check plugin status and compatibility before treating the installation as complete.
A successful live view does not prove that recordings are being written. Likewise, a timeline entry does not prove that a stored video can be played or exported. Exercise each capability that matters to your deployment.
Camera placement, audio capture, face recognition, license-plate processing, employee monitoring, public-area recording, retention, and remote viewing may be regulated. Obtain required consent, provide notices where applicable, restrict collection to a legitimate purpose, and follow the surveillance and privacy laws that apply in your location. Technical access does not create legal authorization.
Verify local health, recordings, and persistence
Inspect container health and logs
cd "$HOME/camera-ui"
docker compose ps
docker compose logs --tail=200 camera-ui
docker stats camera.ui
Confirm that the service remains up and is not repeatedly restarting. Logs should not show recurring permission, database, camera connection, or storage errors. Resource use will vary with the number of cameras and enabled workloads, so establish a normal baseline for your own installation.
Inspect mounts and free space
docker inspect camera.ui --format '{{json .Mounts}}'
df -h "$HOME/camera-ui/config" "$HOME/camera-ui/recordings"
du -sh "$HOME/camera-ui/config" "$HOME/camera-ui/recordings"
The mount inspection should show the intended host paths attached to /app/config and /recordings. Check free space on the actual filesystems, not merely on the root filesystem. If recordings use a dedicated disk, verify that the disk is mounted before camera.ui starts.
Recreate the container without deleting data
Once onboarding and a basic camera test are complete, recreate the container:
docker compose up -d --force-recreate
docker compose ps
docker compose logs --tail=100 camera-ui
Sign in again and confirm that the account, settings, cameras, and intended persistent data remain present. This test proves that important state is not stored only in the disposable container layer.
Do not use docker compose down -v during routine testing. The -v option removes named volumes associated with a project. This deployment uses bind mounts, but avoiding destructive volume flags is still a sound operating habit.
Application-level verification checklist
http://localhost:8081opens on the Docker host.http://DOCKER-HOST-IP:8081opens from an authorized LAN device.- The master account can sign in after container recreation.
- Configured live streams remain stable for a meaningful test period.
- Enabled PTZ, snapshots, or two-way audio work as expected.
- Subscription-backed recordings are written to the intended storage.
- A stored recording can be played and, if required, exported.
- The recording filesystem has sufficient free capacity.
- No persistent permission or connection errors appear in the logs.
Expose the camera.ui web endpoint with Localtonet
After local verification, a Localtonet HTTP tunnel can expose the camera.ui web endpoint. Our client establishes an outbound connection to a Localtonet relay, so this workflow does not require inbound router port forwarding, a public IP address, firewall changes, or VPN setup.
This claim is deliberately limited to the web endpoint. camera.ui documents WebRTC and MSE streaming, along with two-way audio, PTZ, push notifications, and other interactive behavior. Loading the HTML interface through an HTTP tunnel does not prove that every media transport, peer-to-peer path, notification mechanism, or auxiliary connection will work through that configuration.
Install and run the Localtonet client
Run our client on the Docker host or another trusted device that can open the verified camera.ui LAN endpoint. The selected client must remain connected whenever the tunnel is needed.
Select the authenticated device
Select the device-specific token for the client that will carry the tunnel. Treat the token as a credential and never publish it in Compose files, screenshots, logs, or support posts.
Select an available relay server
Choose a server or region currently offered in the Localtonet dashboard. Do not copy a server code from an unrelated or outdated tutorial.
Create an HTTP tunnel
Set the local target to the Docker host address and host-side port 8081. If the Localtonet client runs on the Docker host, use a host-reachable local address. If it runs elsewhere, use the Docker host's LAN address.
Choose the process type and start the tunnel
Select an available Random Sub Domain, Custom Sub Domain, or Custom Domain process type, then press Start. Creating a tunnel does not start it. These HTTP process types serve the target at a public HTTPS address.
Test from a genuinely external network
Disable Wi-Fi on a test phone or use another external connection. Open the assigned URL, authenticate, and test the interface and each required real-time capability separately.
The current Docker and getting-started material reviewed for this tutorial does not prescribe a separate camera.ui environment variable solely for opening the web interface through this HTTP tunnel. Do not invent a public URL, trusted-proxy, WebRTC, or forwarded-header setting. If a later camera.ui release documents a proxy or external-URL setting for the selected media mode, apply the release-specific instruction and retest locally before restarting public access.
For current Localtonet dashboard details, see our HTTP tunnel documentation. Custom-domain DNS values must come from the current dashboard and documentation rather than an old deployment.
External-network test matrix
| Capability | How to test | What the result proves |
|---|---|---|
| Web interface | Open the public HTTPS URL and sign in. | The HTTP endpoint and application login are reachable. |
| Live video | Open each required stream and observe it for a sustained period. | That stream and its selected transport work in the tested browser and network. |
| WebRTC and MSE behavior | Test the modes exposed by the installed camera.ui release. | Only the specifically tested mode is confirmed. One mode succeeding does not validate the other. |
| Two-way audio | Test microphone permission, outgoing audio, and return audio. | The camera, browser, permissions, and remote path support the tested audio workflow. |
| Playback and export | Open a stored recording and complete a small export. | The subscription-backed NVR path works remotely for that test. |
| Push notifications | Generate an authorized test event and observe delivery. | The configured notification workflow works. Loading the website alone does not prove this. |
An HTTP tunnel verifies access to camera.ui's web endpoint. WebRTC can involve connection behavior beyond ordinary page delivery, and other real-time features may use separate paths. Record the browser, network, camera, media mode, and feature tested. If a required function fails, stop public access while reviewing current camera.ui proxy and streaming documentation.
Harden camera.ui, cameras, recordings, and remote access
Expose only camera.ui
Point the Localtonet HTTP tunnel only to camera.ui on the verified host port. Do not expose camera administration pages, Docker management interfaces, the Docker API, the Docker socket, host dashboards, databases, SSH, debugging ports, or plugin backends. Administrative services should remain on trusted management networks.
Use least-privilege identities
Use a unique camera.ui master password and enable two-factor authentication when supported by the installed release. Give camera.ui dedicated camera accounts instead of camera administrator credentials whenever the required functions allow it. Remove obsolete accounts and avoid sharing an unrestricted administrator identity among multiple people.
Protect configuration and recording data
The config directory may contain sensitive application state, camera addresses, account-related information, and integration configuration. The recordings directory contains surveillance footage and related material. Restrict host access, backup access, and physical access to both locations. Encrypt host disks and backup media when required by your threat model or applicable policy.
Backups can be more sensitive than the live system because they may preserve old recordings and credentials beyond their intended retention period. Apply a documented retention schedule and securely remove expired copies.
Protect the Localtonet token
A Localtonet device token identifies the client device. Do not place it in the camera.ui Compose file, public source control, screenshots, or shared logs. If exposure is suspected, replace the credential through the appropriate account workflow.
Keep remote access intentional
A Localtonet tunnel is available only while the selected client is connected and the tunnel is running. Stop a temporary tunnel when it is no longer required. Delete stale tunnel configurations and periodically verify that every active public endpoint still has an owner and a legitimate purpose.
Anyone who learns the public address can attempt to reach the login interface. Complete authentication setup before starting the tunnel, keep camera.ui and its plugins current, monitor logs, and stop the tunnel during account recovery or maintenance that creates a temporary weak state.
Back up, restore, update, and roll back the deployment
Create a consistent backup
The actual persistent paths in this deployment are $HOME/camera-ui/config and $HOME/camera-ui/recordings. The Compose file is also important because it records the image, environment, port, and mounts. For the most consistent filesystem copy, stop the service before archiving these paths:
cd "$HOME/camera-ui"
docker compose stop
tar -czf "$HOME/camera-ui-backup-$(date +%Y%m%d-%H%M%S).tar.gz" \
compose.yaml config recordings
docker compose start
docker compose ps
Recording archives can be very large. If recordings are protected by a different backup or retention system, back up the Compose file and configuration separately, then document exactly how recording data is protected. Do not silently omit recordings while calling the result a full backup.
Copy the archive to a separate protected destination and test that it can be listed:
tar -tzf "$HOME/camera-ui-backup-YYYYMMDD-HHMMSS.tar.gz"
Restore a backup
Stop camera.ui before replacing persistent data. Preserve the current directories until the restore has been verified:
cd "$HOME/camera-ui"
docker compose down
mv config config.before-restore
mv recordings recordings.before-restore
tar -xzf /path/to/camera-ui-backup-YYYYMMDD-HHMMSS.tar.gz
docker compose up -d
docker compose logs --tail=200 camera-ui
The archive must have been created with paths compatible with the current working directory. Verify login, camera configuration, recordings, playback, and free space before deleting the pre-restore copies. Do not restore untrusted archives because extracted paths and application data can affect the host and service.
Update camera.ui
Review the camera.ui release notes first. Back up persistent data, note the current image identity, and verify compatibility among camera.ui, the NVR plugin, AI backend, and other installed plugins.
cd "$HOME/camera-ui"
docker inspect camera.ui --format '{{.Config.Image}} {{.Image}}'
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=200 camera-ui
Test local login, live streams, detection, recording, playback, exports, plugins, and persistence before testing the Localtonet URL. If the local port or proxy behavior changes, update the tunnel target only after the revised local endpoint works.
The camera.ui 2.3.0 release specifically instructed users to update the NVR plugin and AI backend together with camera.ui for the release's search, tracking, re-identification, and segmentation behavior. That is a version-specific example of why coordinated components must be reviewed rather than upgraded independently.
Plan a rollback before pulling
The floating latest tag is convenient for installation but is not a reliable rollback identifier. Before updating, record the running image ID and the exact release tag or digest when one is available from the project's current release instructions. For controlled operations, replace latest in compose.yaml with an approved immutable version or digest.
If an update fails and the previous image is still present, restore the pre-update configuration backup if the new release migrated it incompatibly, set the Compose image back to the recorded previous version, and recreate the service:
docker compose down
docker compose up -d
docker compose logs --tail=200 camera-ui
Do not guess an old tag. A container rollback without a compatible data rollback may fail when application state has been migrated. Follow the release-specific migration guidance and preserve both the old data backup and image identity until the new deployment is accepted.
Monitor disk capacity and logs
df -h "$HOME/camera-ui/recordings"
du -sh "$HOME/camera-ui/recordings"
docker compose logs --since=24h camera-ui
Set an operating threshold that leaves enough space for ongoing writes, indexes, exports, and maintenance. If storage is unexpectedly growing, investigate retention and recording configuration rather than deleting unknown application files from inside the persistent directories.
Troubleshoot common camera.ui Docker problems
The image cannot be pulled
Confirm DNS, internet access, registry reachability, and the image reference in compose.yaml. An architecture error indicates that the selected image does not provide a compatible build for the host. Do not work around an architecture mismatch by downloading an unrelated community image without reviewing its provenance and configuration.
The container exits or restarts repeatedly
docker compose ps
docker compose logs --tail=300 camera-ui
Look for the first substantive error. Typical categories include unwritable mounts, unsupported architecture, malformed configuration, missing files, port conflicts, storage failure, or an incompatible plugin. Correct the underlying issue before restarting.
Port 8081 is already in use
Identify the existing listener. If it cannot be moved, change only the host side of the mapping:
ports:
- "9081:8081"
The local endpoint then becomes http://DOCKER-HOST-IP:9081, and Localtonet must target port 9081. The container still listens on port 8081.
The interface opens on the host but not another LAN device
Confirm that the second device is using the Docker host's LAN address rather than localhost. Check host firewall and network-segmentation policy. Do not disable the firewall broadly. Permit only the required source network and port if LAN access is intended.
The interface works but the camera does not
Verify the camera's address, dedicated account, enabled protocol, and stream profile. Confirm that the Docker host can reach the camera network. ONVIF discovery may not cross network boundaries even when a direct connection is possible, so test the documented direct-add method where appropriate.
Configuration disappears after recreation
Inspect mounts:
docker inspect camera.ui --format '{{json .Mounts}}'
Confirm that the expected host configuration directory is mounted at /app/config. If the deployment previously ran without the mount, data may exist only in the old container layer. Do not remove the old container until recoverable data has been assessed.
Recordings are missing or the disk fills
Confirm that /recordings maps to the intended host filesystem and that the filesystem was mounted before camera.ui started. Check recording and retention settings, then inspect capacity with df and consumption with du. Avoid manually deleting database or index files whose purpose is unknown.
The Localtonet page opens but live video does not
First verify the same stream from a LAN browser. Then test the media modes made available by the installed camera.ui version. A successful web login proves the HTTP endpoint, not every WebRTC, MSE, audio, or peer-to-peer path. Review current camera.ui remote-access and proxy documentation for the installed release before changing headers, public URLs, ICE behavior, or media settings.
The public URL does not open
Check the dependency chain in order: camera.ui is running, the exact target opens from the Localtonet client device, the correct Localtonet device is connected, the selected relay is available, the target IP and port are correct, and the tunnel has been started. Creating a tunnel alone does not make it active.
The browser says it cannot reach the home server after an update
Test locally and inspect logs first. For camera.ui 2.3.0 specifically, the release notes documented stale browser site data after updating behind Pangolin, Authelia, or another login proxy. Clearing site data allowed the proxy to request authentication again and load the new version. This is a version-specific remedy, not a universal fix for server connectivity failures.
The master password is forgotten
Use the recovery documentation for the exact installed release. camera.ui 2.3.0 introduced a documented procedure in which an authorized administrator creates an empty file named reset-password in camera.ui's volume folder and restarts camera.ui. In that release, the master account can then sign in with admin, choose a new password, and two-factor authentication is disabled.
For this Compose layout, the host directory corresponding to the camera.ui configuration volume is $HOME/camera-ui/config. Because recovery behavior can change after 2.3.0, confirm the current camera.ui sign-in recovery page before using this procedure on a later release.
Stop the Localtonet tunnel before password recovery. Perform the reset from the trusted LAN, immediately replace the temporary admin password, re-enable two-factor authentication, remove the reset marker if the installed documentation requires it, restart camera.ui, and verify local sign-in before restoring remote access.
Frequently asked questions
What URL opens this camera.ui Docker installation?
Open http://localhost:8081 on the Docker host or http://DOCKER-HOST-IP:8081 from another authorized LAN device. If you change the host side of the Compose port mapping, use that replacement host port.
Where does this deployment store camera.ui data?
The tutorial stores configuration in $HOME/camera-ui/config, mounted at /app/config, and recordings in $HOME/camera-ui/recordings, mounted at /recordings. Back up both paths and the Compose file according to the data you need to recover.
Are the camera.ui mobile apps server installation options?
No. The iOS and Android applications are viewers. Docker, Proxmox, and bare-metal Linux are camera.ui's always-on server options. The desktop application combines a server and viewer.
Which camera.ui features require a subscription?
Live view and real-time detection are free. An active subscription covers NVR recording and features built on it, including playback, export, face recognition, semantic search, and AI descriptions. Push notifications also require an active subscription.
Does camera.ui require cloud storage?
No mandatory cloud is required, and camera.ui states that no third party has to hold a copy of your recordings. You remain responsible for local storage, backups, retention, access control, and legal compliance.
Which Localtonet tunnel type should I use?
Use an HTTP tunnel for the camera.ui web endpoint and target the Docker host's verified host-side port. This exposes the web interface, but it does not by itself guarantee that every WebRTC, MSE, audio, notification, or peer-to-peer function will work.
Do I need router port forwarding?
No. The Localtonet client creates an outbound connection to our relay infrastructure, so this workflow does not require inbound router port forwarding, firewall changes, VPN setup, or a public IP address. The selected client and tunnel must remain running.
Can Localtonet run on another device?
Yes. The selected Localtonet device must be able to reach http://DOCKER-HOST-IP:8081 over the local network. Test that exact endpoint from the client device before creating the tunnel.
How do I know the deployment will survive an update or recreation?
Inspect the mounts, back up the configuration and recordings, run docker compose up -d --force-recreate, and verify that accounts, cameras, settings, and intended recordings remain available. Record the current image version or digest before updating so rollback is possible.
Connect your verified camera.ui web interface with Localtonet
Finish camera.ui onboarding, secure the accounts, confirm persistent storage, and test every required camera function locally. Then create a Localtonet HTTP tunnel to the verified Docker host and port, and validate web and media behavior from an external network.
Get Started Free โ