{ url shortener }
← back

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

  • C# 13 / .NET 9
  • ASP.NET Core
  • StackExchange.Redis
  • Docker & Compose
  • Caddy
  • GitHub Actions
  • Google Cloud Platform
  • Let's Encrypt