Snipe-IT Inventory System
Homelab application case study
Deploying Snipe-IT on TrueNAS SCALE
A self-hosted asset-management deployment built on my TrueNAS homelab using containers, persistent datasets, MariaDB, backup routines, and Cloudflare Tunnel for selected remote access.
Turning a homelab NAS into an asset-management platform.
This project documents a self-hosted Snipe-IT deployment running inside my TrueNAS SCALE environment. The objective was to build a realistic asset-management lab where I could practice application deployment, database administration, persistent storage, backup, permissions, and remote access.
Snipe-IT provides a structured way to track hardware, assignments, accessories, licenses, locations, and lifecycle information. In this homelab, it also serves as a practical environment for testing inventory workflows before applying similar concepts in operational IT.
The application runs on the same compact server as the rest of the homelab.
Application, database, storage, and access were treated as separate layers.
Create dedicated storage locations for application configuration, database data, and backups before starting the containers.
Run Snipe-IT and the MariaDB backend as separate containers using a Compose-based configuration.
Create the database, database user, password, and application connection parameters required by Snipe-IT.
Map application and database storage to the appropriate TrueNAS datasets so container recreation does not destroy persistent data.
Add the selected service to the Cloudflare Tunnel configuration, confirm HTTPS access, and test application behavior before considering the deployment complete.
Persistent application data is kept outside the containers.
The Snipe-IT application data is stored under a dedicated dataset in the TrueNAS pool. Database files are kept on SSD-backed storage for responsiveness, while backup data is handled separately from the running containers.
Application data
Permissions used in this lab
Three services make up the core deployment.
The web application responsible for asset, accessory, license, user, and lifecycle management.
Database backend used by the Snipe-IT application.
Outbound tunnel used to make the selected web service reachable remotely without direct router port forwarding.
Keep the application private by default and expose only what is required.
On the local network, Snipe-IT is accessed through the homelab infrastructure. Remote access is provided through Cloudflare Tunnel. I have intentionally removed the public Snipe-IT hostname from this version of the article because publishing an administrative endpoint adds little value to the technical case study.
The important design point is the access pattern: remote traffic is brokered through an outbound tunnel rather than by forwarding an application port directly from the internet to the NAS.
Application availability is only useful if the data can be recovered.
Most of the learning came from the failure modes.
The containers started, but the application could not authenticate to the database using the configured values.
After aligning the MariaDB database name, user, password, and Snipe-IT connection settings, the application loaded normally.
The TrueNAS dataset ownership did not initially match the user/group expected by the application runtime.
Ownership and file modes were adjusted for the affected datasets so the containers could read and write persistent data correctly.
The initial tunnel configuration did not correctly route the intended hostname to the local Snipe-IT service.
After fixing the tunnel configuration and service target, HTTPS access worked through the intended tunnel path.
A public login page is not the same thing as a secure deployment.
The next improvements are operational, not cosmetic.
The useful next phase is to improve identity, lifecycle automation, and recovery rather than simply adding more containers. Candidate improvements include directory integration, event-driven asset notifications, more formal database backup testing, and additional storage capacity when the data actually requires it.