Skip to content

fofola1/AniOwn

Repository files navigation

AniOwn

AniOwn Logo

Self-hosted anime downloader with a managed directory structure — designed to work perfectly with Jellyfin or Plex.

Docker Python React FastAPI Celery


✨ Features

  • Search & Discover — Search any anime by title using the Consumet API (AniKai provider).
  • SUB / DUB toggle — Choose sub or dub globally or per episode/batch.
  • Single-episode & batch downloads — Queue one episode or an entire season at once.
  • Quick queue on hover — Hover a search result card to reveal diagonal SUB / DUB quick-action buttons.
  • S00E00 file naming — Downloaded files are automatically renamed using the standard ShowName-S01E03.mp4 convention.
  • Organised media library — Files are moved to a structured /media/Show_Name/season_01/ hierarchy compatible with Jellyfin and Plex out of the box. Movies, OVAs and Specials go to season_00.
  • Plex-style Library UI — Drill down from series → season → episode inside the app.
  • Unassigned season resolver — If the season cannot be detected automatically, the Transfer Log presents an inline form to manually assign the correct folder without losing the file.
  • Episode status in Discover — When browsing a show's episodes, each row shows its real download status (queued, downloading, completed, failed) with Play / Delete / Retry actions inline.
  • Transfer Log — Live sidebar tracking every download with status badges, error tooltips, Retry buttons, and a Clear All action (soft-delete — files stay in the Library).
  • Hard delete — Deleting from the Library physically removes the .mp4 from disk.
  • Browser history navigation — Back / Forward buttons work correctly across all views. URLs encode the current state so deep links and bookmarks work.
  • Search history — Recent searches are persisted in localStorage. A live-filtering dropdown with keyboard navigation (↑ ↓ Enter Esc) appears while typing, exactly like a browser address bar.
  • Remote access — Works through any tunnel (Pinggy, Ngrok, Tailscale, Cloudflare) — allowedHosts is set to all in the dev config.
  • Single Docker image — All services (API, Celery worker, Redis, Consumet) run inside one container managed by supervisord. Deploy with a single docker compose up -d.

🏗️ Architecture

Everything runs inside a single container managed by supervisord:

┌───────────────────────────────────────────────────────────────────┐
│  Browser → http://localhost:8000                                  │
└───────────────────────────┬───────────────────────────────────────┘
                            │ HTTP
┌───────────────────────────▼───────────────────────────────────────┐
│  AniOwn container (port 8000)                                     │
│                                                                   │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │  FastAPI / Uvicorn                                          │  │
│  │  • Serves built React SPA (/)                               │  │
│  │  • REST API for downloads, library, media streaming         │  │
│  │  • Proxies search/info/watch → Consumet (localhost:3000)    │  │
│  └───────────────┬──────────────────────┬──────────────────────┘  │
│                  │ Celery tasks          │ SQLite                 │
│  ┌───────────────▼──────┐   ┌────────────▼─────────────────────┐  │
│  │  Celery Worker       │   │  /app/data/database.db           │  │
│  │  yt-dlp + ffmpeg     │   │  (named Docker volume)           │  │
│  └───────────────┬──────┘   └──────────────────────────────────┘  │
│                  │ broker                                         │
│  ┌───────────────▼──────┐   ┌──────────────────────────────────┐  │
│  │  Redis (localhost)   │   │  Consumet API (localhost:3000)   │  │
│  └──────────────────────┘   └──────────────────────────────────┘  │
└───────────────────────────────────────────────────────────────────┘

🚀 Getting Started

Prerequisites

Option A — Pull from GHCR (recommended, no clone needed)

# Download only the compose file
curl -O https://raw.githubusercontent.com/fofola1/AniOwn/main/docker-compose.yml

# Start
docker compose up -d

Docker will pull the pre-built image automatically. Open http://localhost:8000.

Option B — Build from source

git clone https://github.com/fofola1/AniOwn.git
cd AniOwn

# Production build (single image)
docker build -t ghcr.io/fofola1/aniown:latest .
docker compose up -d

# — or — development mode with hot-reload
docker compose -f docker-compose.dev.yml up -d --build

First build — compiles React, copies Consumet from its official Docker image, and installs Python deps. Expect 3–5 minutes. Subsequent builds use the layer cache.


📦 Volumes

Host path Container path Purpose
./config/ /app/data SQLite database (persists across restarts)
./downloads/ /downloads Temporary download staging area
./media/ /media Final organised media library

Point ./media at Jellyfin or Plex as an Anime library and everything is detected automatically.


📁 Directory Structure

AniOwn/
├── backend/
│   ├── main.py           # FastAPI application & routes, SPA serving
│   ├── tasks.py          # Celery download tasks, season parsing, file relocation
│   ├── celery_app.py     # Celery app factory
│   ├── database.py       # SQLAlchemy model (SQLite, stored in /app/data)
│   ├── migrate.py        # Schema migration helper
│   ├── requirements.txt
│   └── Dockerfile        # Used by docker-compose.dev.yml only
├── frontend/
│   ├── src/
│   │   └── App.jsx       # Entire React application (single-page)
│   ├── public/
│   │   └── logo.png      # App icon / favicon
│   ├── index.html
│   ├── vite.config.js    # Dev server config (allowedHosts: all, /api proxy)
│   └── Dockerfile        # Used by docker-compose.dev.yml only
├── Dockerfile            # Production multi-stage build (React + Consumet + Python)
├── supervisord.conf      # Manages all 4 processes inside the single container
├── docker-compose.yml    # Production — pull image from GHCR, single service
├── docker-compose.dev.yml # Development — build from source, hot-reload
├── logo.png              # Full-quality logo for README / branding
└── LICENSE

⚙️ Configuration

The production docker-compose.yml needs no configuration to work out of the box. Optional env vars:

Variable Default Description
PORT 8000 Host port to expose the app on
CONCURRENCY 2 Number of parallel downloads
CORS_ORIGINS * Comma-separated allowed origins (restrict for extra security)

Example with custom values:

services:
  aniown:
    image: ghcr.io/fofola1/aniown:latest
    container_name: aniown
    volumes:
      - ./config:/app/data
      - ./downloads:/downloads
      - ./media:/media
    ports:
      - 8000:8000
    restart: unless-stopped
    environment:
      - CONCURRENCY=4
      - MEDIA_PREFERENCE=DUB
      - ALTERNATIVE_FALLBACK=true
      - YTDLP_INSECURE_TLS=true # use this only when you encounter issues and know what you are doing
      - CORS_ORIGINS=https://yourdomain.com
      - ALLOWED_HOSTS=true # allows all hosts

🔧 Tech Stack

Layer Technology
Frontend React 19, Vite, TailwindCSS v4, Lucide Icons
Backend API FastAPI, Uvicorn
Task Queue Celery 5, Redis 7
Database SQLite (via SQLAlchemy)
Downloader yt-dlp, ffmpeg
Anime Sources Consumet API (AniKai provider)
Process Manager Supervisord
Containerisation Docker, Docker Compose

📝 License

GNU General Public License v3.0 — see LICENSE for details.

About

Self-hosted anime downloader with a managed directory structure — designed to work perfectly with Jellyfin or Plex.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors