Skip to content

Repository files navigation

Watched

A full-stack movie / TV tracker web app, using the TMDB API.

TypeScript React Vite NestJS PostgreSQL Prisma Docker

Features

  • User accounts and profiles
  • Library: watched / to watch
  • Filter, sort and view library as grid/list
  • Collections: organize titles in collections
  • Visibilty: set library, collections and titles as public/private
  • Follow users and get updates on your feed
  • Rate titles and add comments
  • Search, get data and posters from TMDB

Stack

  • Frontend: React, Vite, Tailwind CSS
  • Backend: NestJS
  • Database: PostgreSQL
  • ORM: Prisma
  • Containerization: Docker, Docker Compose
  • Nginx
  • Cloudflare Tunnel (optional)
  • CI/CD: GitHub Actions, GHCR, webhook

Instructions

Requirements

  • Make
  • Docker
  • Docker Compose

Quick start

⚠️ A TMDB API key is required.

# copy and fill env
cp .env.example .env

# build and start dev
make dev

# build and start prod
make prod

Cloudflare Tunnel

Expose the app publicly via Cloudflare Tunnel.

Create a tunnel in Protect & Connect → Networking → Tunnels then add a "Published application" route to http://frontend:80.

# build prod and start tunnel
make cloud

⚠️ CLOUDFLARE_TOKEN needs to be filled in .env.

Optional: if you want to deploy via webhook, create a route to http://host.docker.internal:9000 that will be your public deploy URL and follow deployment setup instructions.

Commands

Command Description
make dev Build and start dev
make redev Rebuild and start dev
make prod Start prod
make cloud Prod + Cloudflare Tunnel
make deploy Deploy (cloud)
make down Stop all containers
make logs Logs
make shback Shell in backend container
make shdb Shell in db container
make prisma Prisma Studio (dev)

CI/CD

Push to main runs checks, builds Docker images, pushes them to GHCR, then auto-deploys on the production server via a webhook.

pipeline

Continuous Integration (CI)

  • Run checks: lint, typecheck, test and build, for frontend and backend.
  • Build and push: build images from Dockerfile.prod, tag :latest / :commit-sha then push to GHCR.

Continuous Deployment (CD)

  • Compute HMAC-SHA256 signature of the payload and send it to webhook.
  • Production server verifies signature, pulls the new images and restarts production.
  • ⚠️ Without DEPLOY_WEBHOOK_URL and WEBHOOK_SECRET set, the pipeline still builds and pushes images to GHCR but skips the deploy step.

Deployment setup

GitHub

Add these variables in Settings → Secrets and variables → Actions:

Name Type Value
DEPLOY_WEBHOOK_URL Secret e.g.: https://deploy.yourdomain.com/hooks/deploy-watched
WEBHOOK_SECRET Secret Same value as WEBHOOK_SECRET in .env

Note: To pull private images, create a GHCR PAT (scope: read:packages) at github.com/settings/tokens and auth to GHCR: docker login ghcr.io -u <username> -p <PAT>.

Production server

Requires webhook.

# create dedicated user
sudo adduser --system --group --home /opt/watched deploy
sudo usermod -aG docker deploy

# clone + configure
sudo -u deploy git clone https://github.com/jeromeberg/watched.git /opt/watched
cd /opt/watched
sudo -u deploy cp .env.example .env
# fill in .env (WEBHOOK_SECRET must match GitHub secret)

# install webhook
sudo apt update && sudo apt install -y webhook
sudo cp deploy/webhook.service /etc/systemd/system/webhook.service
sudo systemctl daemon-reload
sudo systemctl enable --now webhook.service

# first deployment
sudo -u deploy make deploy

Maintenance

# logs
journalctl -u webhook -f
tail -f /opt/watched/deploy/deploy.log

# rollback
make deploy IMAGE_TAG=<commit-sha>

About

A full-stack movie / TV tracker web app, using the TMDB API.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages