←

180° Fitness & Spa

The website and CMS for 180° Fitness & Spa in Jnah, Beirut: four levels of fitness, wellness, sport and spa, every section editable by the club's own team.

Train. Relax. Rejuvenate.

The website and CMS for 180° Fitness & Spa in Jnah, Beirut: four levels of fitness, wellness, sport and spa, every section editable by the club's own team.

live · Fitness · Next.js 16 · CMS

  • 13Public sections
  • 4Levels in the building
  • 1Admin CMS for the team
  • May → Sep 2026Built in
The 180° home page. Click to open.The 180° home page. Click to open.

Product developer, website and CMS

I built the gym's new website with its own admin. The site runs on a staging domain while the client's old site stays live, so the cutover is a decision, not an accident.

  • Next.js 16 site: fitness, classes, kids, events, spa, memberships, trainers, news, journal, locations, BMI, booking, contact
  • Admin CMS with media uploads for every section
  • Push-to-deploy to its own service, port and backups on a shared box

What it does

  1. 01

    Every part of the club

    Fitness, classes, kids, events, spa, memberships, trainers, news and a journal, each its own section.

  2. 02

    Book a tour

    Booking and contact forms handled by server actions.

  3. 03

    BMI calculator

    A small tool on the site for members and visitors.

  4. 04

    CMS for the team

    An admin panel for news, trainers, gallery, classes and spa, with an image library.

How it was built

  1. Next.js 16 with SQLite

    Drizzle ORM over a local SQLite file, bcrypt for admin passwords and sharp for images. The data never touches the Postgres that other sites on the same box share.

  2. Uploads that actually serve

    Next only serves public files that existed at build time, so runtime uploads 404ed. Uploads now stream from disk through a route handler that checks the resolved path stays inside the uploads folder and only serves allowed types.

  3. Isolated on a shared box

    Its own systemd unit, port, app folder, backups and nginx vhost. A push to main rsyncs the source, keeps the database and uploads, runs the deploy script and checks the public URL returns 200.

Stack

Site
Next.js 16, Drizzle ORM, SQLite through libsql, bcryptjs, sharp.
Hosting
nginx and systemd on a shared box, deployed by GitHub Actions.