A clean, modern, and professional portal designed to centralize access to all public services, demos, and internal infrastructure tools. Built with a focus on speed, clarity, and ease of maintenance.
- Categorized Dashboard: Automatically separates public-facing projects, live demos, and internal management tools.
- Liveness Monitoring: Integrated health-check system with real-time status indicators.
- Data-Driven: Easily maintainable via a single
services.jsonfile. - Modern UI: Apple-style "Soft UI" with staggered entry animations and tactile feedback.
- Personal Website - Modern personal platform and CMS.
- QRender - Artistic QR code generator.
- Markdown-to-PDF - Professional writing station.
- PDF Workspace - Unified PDF compression and management toolkit.
- Photo Portfolio - Travel photo portfolio with interactive world map and country-grouped timeline.
- Cloud Storage - Nextcloud (Alternative to Google Drive/iCloud).
- Image Service - Immich (Alternative to Google Photos).
- Online Office - OnlyOffice (Alternative to Google Workspace/M365).
- Line Service - Automated backup bot.
- NAS Storage - TrueNAS SCALE (Alternative to Synology/QNAP).
- Frontend: Vanilla HTML5, CSS3 (CSS Grid/Flexbox), Inter Font.
- Backend: Node.js + Express.js (serving static assets).
- DevOps: Docker, Shell Scripting, Git.
- Node.js (v20+) or Docker.
# Clone the repository
git clone https://github.com/Benedict-CS/portal.git
cd portal
# Install dependencies
npm install
# Start the dev server
npm startThe portal will be available at http://localhost:3000.
# Build the image
docker build -t benedict-portal .
# Run the container
docker run -d -p 3000:3000 --name my-portal benedict-portalUse the provided deploy.sh to update your running instance with the latest code from GitHub:
chmod +x deploy.sh
./deploy.shThe portal is data-driven — cards are rendered at runtime from services.json.
Add a new entry under the appropriate category:
{
"name": "Service Name",
"url": "https://service.example.com",
"description": "Short description of the service.",
"icon": "🚀"
}After deploying the updated file, the new card appears with a live status
indicator (the backend pings the URL via /api/health).
MIT