|
1 | | -# VFS Cache Proxy |
| 1 | +# rclone-vfs |
2 | 2 |
|
3 | 3 | A high-performance streaming proxy server built on top of [Rclone's VFS](https://rclone.org/commands/rclone_mount/#vfs-file-caching) layer. This service allows you to stream files from any HTTP/HTTPS URL with the benefits of Rclone's smart caching, buffering, and read-ahead capabilities. |
4 | 4 |
|
5 | | -It also features an internal metadata cache using `freecache` to minimize upstream requests for file size and modification times. |
6 | | - |
7 | 5 | ## Features |
8 | 6 |
|
9 | 7 | - **Rclone VFS Integration**: Leverages Rclone's robust VFS for disk caching, sparse file support, and efficient streaming. |
10 | | -- **Smart Metadata Caching**: In-memory caching of file size and modification times to reduce latency and upstream API calls. |
11 | 8 | - **Flexible Input**: Supports passing target URLs via query parameters or Base64-encoded paths. |
12 | | -- **Deduplication**: Optional query parameter stripping to cache identical files with different access tokens together. |
13 | | -- **Docker Ready**: minimal Alpine-based Docker image. |
| 9 | +- **Deduplication**: Optional query parameter and domain stripping to maximize cache hits for mirrored content. |
| 10 | +- **Caddy Ready**: Includes a native Caddy module for easy integration into your web server. |
| 11 | +- **Docker Ready**: Minimal Alpine-based Docker image. |
14 | 12 |
|
15 | 13 | ## Getting Started |
16 | 14 |
|
17 | 15 | ### Prerequisites |
18 | 16 |
|
19 | | -- Docker |
| 17 | +- Docker or Go 1.25+ |
20 | 18 |
|
21 | 19 | ### Installation & Run |
22 | 20 |
|
23 | | -You can run the VFS Proxy directly using Docker. This will pull the image (if hosted) or you can build it locally. |
24 | | - |
25 | | -To run the server with a persistent cache directory: |
| 21 | +You can run `rclone-vfs` directly using Docker: |
26 | 22 |
|
27 | 23 | ```bash |
28 | 24 | docker run -d \ |
29 | 25 | -p 8080:8080 \ |
30 | | - -v /path/to/host/cache:/app/cache \ |
31 | | - vfs-proxy --cache-dir /app/cache |
| 26 | + -v /path/to/host/cache:/tmp/rclone_vfs_cache \ |
| 27 | + ghcr.io/tgdrive/rclone-vfs --cache-dir /tmp/rclone_vfs_cache |
32 | 28 | ``` |
33 | 29 |
|
34 | | -You can pass any CLI flags (see below) to the end of the docker run command. |
35 | | - |
36 | 30 | ## CLI Flags |
37 | 31 |
|
| 32 | +All Rclone VFS settings are supported. Below are the most common ones: |
| 33 | + |
38 | 34 | | Flag | Default | Description | |
39 | 35 | |------|---------|-------------| |
40 | 36 | | `--port` | `8080` | Port to listen on. | |
41 | 37 | | `--cache-dir` | System Temp | Directory to store the VFS disk cache. | |
| 38 | +| `--cache-mode` | `off` | VFS cache mode (`off`, `minimal`, `writes`, `full`). | |
42 | 39 | | `--chunk-size` | `64M` | The chunk size for read requests. | |
43 | 40 | | `--chunk-streams` | `2` | Number of parallel streams to read at once. | |
44 | 41 | | `--max-age` | `1h` | Max age of files in the VFS cache. | |
45 | 42 | | `--max-size` | `off` | Max total size of objects in the cache. | |
46 | | -| `--strip-query` | `false` | If true, strips query parameters from the URL when generating the cache key. Useful for signed URLs. | |
47 | | -| `--strip-domain` | `false` | If true, strips domain and protocol from the URL when generating the cache key. Useful for content mirrored across multiple domains. | |
48 | | -| `--metadata-cache-size` | `5M` | Size of the in-memory metadata cache. | |
| 43 | +| `--strip-query` | `false` | If true, strips query parameters from the URL when generating the cache key. | |
| 44 | +| `--strip-domain` | `false` | If true, strips domain and protocol from the URL. | |
| 45 | +| `--shard-level` | `1` | Number of directory levels for sharding the cache. | |
| 46 | + |
| 47 | +*Run `rclone-vfs --help` to see all available flags, including advanced VFS permissions and timing settings.* |
49 | 48 |
|
50 | 49 | ## API Endpoints |
51 | 50 |
|
52 | 51 | ### 1. Stream via Query Parameter |
53 | | - |
54 | 52 | ```http |
55 | 53 | GET /stream?url=https://example.com/video.mp4 |
56 | 54 | ``` |
57 | 55 |
|
58 | 56 | ### 2. Stream via Base64 Path |
59 | | - |
60 | | -Useful for tools or players that struggle with query parameters in URLs. |
61 | | - |
62 | | -1. Base64 encode your target URL (URL-safe or standard). |
63 | | - - `https://example.com/video.mp4` -> `aHR0cHM6Ly9leGFtcGxlLmNvbS92aWRlby5tcDQ` |
64 | | -2. Request the path: |
65 | | - |
66 | | -```http |
67 | | -GET /stream/aHR0cHM6Ly9leGFtcGxlLmNvbS92aWRlby5tcDQ |
68 | | -``` |
| 57 | +Useful for players that struggle with query parameters. |
| 58 | +1. Base64 encode your URL: `https://example.com/video.mp4` -> `aHR0cHM6Ly9leGFtcGxlLmNvbS92aWRlby5tcDQ` |
| 59 | +2. Request: `GET /stream/aHR0cHM6Ly9leGFtcGxlLmNvbS92aWRlby5tcDQ` |
69 | 60 |
|
70 | 61 | ## Caddy Plugin |
71 | 62 |
|
72 | | -VFS Cache Proxy can be used as a Caddy module. This allows Caddy to act as a high-performance caching reverse proxy for specific upstreams. |
73 | | - |
74 | | -### 1. Build with xcaddy |
75 | | - |
76 | | -Since this is a Go plugin, you must compile it into Caddy: |
77 | | - |
| 63 | +Build Caddy with the module: |
78 | 64 | ```bash |
79 | | -xcaddy build \ |
80 | | - --with github.com/tgdrive/vfscache-proxy/caddy |
| 65 | +xcaddy build --with github.com/tgdrive/rclone-vfs/caddy |
81 | 66 | ``` |
82 | 67 |
|
83 | | -### 2. Caddyfile Usage |
84 | | - |
85 | | -#### Pattern A: Simple Reverse Proxy |
86 | | -Acts as a transparent caching layer for an upstream server. |
87 | | - |
| 68 | +### Caddyfile Usage |
88 | 69 | ```caddyfile |
89 | 70 | :8080 { |
90 | 71 | vfs https://upstream.com { |
91 | 72 | cache_dir /var/cache/vfs |
| 73 | + cache_mode full |
92 | 74 | max_age 24h |
93 | | - } |
94 | | -} |
95 | | -``` |
96 | | -*Request:* `GET /movie.mp4` -> *Fetches & Caches:* `https://upstream.com/movie.mp4` |
97 | | - |
98 | | -#### Pattern B: Specific Route |
99 | | -Only proxy specific paths through the VFS layer. |
100 | | - |
101 | | -```caddyfile |
102 | | -example.com { |
103 | | - route /media/* { |
104 | | - vfs https://s3.amazonaws.com/my-bucket { |
105 | | - chunk_size 128M |
106 | | - chunk_streams 4 |
107 | | - } |
108 | | - } |
109 | | - |
110 | | - # Other standard Caddy logic |
111 | | - file_server browse |
112 | | -} |
113 | | -``` |
114 | | - |
115 | | -#### Pattern C: Stripping Prefix (`handle_path`) |
116 | | -Useful if the upstream does not expect the local path prefix. |
117 | | - |
118 | | -```caddyfile |
119 | | -:8080 { |
120 | | - handle_path /stream/* { |
121 | | - vfs https://cdn.example.net { |
122 | | - strip_domain |
123 | | - strip_query |
124 | | - } |
| 75 | + strip_query |
125 | 76 | } |
126 | 77 | } |
127 | 78 | ``` |
128 | 79 |
|
129 | 80 | ### Caddyfile Directives |
130 | | - |
131 | | -| Directive | Description | |
132 | | -|-----------|-------------| |
133 | | -| `upstream` (arg) | **Required**. The base URL of the source server. | |
134 | | -| `cache_dir` | Directory for the VFS disk cache. | |
135 | | -| `max_age` | Max age of files in cache (e.g., `1h`, `24h`). | |
136 | | -| `max_size` | Max total size of the disk cache. | |
137 | | -| `chunk_size` | Chunk size for read requests (default `64M`). | |
138 | | -| `chunk_streams` | Parallel download streams per request. | |
139 | | -| `strip_query` | Strip query parameters for the metadata cache key. | |
140 | | -| `strip_domain` | Strip domain/protocol for the metadata cache key. | |
141 | | -| `metadata_cache_size` | Size of the in-memory metadata cache (default `5M`). | |
142 | | -| `fs_name` | Custom name for the VFS file system. | |
143 | | -| `cache_mode` | VFS cache mode (`off`, `minimal`, `writes`, `full`). | |
144 | | - |
145 | | ---- |
| 81 | +- `upstream` (argument): The base URL of the source server. |
| 82 | +- `cache_dir`: Path to disk cache. |
| 83 | +- `cache_mode`: `off`, `minimal`, `writes`, or `full`. |
| 84 | +- `max_age`, `max_size`, `chunk_size`, `chunk_streams`. |
| 85 | +- `strip_query`, `strip_domain`, `shard-level`. |
| 86 | +- `read_only`, `no_seek`, `no_checksum`, etc. |
146 | 87 |
|
147 | 88 | ## How it Works |
148 | 89 |
|
149 | | -1. **Request**: The server receives a request for a URL. |
150 | | -2. **Metadata**: It checks an in-memory `freecache` for the file's size and modification time. |
151 | | - - If missing, it performs an HTTP `HEAD` (or `GET` range) request to the upstream URL and caches the result for 1 hour. |
152 | | -3. **VFS Mount**: The file is virtually "mounted" using the `link` backend. |
153 | | -4. **Streaming**: Rclone's VFS layer handles the reading, downloading chunks in parallel (`--chunk-streams`), and caching them to disk (`--cache-dir`). |
154 | | -5. **Response**: The content is streamed to the client with support for Range requests (seeking). |
| 90 | +1. **VFS Mapping**: The requested URL is mapped to a unique deterministic path in a virtual rclone file system. |
| 91 | +2. **Streaming**: Rclone's VFS layer handles the heavy lifting—on-demand downloading, parallel chunk streaming, and local disk persistence. |
| 92 | +3. **Efficiency**: Range requests are fully supported, allowing clients to seek through large files without downloading the entire file. |
0 commit comments