Skip to content
CategoryWeb App
Skills
Next.js/Docker/Linux/Hono/Python

Dog Town Screenshot
DogTown Homepage

DogTown is a self-hosted photo-sharing app running on my Raspberry Pi. Naturally, the theme is dogs because dogs play a big part in my life. đŸ¶


Tech Stack

Diagram showing the tech stack powering this site
DogTown Diagram
LayerTechnology
OSRaspberry Pi OS (Debian GNU/Linux "trixie")
TunnelCloudflare Tunnel
WebNext.js, React, TypeScript, Tailwind CSS, shadcn/ui, Three.js, MDX, Drizzle ORM, NextAuth.js
DatabasePostgreSQL
AI ValidationPython, FastAPI, OpenNSFW, PyTorch
System ProfilerHono, TypeScript, Node.js
InfraDocker, Docker Compose, GitHub Actions, Bash/JavaScript helper scripts, NGINX (reverse proxy + caching)
AnalyticsUmami

Core

Full-stack Next.js app

DogTown is a full-stack Next.js app built with React + TypeScript, styled with Tailwind and shadcn/ui, and extended with MDX so I can write content while still embedding custom components. It includes authentication via NextAuth, a clean upload flow with client-side image compression, and a dashboard with live system metrics.

I treated it like a real production app: clear separation of concerns, robust design system, and optimized for performance. The result is something that feels snappy and “product-like,” even though it's running on a tiny computer in my house.

Database

DogTown uses PostgreSQL and Drizzle ORM to keep the schema and queries strongly typed. The data model is fairly simple, but it's easy to extend and modify as the project grows.


Supporting Services

AI Image Validation

To keep user-generated content on-brand and safe for all audiences, I created DogBot: a an AI image validation service. Built using:

  • OpenNSFW (inappropriate content detection)
  • PyTorch/TorchVision (verify images contain dogs)

It runs on a FastAPI server, processing images and returning isDog and isNSFW as scores/booleans. I designed it as a dedicated service so it could evolve independently from the web app.

apparently hammers are not dogs... thanks DogBot!

System Profiler

DogTown also includes a custom system-profiler service built with Hono + Node.js. It collects metrics from the PI and docker containers, which are fetched from the Next.js app streamed to the frontend in realtime.

This started as a way for me to look under the hood, but evolved into it's own page with a dashboard UI made with Recharts. I also added a 3D raspberry pi model using three.js for some visual flair.

DogTown Dashboard Screenshot
DogTown Dashboard

DevOps/Infra

Containerization

Everything runs in isolated Docker containers, wired together with Docker-Compose. This enables development, staging, and production environments to stay in sync. I also have a variety of utility scripts to help with things like manual deployments, updates, and maintenance.

This infrastructure speeds up development and deployment significantly and makes the app portable and easy to deploy across multiple environments.

CI/CD

I set up GitHub Actions to automate builds and deployments so updates are consistent and low-stress. The pipeline handles the typical steps—build, validate, and ship—so I'm not SSH'ing into the Pi at midnight to copy files around and hope for the best. It also nudged me toward better habits: keeping changes small, ensuring environments are deterministic, and treating deployments like a repeatable process rather than a one-off event.

In practice, it makes the project easier to maintain over time. If I can't deploy confidently, I stop shipping—so the CI/CD work is what keeps this hobby project alive.

Reverse Proxy & Caching

I added Nginx to cache images and other static assets. This was an easy way to reduce load on the Pi and improve the overall performance of the app.


Networking, Security, & Analytics

Secure Tunnel

DogTown is exposed to the internet through Cloudflare Tunnel, which means I didn't have to setup port forwarding on my router. It also provides some additional security and performance gains like DDoS protection and TLS/SSL termination.

Analytics

For analytics, I use Umami. This continues the theme of self-hosting and privacy-first. It's lightweight, privacy-friendly, and fits the self-hosted ethos of the project. It runs in a docker container and is accessible via a separate subdomain in the tunnel.


Final Thoughts

I learned a lot from this project—Docker, DevOps, Linux, bash scripting, networking, and more. If you happen to be looking for ideas for your next side-project, I'd highly recommend picking up a Raspberry Pi.

Thanks for reading! ❀

Back Home

Me with pups
Bonus: Me with some of my favorite pups