VaultPi
My Raspberry Pi homelab and personal cloud: an NAS provisioned with IaC, an event-driven AWS photo pipeline, and zero inbound ports. This site is served from it.

- ROLE
- Solo: design, infrastructure as code, pipeline and ops
- RESULT
- Replaced iCloud for 14,000+ photos (300+ GB); reproducible from Terraform + 11 Ansible roles
- STATUS
- Running 24/7 (Sep 2025 – present)
- STACK
- AWSTerraformAnsibleDockerImmichTailscaleCloudflare Tunnel
- LINKS
- GitHub ↗
Quest briefing
Problem
Photos and files piled up on my laptop with no dedup, no tags and no backup. A Raspberry Pi already ran my personal services and sat mostly idle. I wanted a personal cloud I control, without opening my home network to the internet.

What I built
- Reproducible from code. The Pi is provisioned with Ansible (11 roles): Docker, HDD mount, Samba, Immich, n8n, Tailscale, monitoring, Watchtower and more. The AWS side (IAM, S3, DynamoDB, Lambda) is managed with Terraform.
- Event-driven AI photo pipeline. Photos sync from the local HDD to S3. Each upload triggers a Lambda that tags the photo (Rekognition) and embeds it (AWS Bedrock Titan), storing results in DynamoDB. Scripts built on top handle duplicate detection and text-to-photo search.
- Immich is the self-hosted photo app. It replaces iCloud with no storage cap or subscription.
- Zero inbound ports. Public services, including this portfolio, are exposed only through outbound Cloudflare Tunnels. Private services (the NAS, Immich, Grafana) are reachable only on the LAN or over Tailscale. Samba never touches the tunnel.
- Ops. Containers run under Portainer. Watchtower keeps images updated and posts to a Discord channel. Grafana dashboards cover the Pi, each container and the AWS side, with disk alerts before a mount fills.





Result
- 14,000+ photos (300+ GB) moved off iCloud onto hardware I own.
- 0 inbound ports open on the home network. You are reading this page through the same tunnel.
- The whole box can be rebuilt from the repo instead of from memory.
Loot (what was learned)
- Dedup exposed organizational debt, not just stray copies. Most duplicates were whole folders mirrored into each other.
- Raw object counts lie. Filter to the files you'll actually process before sizing the job.
- Outbound-only tunnels remove a whole class of attack surface.
- ARM quirks: not every container image runs well on a Raspberry Pi.
- DNS is always the problem. Even at home. Especially at home.