Portfolio & Project Management Platform
Designed and deployed a self-hosted project portfolio platform using Flask, Docker, Raspberry Pi, and Cloudflare Tunnel. The platform includes persistent project management, document uploads, administrative controls, and identity-protected remote access without exposing inbound ports on my home network.
Overview
I designed and deployed a self-hosted portfolio management platform to provide a centralized location for documenting and presenting my technical projects. Rather than using a traditional hosting provider, I deployed the application on a Raspberry Pi running Debian Linux in my home environment.
The application was developed in Python using Flask and provides a public-facing portfolio along with a private administrative interface for creating, editing, and deleting projects. Projects can contain descriptions, technology tags, screenshots, documentation, GitHub repositories, and external links.
The application is containerized with Docker and served using Gunicorn. Docker Compose manages the application configuration, persistent storage, environment variables, and automatic container recovery.
Infrastructure
The production application runs inside a Docker container on an Raspberry Pi. The container exposes the Flask/Gunicorn service only to the Raspberry Pi's localhost interface rather than directly to the local network or Internet.
Cloudflare Tunnel provides the external connection between the Raspberry Pi and Cloudflare's network. The tunnel establishes an outbound-only connection, allowing the portfolio to be publicly available without configuring router port forwarding or directly exposing the Raspberry Pi to inbound Internet traffic.
Cloudflare DNS maps the portfolio domain to the Cloudflare Tunnel, allowing visitors to access the application using its public HTTPS domain.
Security
Security was incorporated into the deployment architecture rather than added only at the application level. The Raspberry Pi does not accept direct inbound web connections from the Internet, and no HTTP/HTTPS ports were forwarded through the home router.
Administrative routes are protected by multiple authentication layers. Cloudflare Access performs identity-based authentication before requests to the /admin interface are forwarded through the tunnel. The Flask application then requires a separate administrative password.
Deployment and reliability
The application is managed using Docker Compose with an automatic restart policy. The Cloudflare Tunnel runs as a system service, allowing both the portfolio application and tunnel connection to automatically recover following a hardware reboot.
Development workflow
Source code is maintained using Git and GitHub. Development changes can be committed and pushed from my development environment, pulled onto the Raspberry Pi, and deployed by rebuilding the Docker container.
This separates application development from production deployment while providing version control and a repeatable deployment process.