Update Dockerfile, docker-compose, and README for Synology NAS deployment

This commit is contained in:
Khoa Vo 2026-05-12 08:56:30 +07:00
parent 03e93fcfa6
commit a41ca7ff2c
3 changed files with 250 additions and 288 deletions

View file

@ -1,39 +1,27 @@
# Build Stage for Frontend # Build Stage for Frontend
FROM node:18-alpine as frontend-build FROM --platform=linux/amd64 node:18-alpine AS frontend-build
WORKDIR /app/frontend WORKDIR /app/frontend
COPY frontend/package*.json ./ COPY frontend/package*.json ./
RUN npm ci RUN npm ci
COPY frontend/ ./ COPY frontend/ ./
RUN npm run build RUN npm run build
# Runtime Stage for Backend # Runtime Stage
FROM python:3.11-slim FROM --platform=linux/amd64 mcr.microsoft.com/playwright/python:v1.49.1-jammy
# Install system dependencies required for Playwright and compiled extensions WORKDIR /app
RUN apt-get update && apt-get install -y \
curl \ RUN pip install --no-cache-dir -U yt-dlp fastapi uvicorn requests python-multipart websockets python-dotenv httpx crawl4ai playwright-stealth
git \
build-essential \ COPY backend/requirements.txt backend/
&& rm -rf /var/lib/apt/lists/* RUN pip install --no-cache-dir -r backend/requirements.txt
WORKDIR /app COPY backend/ backend/
# Install Python dependencies COPY --from=frontend-build /app/frontend/dist /app/frontend/dist
COPY backend/requirements.txt backend/
RUN pip install --no-cache-dir -r backend/requirements.txt RUN playwright install chromium --with-deps
# Install Playwright browsers (Chromium only to save space) EXPOSE 8002
RUN playwright install chromium
RUN playwright install-deps chromium CMD ["python", "backend/main.py"]
# Copy Backend Code
COPY backend/ backend/
# Copy Built Frontend Assets
COPY --from=frontend-build /app/frontend/dist /app/frontend/dist
# Expose Port
EXPOSE 8002
# Run Application
CMD ["python", "backend/main.py"]

417
README.md
View file

@ -1,263 +1,264 @@
# 🎵 PureStream # kv-tiktok
**Distraction-free TikTok viewing** - A clean, ad-free TikTok client with a beautiful minimal interface. **Self-hosted TikTok viewer** — A clean, ad-free TikTok client you can run on your own NAS or server.
![PureStream Demo](https://img.shields.io/badge/Platform-Web-blue) ![Docker](https://img.shields.io/badge/Docker-Ready-blue) ![License](https://img.shields.io/badge/License-MIT-green) ## Features
## ✨ Features - **For You Feed** — Video feed from popular TikTok creators
- **Search** — Search videos and users
- **Following** — Track your favorite creators
- **Liked Videos** — Save favorites to a persistent Liked tab
- **Download** — Download videos directly
- **Autoplay** — Muted autoplay with tap-to-unmute
- **Mobile-friendly** — Responsive design for any screen
- **Docker-ready** — Single container, easy deployment on Synology NAS
- 🎬 **Clean Video Feed** - No ads, no distractions, just content ## Architecture
- 🔍 **Powerful Search** - Search by username, video URL, or keywords
- 👥 **Follow System** - Keep track of your favorite creators
- 💾 **Tab Persistence** - Switch tabs without losing your place
- 👆 **Swipe Navigation** - Swipe left/right to switch tabs (mobile)
- ⌨️ **Keyboard Controls** - Arrow keys for tabs, Space for pause, Up/Down for scroll
- ❤️ **Heart Animations** - Double-tap to show love
- 🔇 **Smart Autoplay** - Videos autoplay muted (tap to unmute)
- 📱 **Responsive Design** - Works on desktop and mobile
- 🐳 **Docker Ready** - Easy deployment on any platform
## 🚀 Quick Start - **Backend**: Python FastAPI with Playwright for TikTok interaction
- **Frontend**: React + Vite
- **Platform**: `linux/amd64` (compatible with Synology NAS x86/x64 models)
### Option 1: Docker Compose (Recommended) ## Prerequisites
The easiest way to run PureStream on your server or Synology NAS. - Docker and Docker Compose installed
- For Synology NAS: Container Manager (Docker) package installed
- Minimum 2GB RAM recommended for browser automation
## Quick Start
### Clone and Run
```bash ```bash
# Create a directory git clone https://github.com/vndangkhoa/kv-tiktok.git
mkdir purestream && cd purestream cd kv-tiktok
docker compose up -d --build
# Download docker-compose.yml
curl -O https://raw.githubusercontent.com/YOUR_USERNAME/purestream/main/docker-compose.yml
# Start the application
docker-compose up -d
# View logs
docker-compose logs -f
``` ```
Access the app at: `http://your-server-ip:8002` Access at `http://your-server-ip:8002`
### Option 2: Docker Run ---
```bash ## Synology NAS Deployment
docker run -d \
--name purestream \
-p 8002:8002 \
--shm-size=2g \
-v purestream_cache:/app/cache \
-v purestream_session:/app/backend/session \
vndangkhoa/purestream:latest
```
### Option 3: Development Setup ### Option 1: Build on NAS via SSH (Recommended)
```bash **Requirements**: SSH access enabled on your NAS (Control Panel → Terminal & SNMP → Enable SSH)
# Clone the repository
git clone https://github.com/YOUR_USERNAME/purestream.git
cd purestream
# Backend setup
cd backend
python -m venv venv
source venv/bin/activate # or `venv\Scripts\activate` on Windows
pip install -r requirements.txt
playwright install chromium
# Start backend
uvicorn main:app --host 0.0.0.0 --port 8002 --reload
# Frontend setup (new terminal)
cd frontend
npm install
npm run dev
```
## 🖥️ Synology NAS Deployment
### Using Container Manager (Docker)
1. **Open Container Manager** → **Registry**
2. Search for `vndangkhoa/purestream` and download the `latest` tag
3. Go to **Container** → **Create**
4. Configure:
- **Port Settings**: Local `8002` → Container `8002`
- **Volume**: Create a folder for cache and map to `/app/cache`
- **Environment**: Add `PYTHONUNBUFFERED=1`
- **Resources**: Allocate at least 2GB RAM (for browser)
5. **Apply** and start the container
### Using docker-compose on Synology
```bash ```bash
# SSH into your NAS # SSH into your NAS
ssh admin@your-nas-ip ssh admin@your-nas-ip
# Create directory # Navigate to your shared folder
mkdir -p /volume1/docker/purestream cd /volume1/docker
cd /volume1/docker/purestream
# Create docker-compose.yml (paste the content from this repo) # Clone the repository
nano docker-compose.yml git clone https://github.com/vndangkhoa/kv-tiktok.git
cd kv-tiktok
# Start # Build and start
docker-compose up -d docker compose up -d --build
# Watch logs to confirm it's running
docker compose logs -f
``` ```
## ⌨️ Keyboard Shortcuts Once running, access at `http://your-nas-ip:8002`
| Key | Action | ### Option 2: Build on PC, Deploy via GUI
|-----|--------|
| `←` `→` | Switch tabs |
| `↑` `↓` | Scroll videos |
| `Space` | Play/Pause |
| `M` | Mute/Unmute |
## 🔧 Environment Variables If your NAS has limited resources:
| Variable | Default | Description | **Step 1: Build on your PC**
|----------|---------|-------------|
| `CACHE_DIR` | `/app/cache` | Video cache directory |
| `MAX_CACHE_SIZE_MB` | `500` | Maximum cache size in MB |
| `CACHE_TTL_HOURS` | `24` | Cache expiration time |
## 📁 Project Structure ```bash
git clone https://github.com/vndangkhoa/kv-tiktok.git
``` cd kv-tiktok
purestream/ docker build -t kv-tiktok:latest .
├── backend/ docker save kv-tiktok:latest -o kv-tiktok.tar
│ ├── api/
│ │ └── routes/
│ │ ├── auth.py # Authentication endpoints
│ │ └── feed.py # Feed & video proxy endpoints
│ ├── core/
│ │ └── playwright_manager.py # Browser automation
│ └── main.py # FastAPI application
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ │ ├── Feed.tsx # Main feed component
│ │ │ └── VideoPlayer.tsx # Video player
│ │ └── App.tsx
│ └── package.json
├── Dockerfile
├── docker-compose.yml
└── README.md
``` ```
## 🔐 Authentication (Admin Setup) **Step 2: Transfer to NAS**
PureStream uses your TikTok session cookies. Once configured by the admin, **all users can access the feed without logging in** - on desktop or mobile. Copy `kv-tiktok.tar` to your NAS using File Station or SCP:
> **Important**: Admin setup should be done from a **desktop/laptop computer** (not a phone) because you need a browser extension to export cookies. ```bash
scp kv-tiktok.tar admin@your-nas-ip:/volume1/docker/
```
### First-Time Setup (Desktop Required) **Step 3: Import via Container Manager**
1. **Set your admin password** in `docker-compose.yml`: 1. Open **Container Manager** on your Synology
```yaml 2. Go to **Registry****Image** → **Import**
environment: 3. Select `kv-tiktok.tar` from the shared folder
- ADMIN_PASSWORD=your_secure_password 4. Wait for import to complete
```
2. **Start/restart the container**: **Step 4: Create Container**
1. Go to **Container** → **Create**
2. Select image: `kv-tiktok:latest`
3. Configure:
| Setting | Value |
|---------|-------|
| Container Name | `kv-tiktok` |
| Port Settings | Local: `8002` → Container: `8002` |
| Memory Limit | Minimum `2GB` |
| Shared Memory | `2GB` |
4. **Volume Settings**: Click **Add Folder**
- Create a folder named `kv-tiktok-cache` in your shared folder
- Mount path: `/app/cache`
5. **Environment Variables**: Click **Add**
- `PYTHONUNBUFFERED` = `1`
- `ADMIN_PASSWORD` = `your_secure_password`
6. **Restart Policy**: Select `unless-stopped`
7. Click **Apply**
**Step 5: Verify**
```bash
# Check container is running
docker ps
# Check logs
docker logs kv-tiktok
```
### Option 3: Via docker-compose (SSH)
```bash
# On your NAS via SSH
cd /volume1/docker/kv-tiktok
docker compose up -d
docker compose logs -f
```
---
## First-Time Setup (TikTok Cookies)
The app requires TikTok session cookies to load the feed.
### Get Your Cookies (Desktop Recommended)
1. Install [Cookie-Editor](https://chrome.google.com/webstore/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm) browser extension
2. Go to [tiktok.com](https://www.tiktok.com) and log in to your account
3. Click the Cookie-Editor icon → **Export****Copy** (select "Export as JSON")
4. Save the exported JSON to `cookies.json` file in the project directory
5. Restart the container:
```bash ```bash
docker-compose up -d --force-recreate docker compose restart
``` ```
3. **Access the admin page**: `http://your-server-ip:8002/admin` ### Alternative: Setup via Admin Page
- Enter your admin password (default: `admin123`)
4. **Get your TikTok cookies** (from a desktop browser): 1. Start the container and visit `http://your-server-ip:8002/admin`
- Install [Cookie-Editor](https://chrome.google.com/webstore/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm) browser extension 2. Login with default password: `admin123` (change this!)
- Go to [tiktok.com](https://www.tiktok.com) and login to your account 3. Follow on-screen instructions to paste cookies
- Click Cookie-Editor icon → **Export** → **Copy**
5. **Paste cookies** in the admin page text area and click **Save Cookies** ---
6. ✅ **Done!** Now anyone can access `http://your-server-ip:8002/` on any device (including phones)
### Getting Cookies on Mobile (If No Desktop Available)
#### 📱 Android Phone
1. **Install Kiwi Browser** from [Google Play Store](https://play.google.com/store/apps/details?id=com.kiwibrowser.browser)
- Kiwi Browser supports Chrome extensions on Android
2. **Install Cookie-Editor extension**:
- In Kiwi, go to: `chrome://extensions`
- Enable "Developer mode" (toggle in top right)
- Go to [Cookie-Editor on Chrome Web Store](https://chrome.google.com/webstore/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm)
- Click "Add to Chrome"
3. **Get cookies**:
- Go to [tiktok.com](https://www.tiktok.com) in Kiwi Browser
- Login to your TikTok account
- Tap the 3-dot menu → Extensions → Cookie-Editor
- Tap **Export** → **Copy**
4. **Paste in admin page**:
- Go to `http://your-server-ip:8002/admin`
- Login with admin password
- Paste cookies and save
#### 🍎 iOS/iPhone
Unfortunately, iOS Safari doesn't support browser extensions. Options:
1. **Use a desktop computer** (recommended) - borrow a friend's laptop for 5 minutes
2. **Use Orion Browser** (limited):
- Install [Orion Browser](https://apps.apple.com/app/orion-browser-by-kagi/id1484498200) from App Store
- It has some extension support, but Cookie-Editor may not work perfectly
3. **Manual method** (advanced):
- On iOS Safari, go to tiktok.com and login
- In Safari: Settings → Safari → Advanced → Web Inspector (enable)
- Connect to Mac with Safari → Develop menu → your phone
- In console: `document.cookie` - copy the sessionid value
- Format as: `[{"name":"sessionid","value":"YOUR_VALUE_HERE"}]`
> **Tip**: The easiest option for iOS users is to use any desktop/laptop computer (Windows, Mac, Linux, Chromebook) to do the one-time cookie setup.
## Configuration
### Environment Variables ### Environment Variables
| Variable | Default | Description | | Variable | Default | Description |
|----------|---------|-------------| |----------|---------|-------------|
| `PYTHONUNBUFFERED` | `1` | Real-time Python logging |
| `ADMIN_PASSWORD` | `admin123` | Password for `/admin` page | | `ADMIN_PASSWORD` | `admin123` | Password for `/admin` page |
| `CACHE_DIR` | `/app/cache` | Video cache directory |
| `MAX_CACHE_SIZE_MB` | `500` | Maximum cache size |
| `CACHE_TTL_HOURS` | `24` | Cache expiration |
> **Security Note**: Cookies are stored locally in the `session/` volume. Anyone with the admin password can view/update them. ### Volumes
| Path | Description |
|------|-------------|
| `/app/cache` | Video cache (LRU, max usage limited by disk space) |
| `/app/cookies.json` | TikTok session cookies (persist across restarts) |
## 🐛 Troubleshooting ### Health Check
### Videos not loading? The container includes a health check endpoint. You can verify with:
- Check if the backend is running: `curl http://localhost:8002/health`
- Check logs: `docker-compose logs -f`
- Try re-logging in (sessions can expire)
### Browser errors on headless server? ```bash
- Ensure `shm_size: '2gb'` is set in docker-compose curl http://localhost:8002/health
- Xvfb is included in the Docker image for virtual display # Expected: {"status":"ok"}
```
### Cache issues?
- Clear cache: `docker exec purestream rm -rf /app/cache/*`
- Restart container: `docker-compose restart`
## 📄 License
MIT License - feel free to use, modify, and distribute.
## 🙏 Acknowledgments
- Built with [FastAPI](https://fastapi.tiangolo.com/) & [React](https://react.dev/)
- Browser automation by [Playwright](https://playwright.dev/)
- Video extraction by [yt-dlp](https://github.com/yt-dlp/yt-dlp)
--- ---
**Made with ❤️ for distraction-free viewing** ## Troubleshooting
### Videos Not Loading
```bash
# Check backend health
curl http://localhost:8002/health
# View logs
docker compose logs -f
# Verify cookies exist
cat cookies.json
```
### Container Won't Start
```bash
# Check logs
docker compose logs
# Verify port 8002 is not in use
netstat -tlnp | grep 8002
```
### Out of Memory
Increase memory limits or clear cache:
```bash
# Clear video cache
rm -rf ./cache/*
docker compose restart
```
### Update to Latest Version
```bash
git pull
docker compose up -d --build
```
---
## Project Structure
```
kv-tiktok/
├── backend/
│ ├── api/routes/ # API endpoints
│ ├── core/ # Core services (Playwright, Crawler)
│ └── main.py # FastAPI application
├── frontend/
│ ├── src/
│ │ ├── components/ # React components
│ │ └── App.tsx
│ └── package.json
├── Dockerfile # Multi-stage build
├── docker-compose.yml # Container orchestration
└── README.md
```
## Synology NAS Compatibility
Tested on Synology models with x86/x64 processors. For ARM-based models (e.g., DS220+, DS920+), the `linux/amd64` image works via emulation, but performance may be slower.
## License
MIT License

View file

@ -1,54 +1,27 @@
version: '3.8' name: kv-tiktok
services: services:
purestream: kv-tiktok:
image: vndangkhoa/purestream:latest image: kv-tiktok:latest
container_name: purestream build:
context: .
dockerfile: Dockerfile
platforms:
- linux/amd64
container_name: kv-tiktok
restart: unless-stopped restart: unless-stopped
ports: ports:
- "8002:8002" - "8002:8002"
volumes: volumes:
- ./cache:/app/cache - ./cache:/app/cache
- ./session:/app/backend/session - ./cookies.json:/app/cookies.json
environment: environment:
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
- CACHE_DIR=/app/cache - ADMIN_PASSWORD=admin123
- MAX_CACHE_SIZE_MB=500 shm_size: 2gb
- CACHE_TTL_HOURS=24
- ADMIN_PASSWORD=admin123 # Change this to your secure password
shm_size: '2gb'
networks:
- purestream_net
healthcheck: healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:8002/health" ] test: ["CMD", "curl", "-f", "http://localhost:8002/health"]
interval: 30s interval: 30s
timeout: 10s timeout: 10s
retries: 3 retries: 3
start_period: 60s start_period: 60s
labels:
- "com.centurylinklabs.watchtower.enable=true"
# Auto-updater: Checks for new images every 5 minutes
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_CLEANUP=true # Remove old images
- WATCHTOWER_POLL_INTERVAL=300 # Check every 5 minutes
- WATCHTOWER_INCLUDE_RESTARTING=true
- WATCHTOWER_ROLLING_RESTART=true # Graceful restart
- WATCHTOWER_LABEL_ENABLE=true # Only update labeled containers
networks:
- purestream_net
networks:
purestream_net:
driver: bridge
ipam:
driver: default
config:
# Using 10.10.0.0 is much safer and less likely to overlap
- subnet: 10.10.0.0/16