Skip to content
srphPublic

About

A personal Netflix clone with sync-play, invitation system, and chatting features.

Topics

Resources

Stars

39 stars

Watchers

6 watching

Forks

Repository files navigation

preview

Care.tv

Care.tv makes it really easy to enjoy movies or watch TV shows with the people you care about, no matter how far!

Targets modern stable desktop and mobile browsers. See MIGRATION.md for the browser policy, verification evidence, and existing limitations.

Quick start

Install Docker with Compose v2 and start its Docker engine. On macOS, the Makefile also uses Valet and nvm when available:

make install   # composer + npm dependencies, and creates missing .env files
make start:db  # start MySQL before running the database setup below
make start     # MySQL + API on http://localhost:8000 + web on http://localhost:8484

make install runs Composer through valet composer and npm through the Node version pinned in ui/.nvmrc, falling back to plain composer/node when Valet or nvm isn't around. It preserves existing .env files and stops at dependencies. Fill in the two .env files and run the database steps below (migrate, db:seed, passport:install) before using the app; the command prints these steps when it finishes.

Run each service separately with make start:api, make start:db, or make start:web. The original make start-api and make start-ui commands remain available, along with make install-api and make install-ui.

make start waits for MySQL to be healthy before launching both dev servers. Ctrl-C stops both dev servers. MySQL runs in the background; stop it with docker compose stop db. Its data persists in the mysql-data Docker volume.

Access from another Tailscale device

Start the app with make start (or keep your existing web and API servers running). In ui/.env, set TAILSCALE_HOST to this Mac's full Tailscale DNS name, without a trailing dot. Find it under Self.DNSName in tailscale status --json, for example:

TAILSCALE_HOST=mbp.example-tailnet.ts.net

Then run:

make serve     # prints the private HTTPS URL to open on the PC
make unserve   # remove this app's Tailscale route when finished

Both devices must be connected to the same tailnet. Tailscale Serve provides HTTPS and proxies to Vite on 127.0.0.1:8484. Vite forwards /api, /auth/discord, and /broadcasting to VITE_API_BASE_URL (or the legacy API_BASE_URL), defaulting to http://127.0.0.1:8000. The browser uses the same origin for those requests in development, so no PC-specific API URL or CORS change is needed. Production builds still use the configured API URL.

The Serve route persists across restarts; the app servers must also be running. This uses HTTPS port 443 on this device's Tailscale address, so reserve it for this app. The development servers and MySQL stay on loopback.

Local MySQL

Docker Compose runs MySQL 5.7, matching the API's existing database version. The image runs with linux/amd64 emulation on Apple Silicon. Connect using:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3307
DB_DATABASE=tv
DB_USERNAME=root
DB_PASSWORD=root

These values are the defaults in api/.env.example. If you already have an api/.env, update its DB_* values to match. Port 3307 keeps the Docker service separate from MySQL installations using port 3306.

The rest of this document covers the same setup step by step, plus the bits make doesn't automate.

API Setup

You will need the Docker MySQL service above, php >=7.2 along with Composer, and ngrok (Optional)

  • Move to the api folder.
cd api
  • Install the dependencies
composer install
  • Copy .env.example to .env, and setup your environment config. Particularly, the database credentials (DB_*).
cp .env.example .env
  • Open up .env, then configure the cdn url & request access code
# Where your media is stored
APP_CDN=https://your-digital-ocean-cdn.sgp1.cdn.digitaloceanspaces.com/

# This is used for the registration, but you can leave empty.
APP_REQUEST_ACCESS_CODE=
  • Publish unique key for Laravel.
php artisan key:generate
  • Run the migrations and provision Passport’s internal personal access client.
php artisan migrate
php artisan db:seed && php artisan db:seed --class=ShowSeeder
php artisan passport:install

The legacy admin row is retained for migration. Sign in with Discord; link existing accounts with php artisan app:link-discord USER_ID DISCORD_USER_ID. See AUTHENTICATION.md for Discord setup and cutover.

  • Setup Pusher by logging in to its dashboard, and creating a client. When you're done, open up .env, and change the following with the details provided by Pusher:
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=
  • You should be good to go. Run the command below then head over to http://localhost:8000
php artisan serve

API Setup: Enable Active Presence Locally (Optional)

Active Presence is a feature that lets you know if a user invited to a room is active or not.

If not enabled, users will simply be inactive by default.

  • If you're setting this up locally, setup ngrok, then point it to port 8000 (port used by php artisan serve).
ngrok http 8000
  • Open up Pusher, head over to the Web Hooks tab.

  • Either paste the api's public url or ngrok's generated url (e.g., http://9542199e.ngrok.io) to the Webhook URL input.

  • Select Presence for the Event Type, then press Add.

Front-end setup

Use Node.js 26.13.0 LTS (pinned in ui/.nvmrc; run nvm install && nvm use from ui/) and npm >=11. The UI uses React 19, TypeScript, and Vite.

  • Move to the ui folder
cd ui
  • Install the dependencies
npm i
  • Copy .env.example to .env. Set VITE_API_BASE_URL and the public Pusher values. Discord and Passport client secrets stay on the API.
cp .env.example .env
  • Start Vite.
npm start

Open http://localhost:8484. Set VITE_API_BASE_URL to your API URL (the default make start:api URL is http://localhost:8000). Existing unprefixed environment variables remain supported through an explicit allowlist; new configuration uses VITE_*.

Use Continue with Discord to sign in or create an account. The separate access-code step appears only when APP_REQUEST_ACCESS_CODE is configured and the user has not already passed it.

Deployment

The API and front-end are deployed separately.

API

Currently, Care.tv is deployed on Laravel Forge. If you follow the API setup instructions properly, things should work out of the box.

  • Initially, make sure to setup Laravel Passport:
php artisan passport:install
  • Configure Discord and link the existing admin’s Discord ID before cutover. See AUTHENTICATION.md.

  • Lastly, make sure to setup active presence - can also be seen above.

Front-end

The web interface is hosted on Netlify for free.

  • Set the root folder to ui; the public folder to dist.
  • Set the environment config accordingly.
  • For the build command:
npm run build

Custom API Commands

# Lists the most recent parties since 3 days ago
php artisan app:list-pt
# Lists the most recent parties since 5 days ago
php artisan app:list-pt 5

# Lists the last 15 registrations
php artisan app:list-users
# Lists the last 30 registrations
php artisan app:list-users 30

Attribution

About

A personal Netflix clone with sync-play, invitation system, and chatting features.

Topics

Resources

Stars

39 stars

Watchers

6 watching

Forks

Releases

Packages

Used by

Contributors

Languages