Three Months, One Industrial IoT System: Lessons from the Field

In three months, we went from prototype to field deployment…and survived 100°F heat, operating system quirks, and unexpected edge cases in the process.

During this quick-turn project, we designed, built, and deployed a production-ready IoT-like device using Balena, Docker, and industrial hardware. The system collects and processes high-resolution image data in the field, with full remote management and update capabilities.

Overall, things went smoothly. The core system came together quickly, and our architecture proved solid. But as always, real-world constraints introduced edge cases, and those cases taught us lessons we’ll carry into the next project.

1. Raspberry Pi 5: Excellent for Prototyping, Not for Harsh Environments

The Raspberry Pi 5 was our starting point. It gave us rapid iteration, a strong developer experience, and zero surprises on the software side. We had our FastAPI stack, PostgreSQL database, and camera processing pipeline running in Docker containers in no time.

But when we ran a heat-soak test simulating field conditions (~100°F ambient), things changed. The Pi throttled, peripherals dropped, and long-term stability became a concern, even with active cooling.

Lesson learned: Use the Pi to move fast, but validate your hardware against real-world thermal and electrical conditions early in the process.

2. Jetson Orin J4012: Industrial Stability with a Setup Curve

We migrated to the NVIDIA Jetson Orin J4012, an industrial-grade SBC built for harsh environments. It passed every thermal and performance test and handled our workload without issue. (It even came with its own thermal test report!)

The tradeoff: integration effort. BalenaOS required extra work to support nvpmodel, GPU drivers, static networking, and some low-level tuning. Nothing insurmountable, but more than a drop-in replacement.

Lesson learned: Industrial hardware gives you environmental confidence, but expect to invest time getting it production-ready.

3. Balena: Great Platform, Know Its Edges

Balena made remote management, OTA updates, and container orchestration painless. Being able to SSH into a unit in the field or push updates across the fleet with zero downtime was a huge win.

Where it got tricky: deeper system config. We ran into challenges with read-only filesystems, network settings (nmcli quirks), and custom boot behavior. Once we learned Balena’s mental model, things smoothed out, but it wasn’t all obvious.

Lesson learned: Balena’s strengths are in deployment and fleet control. For anything under the hood, read the docs twice and prototype config changes in isolation.

4. Docker: Clean Deployments, Persistent Gotchas

Our stack runs in containers: FastAPI for the web interface, PostgreSQL for metadata, and OpenCV-based image processing. Docker made deployments clean and consistent across devices.

Where things got messy: volume persistence and file permissions. Bind-mounts across containers, UID mismatches, and edge-case reboots exposed subtle bugs. None of it broke the system, but they slowed us down.

Lesson learned: Treat containers as ephemeral, but design your volumes and state management like they’ll be around forever.

5. Networking: Forget Wi-Fi. Go Wired or Go Home

In field deployments, the simpler the network setup, the better. Wi-Fi wasn’t reliable enough, so we went all-wired with static IPs and a controlled DHCP fallback.

Balena’s abstraction over NetworkManager worked—but scripting nmcli inside a container to ensure reliability across reboots required some care. Once it was stable, it stayed stable.

Lesson learned: Predictable networking beats smart networking. Define it. Test it. Lock it down.

6. Logging: Build Visibility from Day One

We routed logs through stdout so Balena could collect and stream them remotely. That covered most of our needs—but intermittent connectivity and bursty output exposed gaps. Local buffering and basic log rotation became essential once the system scaled.

Debugging got a lot easier once every container had structured, timestamped output, and we made sure nothing important was silently failing.

Lesson learned: Don’t wait until something breaks to care about logging. Observability is part of the system, not an add-on.

7. Team Process: Small, Focused, and Aligned

We worked in tight, two-week sprints with clearly defined goals and a great DevOps environment—leading up to deployment readiness. Everyone on the team was an owner, and that meant fewer meetings, faster decisions, and fewer dropped balls.

There wasn’t a lot of ceremony, but there was accountability. That made the difference.

Lesson learned: A small, committed team with shared ownership will outpace a larger, siloed one every time.

Conclusion

This project came together quickly, scaled well, and held up under field conditions, but that didn’t happen by accident. Early testing, choosing the right hardware, understanding our tools (especially Balena), and treating edge cases as part of the core system made the difference.

Key Lessons:

  • Test your hardware in real conditions early—lab success doesn’t guarantee field stability.
  • Industrial boards aren’t drop-in replacements—budget time for integration and low-level config.
  • Balena is powerful, but opinionated—understand its constraints before committing.
  • Containers are disposable—your data isn’t—design your volumes and state management accordingly.
  • Wired, static networking is your friend—predictability beats flexibility in the field.
  • Logging isn’t optional—build observability in from day one or regret it later.
  • Shared ownership accelerates progress—a small, aligned team moves faster than a large, divided one.

The next time we do this, we’ll carry those lessons forward (and maybe avoid a few of the surprises along the way).

Recommended blog posts