Important
Hosted website: server.giraycoskun.dev
Tip
Features
- Responsive landing page for self-hosted services and personal projects
- Live service reachability badges with
Running,Offline, andWaitingstates - Searchable Port Mapper view at
/ports - Searchable Bash Commands Reference view at
/commands - Separate local and external builds backed by different JSON datasets
- Lightweight deployment pipeline using GitHub webhooks, Express,
systemd, and Nginx - Nginx routing that serves
dist-localordist-externalbased on request origin
server.giraycoskun.dev is a React + Vite + TypeScript dashboard for a home server. It exposes self-hosted services, personal projects, utility pages, and a small deployment webhook used to rebuild the site after GitHub pushes.
The frontend currently uses:
src/data/data-local.jsonfor the local-network versionsrc/data/data-external.jsonfor the public version
Current content snapshot:
- Local build: 18 services and 6 projects
- External build: 9 services and 6 projects
- Main routes:
/,/ports,/commands
- React 19
- Vite 7
- TypeScript 5
- Tailwind CSS 4
- React Router 7
- Express 5 for the webhook listener
- Nginx for TLS termination, reverse proxying, and static file serving
| Route | Purpose |
|---|---|
/ |
Landing page for services and projects |
/ports |
Searchable port-to-service and port-to-project mapping |
/commands |
Searchable Linux and bash command reference |
/webhook |
GitHub webhook endpoint proxied to the Express server |
/webhook/health |
Health endpoint for the webhook service |
- Node.js 24+ recommended
pnpm
pnpm installpnpm dev| Command | Description |
|---|---|
pnpm dev |
Start the Vite development server |
pnpm build |
Run TypeScript build and create the default production bundle |
pnpm build:local |
Build the local-network version into dist-local |
pnpm build:external |
Build the public version into dist-external |
pnpm preview |
Preview the built frontend |
pnpm lint |
Run ESLint |
pnpm start |
Start the Express webhook server from src/server/webhook.tsx |
The frontend chooses its data source using VITE_ENV.
.env.local
VITE_ENV=local.env.external
VITE_ENV=externalThe webhook server also needs runtime secrets and deployment credentials. Provide them through a systemd EnvironmentFile such as /etc/webhook-server.env instead of hardcoding values in commands:
WEBHOOK_SECRETGITHUB_TOKENPORT(optional, defaults to9000)
| Path | Purpose |
|---|---|
src/App.tsx |
Main router and landing page |
src/pages/ports.tsx |
Port Mapper page |
src/pages/commands.tsx |
Bash Commands Reference page |
src/data/data.tsx |
Loads environment-specific JSON data |
src/data/data-local.json |
Local-network services and projects |
src/data/data-external.json |
Public-facing services and projects |
src/util/check.tsx |
Client-side URL reachability checks |
src/server/webhook.tsx |
Express webhook listener |
src/server/build.sh |
Deployment build script |
nginx.conf |
Nginx configuration for serving and proxying |
This project intentionally generates two frontend outputs:
dist-localfor requests coming from the home networkdist-externalfor public requests
At runtime:
- Nginx classifies the request as local or external.
- It maps the request to the correct build directory.
- The frontend loads the matching JSON dataset through
src/data/data.tsx.
This allows the public site to expose a reduced set of services while keeping the local dashboard more complete.
The deployed setup is intentionally lightweight:
- A push to GitHub triggers a webhook request to
/webhook. - Nginx forwards that request to the Express app on port
9000. src/server/webhook.tsxverifiesX-Hub-Signature-256.- The webhook server runs
src/server/build.sh. - The build script fetches the latest changes, installs dependencies, and rebuilds both frontend variants.
- Nginx continues serving
dist-localordist-externalbased on the incoming client.
Current build script flow:
git fetch ...
git pull ...
pnpm install
pnpm build:local
pnpm build:externalThe repository includes an Nginx configuration that:
- redirects HTTP to HTTPS
- uses a Cloudflare origin certificate
- trusts
CF-Connecting-IPfor request origin detection - proxies
/webhookto the local Express listener - switches the site root between
dist-localanddist-external
Typical deployment steps:
sudo cp nginx.conf /etc/nginx/sites-available/default
sudo nginx -t
sudo systemctl reload nginxExample systemd unit name:
/etc/systemd/system/server-webhook.service
Example service definition:
[Unit]
Description=GitHub Server Webhook Listener
After=network.target
[Service]
Type=simple
User=giraycoskun
WorkingDirectory=/home/giraycoskun/Code/server.giraycoskun.dev/
ExecStart=/home/giraycoskun/.nvm/versions/node/v24.11.1/bin/pnpm start
Restart=always
Environment="PATH=/home/giraycoskun/.nvm/versions/node/v24.11.1/bin:/usr/local/bin:/usr/bin:/bin"
EnvironmentFile=/etc/webhook-server.env
StandardOutput=append:/var/log/server-webhook.log
StandardError=inherit
[Install]
WantedBy=multi-user.targetUseful commands:
sudo systemctl daemon-reload
sudo systemctl enable server-webhook
sudo systemctl restart server-webhook
sudo systemctl status server-webhook
journalctl -u server-webhook.service -n 50 -fLocal build:
External build:

