A self-hosted URL shortener running on a single GCP VM.
Shorten, redirect, and track clicks via a stateless ASP.NET Core API backed by Redis.
try it →
-
ASP.NET Core 9
minimal API, controllers
-
Redis 7
atomic SET NX, TTL, click counts
-
Docker
multi-stage build, non-root
-
Caddy
auto HTTPS, reverse proxy
-
GitHub Actions
build gate + SSH deploy
-
GCP Compute
Ubuntu VM, custom VPC, static IP
-
Rate limiting
10 req/min per IP → 429
-
Forwarded headers
correct scheme/host behind proxy
how it works
- POST /shorten — validates an absolute http/https URL (or a custom code matching
^[A-Za-z0-9_-]{1,32}$), generates a code, stores url:<code> in Redis with an optional TTL.
- GET /<code> — looks up the target and issues a 302 redirect, incrementing the click counter.
- GET /stats/<code> — returns metadata and the click count.
- Generated codes are a SHA-256 prefix reserved atomically with
SET NX; on collision the prefix extends (7–64 chars).
deployment
- Single VM runs two containers: the API and Redis, gated by a Redis healthcheck.
- Caddy terminates TLS and reverse-proxies
short.fahmykamal.site to the API; certificates are issued and renewed automatically.
- Pushes to
main run CI (compose validate + image build), then deploy over SSH only after the build passes.
- The API trusts proxy headers so generated short URLs are correct behind Caddy.
stack