retold-remote 0.0.23 → 0.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/css/retold-remote.css +343 -20
- package/docs/.nojekyll +0 -0
- package/docs/README.md +64 -12
- package/docs/_cover.md +6 -6
- package/docs/_sidebar.md +2 -0
- package/docs/_topbar.md +1 -1
- package/docs/_version.json +7 -0
- package/docs/collections.md +30 -0
- package/docs/css/docuserve.css +327 -0
- package/docs/ebook-reader.md +75 -1
- package/docs/image-explorer.md +62 -2
- package/docs/index.html +39 -0
- package/docs/retold-catalog.json +254 -0
- package/docs/retold-keyword-index.json +31216 -0
- package/docs/server-setup.md +122 -91
- package/docs/stack-launcher.md +218 -0
- package/docs/synology.md +585 -0
- package/docs/ultravisor-configuration.md +5 -5
- package/docs/ultravisor-integration.md +4 -2
- package/package.json +20 -14
- package/source/Pict-Application-RetoldRemote.js +22 -0
- package/source/RetoldRemote-ExtensionMaps.js +1 -1
- package/source/cli/RetoldRemote-Server-Setup.js +460 -7
- package/source/cli/RetoldRemote-Stack-Launcher.js +563 -0
- package/source/cli/RetoldRemote-Stack-Run.js +41 -0
- package/source/cli/commands/RetoldRemote-Command-Serve.js +129 -54
- package/source/providers/CollectionManager-AddItems.js +166 -0
- package/source/providers/Pict-Provider-GalleryNavigation.js +55 -0
- package/source/providers/Pict-Provider-OperationStatus.js +597 -0
- package/source/providers/keyboard-handlers/KeyHandler-ImageExplorer.js +20 -1
- package/source/providers/keyboard-handlers/KeyHandler-Viewer.js +23 -0
- package/source/server/RetoldRemote-AudioWaveformService.js +49 -3
- package/source/server/RetoldRemote-CollectionExportService.js +763 -0
- package/source/server/RetoldRemote-CollectionService.js +5 -0
- package/source/server/RetoldRemote-EbookService.js +218 -3
- package/source/server/RetoldRemote-ImageService.js +221 -46
- package/source/server/RetoldRemote-MediaService.js +63 -4
- package/source/server/RetoldRemote-MetadataCache.js +25 -5
- package/source/server/RetoldRemote-OperationBroadcaster.js +363 -0
- package/source/server/RetoldRemote-SubimageService.js +680 -0
- package/source/server/RetoldRemote-ToolDetector.js +50 -0
- package/source/server/RetoldRemote-UltravisorBeacon.js +18 -3
- package/source/server/RetoldRemote-UltravisorDispatcher.js +65 -491
- package/source/server/RetoldRemote-UltravisorOperations.js +133 -20
- package/source/server/RetoldRemote-VideoFrameService.js +302 -9
- package/source/views/MediaViewer-EbookViewer.js +419 -1
- package/source/views/MediaViewer-PdfViewer.js +1050 -0
- package/source/views/PictView-Remote-AudioExplorer.js +77 -1
- package/source/views/PictView-Remote-CollectionsPanel.js +213 -0
- package/source/views/PictView-Remote-Gallery.js +365 -64
- package/source/views/PictView-Remote-ImageExplorer.js +1529 -44
- package/source/views/PictView-Remote-ImageViewer.js +2 -2
- package/source/views/PictView-Remote-Layout.js +58 -0
- package/source/views/PictView-Remote-MediaViewer.js +100 -25
- package/source/views/PictView-Remote-RegionsBrowser.js +554 -0
- package/source/views/PictView-Remote-SubimagesPanel.js +353 -0
- package/source/views/PictView-Remote-TopBar.js +1 -0
- package/source/views/PictView-Remote-VideoExplorer.js +77 -1
- package/web-application/css/docuserve.css +277 -23
- package/web-application/css/retold-remote.css +343 -20
- package/web-application/docs/README.md +64 -12
- package/web-application/docs/_cover.md +6 -6
- package/web-application/docs/_sidebar.md +2 -0
- package/web-application/docs/_topbar.md +1 -1
- package/web-application/docs/collections.md +30 -0
- package/web-application/docs/ebook-reader.md +75 -1
- package/web-application/docs/image-explorer.md +62 -2
- package/web-application/docs/server-setup.md +122 -91
- package/web-application/docs/stack-launcher.md +218 -0
- package/web-application/docs/synology.md +585 -0
- package/web-application/docs/ultravisor-configuration.md +5 -5
- package/web-application/docs/ultravisor-integration.md +4 -2
- package/web-application/js/pict-docuserve.min.js +12 -12
- package/web-application/js/pict.min.js +2 -2
- package/web-application/js/pict.min.js.map +1 -1
- package/web-application/retold-remote.js +6596 -1784
- package/web-application/retold-remote.js.map +1 -1
- package/web-application/retold-remote.min.js +75 -23
- package/web-application/retold-remote.min.js.map +1 -1
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
# Synology Container Manager Setup
|
|
2
|
+
|
|
3
|
+
Run the full Retold stack on a Synology NAS using Container Manager (Synology's built-in Docker + Docker Compose package). This gives you a single self-contained container that runs Ultravisor, Retold Remote, and Orator-Conversion, with all optional media processing tools baked in.
|
|
4
|
+
|
|
5
|
+
## Why Build Elsewhere and Transfer?
|
|
6
|
+
|
|
7
|
+
**Don't try to build the image directly on the NAS** unless you have a beefy unit. Synology NASes are usually slow ARM or low-power x86 boxes, and building this image involves:
|
|
8
|
+
|
|
9
|
+
- Downloading ~1.5 GB of base packages (Calibre, LibreOffice, ffmpeg, etc.)
|
|
10
|
+
- Compiling sharp's native binding (slow on a Realtek SoC)
|
|
11
|
+
- Running ultravisor's webinterface postinstall
|
|
12
|
+
|
|
13
|
+
On a typical Synology, this can take **45+ minutes** and may run out of memory mid-build. Worse, if you only copy `docker-compose.yml` to the NAS without the source tree, Container Manager errors with:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
unable to prepare context: unable to evaluate symlinks in Dockerfile path:
|
|
17
|
+
lstat /volume1/docker/retold-stack/Dockerfile: no such file or directory
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The fix: **build the image on a real computer (your laptop, desktop, dev workstation), save it to a tar file, and load that tar on the NAS**. The included `docker-build-and-save.sh` script does the build and packaging in one step.
|
|
21
|
+
|
|
22
|
+
## Prerequisites
|
|
23
|
+
|
|
24
|
+
- **DSM 7.2 or newer** with **Container Manager** installed (Package Center -> Install Container Manager)
|
|
25
|
+
- A development machine with **Docker installed** (Docker Desktop, OrbStack, Colima, or native Docker on Linux)
|
|
26
|
+
- At least **2 GB of free RAM** on the NAS for the running container
|
|
27
|
+
- A few GB of free disk space on the NAS for the loaded image and cache
|
|
28
|
+
- Your media folder somewhere on the NAS (e.g., `/volume1/media`, `/volume1/photo`, `/volume1/video`)
|
|
29
|
+
|
|
30
|
+
## ⚠ ARCHITECTURE -- READ THIS FIRST ⚠
|
|
31
|
+
|
|
32
|
+
**This is the single most common cause of "videos and large images don't work" on a Synology.** Read it before building anything.
|
|
33
|
+
|
|
34
|
+
### Most Synology NAS units are amd64
|
|
35
|
+
|
|
36
|
+
Almost every Synology NAS -- including all Celeron, Pentium, Atom, Ryzen, and Xeon-based models -- is **amd64** (also called x86_64). Only a handful of low-end ARM-based models (e.g., DS118, DS220j, DS223j) are arm64.
|
|
37
|
+
|
|
38
|
+
**Find your NAS architecture:**
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
ssh admin@your-nas
|
|
42
|
+
uname -m
|
|
43
|
+
# x86_64 -> amd64 (most Synology models)
|
|
44
|
+
# aarch64 -> arm64 (a handful of low-end models)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or check the [Synology spec sheet](https://www.synology.com/en-global/products) for your model under "CPU".
|
|
48
|
+
|
|
49
|
+
### Most build machines are different from the NAS
|
|
50
|
+
|
|
51
|
+
If you build the image on:
|
|
52
|
+
|
|
53
|
+
| Build machine | Build machine arch | Synology arch | Cross-arch? |
|
|
54
|
+
|---------------|--------------------|----|----|
|
|
55
|
+
| MacBook Pro (M1/M2/M3/M4) | arm64 | amd64 (most) | **YES** |
|
|
56
|
+
| MacBook Pro (Intel) | amd64 | amd64 (most) | No |
|
|
57
|
+
| Linux desktop (Intel/AMD) | amd64 | amd64 (most) | No |
|
|
58
|
+
| Raspberry Pi 4/5 | arm64 | amd64 (most) | **YES** |
|
|
59
|
+
|
|
60
|
+
If you build on an Apple Silicon Mac and your NAS is amd64 (the most common case), **you must explicitly pass `--amd64` to the build script** or you'll get an arm64 image that runs on the NAS through QEMU emulation. Native code (sharp/libvips, ffmpeg, ImageMagick, LibreOffice, Calibre) is **5-20x slower under emulation and frequently times out** -- which produces exactly the symptoms of "small thumbnails work, large image previews and video frame extraction don't work".
|
|
61
|
+
|
|
62
|
+
### What the build script does about it
|
|
63
|
+
|
|
64
|
+
As of the current version, `./docker-build-and-save.sh` **refuses to run** without an explicit `--amd64` or `--arm64` flag. There is no silent default. This is intentional -- it's safer to fail fast than to silently produce a broken image.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# CORRECT -- explicit target:
|
|
68
|
+
./docker-build-and-save.sh --amd64 # for Intel/AMD Synology (most)
|
|
69
|
+
./docker-build-and-save.sh --arm64 # for ARM-based Synology
|
|
70
|
+
./docker-build-and-save.sh slim --amd64 # slim variant + amd64
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### What the stack launcher does about it
|
|
74
|
+
|
|
75
|
+
When the container starts, the stack launcher checks for emulation signals (CPU vendor `VirtualApple`, `qemu` strings in `/proc/cpuinfo`, kernel/binary architecture mismatch, slow CPU loop benchmark) and prints a giant red warning if any are detected:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
==========================================================
|
|
79
|
+
WARNING: container is running under emulation!
|
|
80
|
+
==========================================================
|
|
81
|
+
Reason: x86_64 binary on Apple Silicon (VirtualApple vendor)
|
|
82
|
+
Node arch: x64
|
|
83
|
+
CPU vendor: VirtualApple
|
|
84
|
+
...
|
|
85
|
+
FIX: rebuild the image for the host architecture.
|
|
86
|
+
./docker-build-and-save.sh --amd64
|
|
87
|
+
==========================================================
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
If you see this warning in your container logs, **your image is the wrong architecture for the host**. Rebuild with the correct flag.
|
|
91
|
+
|
|
92
|
+
### What the smoke test does about it
|
|
93
|
+
|
|
94
|
+
The included `docker-smoke-test.sh` (run from your dev machine against any image tag) compares the image's stated architecture against the host arch and prints a warning before running the tests if they don't match. Failing tests under arch mismatch include a hint pointing at the rebuild command.
|
|
95
|
+
|
|
96
|
+
## Step-by-Step Setup
|
|
97
|
+
|
|
98
|
+
### 1. On your dev machine: build the image
|
|
99
|
+
|
|
100
|
+
Clone the retold-remote repo (if you haven't already) and run the build script. **You must pass `--amd64` or `--arm64`** -- the script refuses to run without it (see the architecture section above for why).
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
cd retold-remote
|
|
104
|
+
|
|
105
|
+
# Full image (3 GB) -- includes LibreOffice + Calibre for doc conversion
|
|
106
|
+
# Most Synology NAS units are amd64:
|
|
107
|
+
./docker-build-and-save.sh --amd64
|
|
108
|
+
|
|
109
|
+
# OR: slim image (1.8 GB) -- no LibreOffice, no Calibre, no MOBI support
|
|
110
|
+
./docker-build-and-save.sh slim --amd64
|
|
111
|
+
|
|
112
|
+
# OR: ARM-based Synology (rare -- only DS118, DS220j, DS223j, etc.):
|
|
113
|
+
./docker-build-and-save.sh --arm64
|
|
114
|
+
./docker-build-and-save.sh slim --arm64
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
This builds the image, then exports it to `retold-stack-image.tar.gz` (or `retold-stack-image-slim.tar.gz` for slim). Measured compressed sizes:
|
|
118
|
+
|
|
119
|
+
- **Full** (`retold-stack-image.tar.gz`): ~900 MB compressed (3 GB uncompressed)
|
|
120
|
+
- **Slim** (`retold-stack-image-slim.tar.gz`): ~425 MB compressed (1.81 GB uncompressed)
|
|
121
|
+
|
|
122
|
+
### 1.5. (Optional but recommended) Smoke-test the image locally
|
|
123
|
+
|
|
124
|
+
Before transferring the multi-hundred-MB image to your NAS, verify it works by running the included smoke test:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
./docker-smoke-test.sh retold-stack:latest
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This generates test fixtures (small/medium/large images, video, audio, PDF, RTF), spins up a temporary container against them, and exercises every API endpoint. You'll see output like:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
Pre-flight checks
|
|
134
|
+
------------------------------------------------------------
|
|
135
|
+
Image: retold-stack:latest
|
|
136
|
+
Image arch: amd64
|
|
137
|
+
Host arch: arm64
|
|
138
|
+
WARNING: Architecture mismatch!
|
|
139
|
+
The image is amd64 but the host is arm64.
|
|
140
|
+
The container will run under QEMU emulation, which is very slow...
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
That warning at the top is **normal and expected** when you're cross-building on a Mac for an amd64 NAS -- but tests that use heavy native code may time out under emulation. **The image will still work fine on the actual NAS** because there's no emulation there. If all tests pass even under emulation, you're golden.
|
|
144
|
+
|
|
145
|
+
If you want to skip emulation and just verify the build is correct, build a matching image for your build host arch and smoke-test that one too:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
./docker-build-and-save.sh --arm64 # match your Mac
|
|
149
|
+
./docker-smoke-test.sh retold-stack:latest # tests run native, fast
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 2. On the NAS: create the project folder
|
|
153
|
+
|
|
154
|
+
In File Station, navigate to `/volume1/docker/` (create the `docker` shared folder first if it doesn't exist). Create a subfolder named `retold-stack`.
|
|
155
|
+
|
|
156
|
+
The final path should be: `/volume1/docker/retold-stack/`
|
|
157
|
+
|
|
158
|
+
### 3. Transfer the image and compose file
|
|
159
|
+
|
|
160
|
+
Copy two files into that folder:
|
|
161
|
+
|
|
162
|
+
- `retold-stack-image.tar.gz` (or `-slim.tar.gz`)
|
|
163
|
+
- `docker-compose.yml` (from the retold-remote repo root)
|
|
164
|
+
|
|
165
|
+
You can use File Station upload, scp, or rsync. Example via scp:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Use the -O flag to force the legacy SCP protocol -- see the note below.
|
|
169
|
+
scp -O retold-stack-image.tar.gz docker-compose.yml \
|
|
170
|
+
admin@your-nas-ip:/volume1/docker/retold-stack/
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
> **Heads up -- OpenSSH 9.0+ scp gotcha:** Modern scp (OpenSSH 9.0 and later) defaults to SFTP under the hood, and Synology's SFTP daemon errors out with `dest open ".../foo/": No such file or directory` on trailing-slash directory destinations even when the directory exists and you have full read/write access.
|
|
174
|
+
>
|
|
175
|
+
> The `-O` flag forces the legacy SCP/RCP protocol and sidesteps the issue. If `-O` still gives you trouble, try one of these alternatives:
|
|
176
|
+
>
|
|
177
|
+
> ```bash
|
|
178
|
+
> # Specify the destination filename explicitly (no trailing slash)
|
|
179
|
+
> scp retold-stack-image.tar.gz \
|
|
180
|
+
> admin@your-nas-ip:/volume1/docker/retold-stack/retold-stack-image.tar.gz
|
|
181
|
+
>
|
|
182
|
+
> # Or use rsync, which is unaffected
|
|
183
|
+
> rsync -avh --progress retold-stack-image.tar.gz docker-compose.yml \
|
|
184
|
+
> admin@your-nas-ip:/volume1/docker/retold-stack/
|
|
185
|
+
> ```
|
|
186
|
+
>
|
|
187
|
+
> If even rsync fails with permission errors, check **DSM Control Panel -> File Services -> FTP -> SFTP** and make sure **Enable SFTP service** is checked. SSH access and SFTP are separate switches in DSM.
|
|
188
|
+
|
|
189
|
+
### 4. Load the image on the NAS
|
|
190
|
+
|
|
191
|
+
There are two ways to do this -- pick whichever feels easier.
|
|
192
|
+
|
|
193
|
+
**Option A: Container Manager UI**
|
|
194
|
+
|
|
195
|
+
1. Open **Container Manager** -> **Image** -> **Add** -> **Add From File**
|
|
196
|
+
2. Browse to `/volume1/docker/retold-stack/retold-stack-image.tar.gz` and select it
|
|
197
|
+
3. Wait for the import to finish (a couple of minutes -- it's decompressing 1+ GB)
|
|
198
|
+
|
|
199
|
+
**Option B: SSH (faster)**
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
ssh admin@your-nas-ip
|
|
203
|
+
cd /volume1/docker/retold-stack
|
|
204
|
+
sudo docker load -i retold-stack-image.tar.gz
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
You should see something like:
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
Loaded image: retold-stack:latest
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### 5. Edit the media volume path in docker-compose.yml
|
|
214
|
+
|
|
215
|
+
Open `docker-compose.yml` in File Station's text editor or via SSH. By default the media volume uses an environment variable with a fallback:
|
|
216
|
+
|
|
217
|
+
```yaml
|
|
218
|
+
volumes:
|
|
219
|
+
- ${MEDIA_PATH:-./media}:/media:ro
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Container Manager doesn't set environment variables by default, so **replace that line** with your actual media path:
|
|
223
|
+
|
|
224
|
+
```yaml
|
|
225
|
+
volumes:
|
|
226
|
+
- /volume1/media:/media:ro # <- your NAS media folder
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Common choices:
|
|
230
|
+
|
|
231
|
+
| If your media lives in... | Use this |
|
|
232
|
+
|---------------------------|----------|
|
|
233
|
+
| `/volume1/media` | `- /volume1/media:/media:ro` |
|
|
234
|
+
| `/volume1/photo` (Photo Station) | `- /volume1/photo:/media:ro` |
|
|
235
|
+
| `/volume1/video` (Video Station) | `- /volume1/video:/media:ro` |
|
|
236
|
+
| `/volume1/music` | `- /volume1/music:/media:ro` |
|
|
237
|
+
| Multiple folders | See [Multiple Media Folders](#multiple-media-folders) below |
|
|
238
|
+
|
|
239
|
+
The `:ro` suffix means read-only -- the container can browse but never modify your media. Leave this unless you need collection export to write back to the media folder (use `:rw` in that case).
|
|
240
|
+
|
|
241
|
+
### 6. Create the project in Container Manager
|
|
242
|
+
|
|
243
|
+
1. Open **Container Manager** from the Synology main menu
|
|
244
|
+
2. Click **Project** in the left sidebar
|
|
245
|
+
3. Click **Create**
|
|
246
|
+
4. Fill in the form:
|
|
247
|
+
- **Project name**: `retold-stack`
|
|
248
|
+
- **Path**: `/volume1/docker/retold-stack/`
|
|
249
|
+
- **Source**: `Use existing docker-compose.yml`
|
|
250
|
+
5. Container Manager will read the compose file and show the service it detected (`retold-stack`)
|
|
251
|
+
6. Click **Next**, review the settings, and click **Done**
|
|
252
|
+
|
|
253
|
+
Because the compose file uses `image: retold-stack:latest` (not `build:`), Container Manager skips the build step entirely. It just creates the named volumes and starts the container -- usually within 30 seconds.
|
|
254
|
+
|
|
255
|
+
### 7. Browse to the web UI
|
|
256
|
+
|
|
257
|
+
Once the container is running (look for "Running" status in Container Manager), open:
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
http://your-nas-ip:7777/
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
You should see the Retold Remote gallery showing the contents of the folder you mounted.
|
|
264
|
+
|
|
265
|
+
The Ultravisor web interface is also available at `http://your-nas-ip:54321/` for monitoring the beacon mesh and work queue.
|
|
266
|
+
|
|
267
|
+
## Pulling From a Registry Instead
|
|
268
|
+
|
|
269
|
+
If you've published the image to a registry (Docker Hub, GitHub Container Registry, your own private registry), you can skip the build-and-transfer dance entirely. Edit `docker-compose.yml`:
|
|
270
|
+
|
|
271
|
+
```yaml
|
|
272
|
+
services:
|
|
273
|
+
retold-stack:
|
|
274
|
+
image: ghcr.io/yourname/retold-stack:latest # <- your registry path
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Then before creating the project on the NAS, run `docker login <registry>` via SSH if it's a private registry. Container Manager will pull the image automatically when the project starts.
|
|
278
|
+
|
|
279
|
+
This is the cleanest workflow if you maintain a CI pipeline that publishes images on every commit.
|
|
280
|
+
|
|
281
|
+
## Building From Source on the NAS (Not Recommended)
|
|
282
|
+
|
|
283
|
+
If you really want to build on the NAS itself (e.g., to make local modifications to the source):
|
|
284
|
+
|
|
285
|
+
1. Copy the **entire** retold-remote source tree to `/volume1/docker/retold-stack/` -- including `Dockerfile`, `package.json`, `package-lock.json`, `source/`, `web-application/`, `css/`, `html/`, and `.dockerignore`. The folder structure must match the repo exactly.
|
|
286
|
+
2. Edit `docker-compose.yml`:
|
|
287
|
+
- Comment out the `image: retold-stack:latest` line
|
|
288
|
+
- Uncomment the `build:` block
|
|
289
|
+
3. In Container Manager -> Project -> Create, point at the folder. Container Manager will run `docker build` against the local Dockerfile.
|
|
290
|
+
|
|
291
|
+
Expect this to take **30-60 minutes** on most NAS hardware and roughly **5 GB of free space** during the build (intermediate layers + base image + final image). It's almost always faster to build on a real machine and transfer the tar.
|
|
292
|
+
|
|
293
|
+
## Resource Considerations
|
|
294
|
+
|
|
295
|
+
The default compose file sets conservative limits:
|
|
296
|
+
|
|
297
|
+
```yaml
|
|
298
|
+
deploy:
|
|
299
|
+
resources:
|
|
300
|
+
limits:
|
|
301
|
+
memory: 2G
|
|
302
|
+
reservations:
|
|
303
|
+
memory: 512M
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Adjust these based on your NAS hardware:
|
|
307
|
+
|
|
308
|
+
| NAS Model | Total RAM | Recommended `memory` limit |
|
|
309
|
+
|-----------|-----------|---------------------------|
|
|
310
|
+
| Low-end (DS120j, DS220j) | 512 MB - 1 GB | Use `Dockerfile.slim`, limit to 512 MB |
|
|
311
|
+
| Mid-range (DS220+, DS920+) | 2-4 GB | 1-2 GB (default 2G works) |
|
|
312
|
+
| High-end (DS1621+, DS923+) | 4-32 GB | 2-8 GB |
|
|
313
|
+
|
|
314
|
+
LibreOffice and Calibre conversions can spike memory usage -- if you see OOM kills in the logs, bump the limit up.
|
|
315
|
+
|
|
316
|
+
### Low-RAM NAS: Use the Slim Variant
|
|
317
|
+
|
|
318
|
+
If your NAS has limited RAM (under 2 GB) or limited disk space, build the slim variant on your dev machine instead:
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
./docker-build-and-save.sh slim
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
This produces `retold-stack-image-slim.tar.gz` (~600 MB compressed). Transfer and load it the same way as the full image -- it tags itself as `retold-stack:slim`. Then update the compose file's image line:
|
|
325
|
+
|
|
326
|
+
```yaml
|
|
327
|
+
image: retold-stack:slim # <- was retold-stack:latest
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
The slim variant:
|
|
331
|
+
- **1.81 GB** uncompressed instead of 3.0 GB (about 1.2 GB smaller)
|
|
332
|
+
- Still supports all image, video, audio, PDF, and EPUB features
|
|
333
|
+
- **Does not** support DOC, DOCX, RTF, ODT, WPD, MOBI, or PowerPoint/Excel
|
|
334
|
+
- **Does not** support MOBI->EPUB conversion
|
|
335
|
+
|
|
336
|
+
## Volume Mounts Explained
|
|
337
|
+
|
|
338
|
+
The compose file defines four volume mounts:
|
|
339
|
+
|
|
340
|
+
| Mount | Path in container | Purpose |
|
|
341
|
+
|-------|-------------------|---------|
|
|
342
|
+
| `/volume1/media:/media:ro` | `/media` | Your media folder (read-only) |
|
|
343
|
+
| `retold-cache:/cache` | `/cache` | Thumbnails, video frames, audio waveforms, converted PDFs, DZI tiles |
|
|
344
|
+
| `ultravisor-data:/data` | `/data` | Ultravisor datastore + work queue journal + staging |
|
|
345
|
+
| `retold-config:/config` | `/config` | Generated stack config files |
|
|
346
|
+
|
|
347
|
+
The last three are **named Docker volumes** -- Synology stores them under `/volume1/@docker/volumes/retold-stack_<name>/`. They persist across container restarts and image rebuilds.
|
|
348
|
+
|
|
349
|
+
### Using Host Folders Instead
|
|
350
|
+
|
|
351
|
+
If you prefer to manage the cache/data as regular folders you can see in File Station, replace the named volumes with bind mounts:
|
|
352
|
+
|
|
353
|
+
```yaml
|
|
354
|
+
volumes:
|
|
355
|
+
- /volume1/media:/media:ro
|
|
356
|
+
- /volume1/docker/retold-stack/cache:/cache
|
|
357
|
+
- /volume1/docker/retold-stack/data:/data
|
|
358
|
+
- /volume1/docker/retold-stack/config:/config
|
|
359
|
+
|
|
360
|
+
# And remove the `volumes:` block at the bottom of the file.
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
Then create those subfolders in File Station before starting the project.
|
|
364
|
+
|
|
365
|
+
## Multiple Media Folders
|
|
366
|
+
|
|
367
|
+
To browse multiple top-level folders as one unified content tree, create a parent folder and mount it:
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
# On the NAS (via SSH or File Station)
|
|
371
|
+
mkdir /volume1/retold-media
|
|
372
|
+
ln -s /volume1/photo /volume1/retold-media/Photos
|
|
373
|
+
ln -s /volume1/video /volume1/retold-media/Videos
|
|
374
|
+
ln -s /volume1/music /volume1/retold-media/Music
|
|
375
|
+
ln -s /volume1/ebooks /volume1/retold-media/Books
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Then mount `/volume1/retold-media` as the media volume. The gallery will show each linked folder as a top-level entry.
|
|
379
|
+
|
|
380
|
+
Alternatively, you can mount multiple folders to different paths inside the container:
|
|
381
|
+
|
|
382
|
+
```yaml
|
|
383
|
+
volumes:
|
|
384
|
+
- /volume1/photo:/media/Photos:ro
|
|
385
|
+
- /volume1/video:/media/Videos:ro
|
|
386
|
+
- /volume1/music:/media/Music:ro
|
|
387
|
+
- /volume1/ebooks:/media/Books:ro
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Either approach works -- the first is simpler for large numbers of folders.
|
|
391
|
+
|
|
392
|
+
## Updating the Container
|
|
393
|
+
|
|
394
|
+
When a new version of Retold Remote is released:
|
|
395
|
+
|
|
396
|
+
1. On your dev machine, pull the latest retold-remote repo
|
|
397
|
+
2. Re-run `./docker-build-and-save.sh` to produce a new tar.gz
|
|
398
|
+
3. Copy the new tar.gz to the NAS, overwriting the old one
|
|
399
|
+
4. SSH into the NAS and run:
|
|
400
|
+
```bash
|
|
401
|
+
sudo docker load -i retold-stack-image.tar.gz
|
|
402
|
+
```
|
|
403
|
+
(or use Container Manager -> Image -> Add -> Add From File again)
|
|
404
|
+
5. In Container Manager -> Project -> `retold-stack` -> **Stop**, then **Start**
|
|
405
|
+
|
|
406
|
+
The container will restart using the freshly loaded image. Your cache, datastore, and config are stored in named volumes so they survive the update untouched.
|
|
407
|
+
|
|
408
|
+
If you're pulling from a registry instead, just `docker compose pull && docker compose up -d` (or use Container Manager's Reset action on the container).
|
|
409
|
+
|
|
410
|
+
## Reverse Proxy (HTTPS Access)
|
|
411
|
+
|
|
412
|
+
If you want to expose Retold Remote over HTTPS via a domain name, use Synology's built-in reverse proxy:
|
|
413
|
+
|
|
414
|
+
1. **Control Panel** -> **Login Portal** -> **Advanced** -> **Reverse Proxy**
|
|
415
|
+
2. Click **Create** and fill in:
|
|
416
|
+
- **Source protocol**: HTTPS
|
|
417
|
+
- **Source hostname**: `media.yourdomain.com` (or whatever subdomain you prefer)
|
|
418
|
+
- **Source port**: 443
|
|
419
|
+
- **Destination protocol**: HTTP
|
|
420
|
+
- **Destination hostname**: `localhost`
|
|
421
|
+
- **Destination port**: 7777
|
|
422
|
+
3. On the **Custom Header** tab, add **WebSocket** (auto-generated rules)
|
|
423
|
+
4. Save
|
|
424
|
+
|
|
425
|
+
You can then access Retold Remote at `https://media.yourdomain.com/` with Synology's Let's Encrypt certificate.
|
|
426
|
+
|
|
427
|
+
## Troubleshooting
|
|
428
|
+
|
|
429
|
+
### "Small images work but videos and large images don't" (the most common issue)
|
|
430
|
+
|
|
431
|
+
If the gallery loads, small thumbnails appear, but anything that needs heavy processing (large image previews, video frame extraction, audio waveforms, document conversion) silently fails or hangs -- **you almost certainly have an architecture mismatch**.
|
|
432
|
+
|
|
433
|
+
**Quick diagnosis:**
|
|
434
|
+
|
|
435
|
+
1. SSH into the NAS and check the container logs:
|
|
436
|
+
```bash
|
|
437
|
+
sudo docker logs retold-stack 2>&1 | grep -E "WARNING|emulation|VirtualApple"
|
|
438
|
+
```
|
|
439
|
+
If you see `WARNING: container is running under emulation!`, that's your answer.
|
|
440
|
+
|
|
441
|
+
2. From your dev machine, run the smoke test against the same image you transferred:
|
|
442
|
+
```bash
|
|
443
|
+
./docker-smoke-test.sh retold-stack:latest
|
|
444
|
+
```
|
|
445
|
+
It will report `Image arch: ...` and `Host arch: ...` and tell you exactly what to do.
|
|
446
|
+
|
|
447
|
+
**Fix:**
|
|
448
|
+
|
|
449
|
+
```bash
|
|
450
|
+
# On your dev machine, rebuild with the correct target arch:
|
|
451
|
+
./docker-build-and-save.sh --amd64 # most Synology models (Celeron/Pentium/Atom/Ryzen/Xeon)
|
|
452
|
+
# Or:
|
|
453
|
+
./docker-build-and-save.sh --arm64 # the few ARM-based Synology models
|
|
454
|
+
|
|
455
|
+
# Transfer the new tar.gz to the NAS:
|
|
456
|
+
scp -O retold-stack-image.tar.gz steven@your-nas:/volume1/docker/retold-stack/
|
|
457
|
+
|
|
458
|
+
# On the NAS:
|
|
459
|
+
sudo docker load -i /volume1/docker/retold-stack/retold-stack-image.tar.gz
|
|
460
|
+
|
|
461
|
+
# Restart the project in Container Manager (Stop, then Start)
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### scp error: `dest open ".../folder/": No such file or directory`
|
|
465
|
+
|
|
466
|
+
This is the OpenSSH 9.0+ scp/SFTP gotcha. Modern scp uses SFTP under the hood, and Synology's SFTP daemon stumbles on trailing-slash directory paths even when the directory exists. **Fix:** add `-O` to force the legacy SCP protocol:
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
scp -O retold-stack-image.tar.gz steven@nas-ip:/volume1/docker/retold-stack/
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
If `-O` still doesn't work, try specifying the destination filename explicitly (no trailing slash), or use `rsync` instead:
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
rsync -avh --progress retold-stack-image.tar.gz steven@nas-ip:/volume1/docker/retold-stack/
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
If even rsync fails, check that SFTP is actually enabled at **DSM Control Panel -> File Services -> FTP -> SFTP -> Enable SFTP service**. SSH access and SFTP are separate toggles in DSM.
|
|
479
|
+
|
|
480
|
+
### Project creation error: "unable to evaluate symlinks in Dockerfile path"
|
|
481
|
+
|
|
482
|
+
```
|
|
483
|
+
unable to prepare context: unable to evaluate symlinks in Dockerfile path:
|
|
484
|
+
lstat /volume1/docker/retold-stack/Dockerfile: no such file or directory
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
This means your `docker-compose.yml` is using `build:` instead of `image:`, but the Dockerfile and source tree are not in the project folder. **Fix:**
|
|
488
|
+
|
|
489
|
+
1. Make sure the compose file's services block looks like this:
|
|
490
|
+
```yaml
|
|
491
|
+
services:
|
|
492
|
+
retold-stack:
|
|
493
|
+
image: retold-stack:latest
|
|
494
|
+
# build: <- must be commented out
|
|
495
|
+
# context: .
|
|
496
|
+
# dockerfile: Dockerfile
|
|
497
|
+
```
|
|
498
|
+
2. Make sure you've actually loaded the image first: `sudo docker load -i retold-stack-image.tar.gz` (or via Container Manager's Image -> Add -> From File). Verify with `sudo docker images | grep retold-stack`.
|
|
499
|
+
3. Recreate the project in Container Manager.
|
|
500
|
+
|
|
501
|
+
### Other common issues
|
|
502
|
+
|
|
503
|
+
| Symptom | Fix |
|
|
504
|
+
|---------|-----|
|
|
505
|
+
| `image not found: retold-stack:latest` | You forgot step 4 (load the image). Run `sudo docker load -i retold-stack-image.tar.gz` first, then start the project. |
|
|
506
|
+
| `exec format error` when starting the container | The image was built for the wrong CPU architecture. Most Synology models are AMD64. Rebuild with `./docker-build-and-save.sh --amd64` (or `--arm64` for ARM-based models) and reload. |
|
|
507
|
+
| Container won't start, logs show "permission denied" on /media | The `node` user inside the container (UID 1000) can't read your media folder. Either chmod the folder to world-readable, or run the container as a different user with `user: "0:0"` in compose (runs as root -- less secure but works) |
|
|
508
|
+
| Logs show "Ultravisor did not become ready within 30000ms" | Resource-constrained NAS. Increase the memory limit in compose, or use the slim variant |
|
|
509
|
+
| Port 7777 already in use | Change the host-side port in compose: `- "8080:7777"` (leaves container side on 7777) |
|
|
510
|
+
| Can't reach http://nas-ip:7777/ from another machine | Check Synology **Control Panel -> Security -> Firewall**. Make sure port 7777 is allowed. |
|
|
511
|
+
| Thumbnails are slow / CPU spikes | Normal during first browse -- thumbnails are generated on demand and cached. Subsequent browses of the same folder will be instant. |
|
|
512
|
+
| Container uses too much memory | Reduce the `memory:` limit in compose, or use the slim variant to drop Calibre and LibreOffice |
|
|
513
|
+
| Collection export fails with "Destination path must be within the content root" | Remember that exports go to subfolders of the `/media` mount. If you mounted `:ro` you'll need to change it to `:rw` or mount a separate writable folder |
|
|
514
|
+
|
|
515
|
+
### Viewing Logs
|
|
516
|
+
|
|
517
|
+
In Container Manager -> Container -> `retold-stack` -> **Details** -> **Log** tab. You'll see output from both the main retold-remote process and the child ultravisor process, with `[ultravisor]` prefixes for the latter.
|
|
518
|
+
|
|
519
|
+
Via SSH:
|
|
520
|
+
|
|
521
|
+
```bash
|
|
522
|
+
docker logs -f retold-stack
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### SSH Into the Running Container
|
|
526
|
+
|
|
527
|
+
```bash
|
|
528
|
+
docker exec -it retold-stack /bin/bash
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
Useful for checking installed tools (`which ffmpeg`, `soffice --version`, etc.), inspecting cache contents at `/cache`, or testing conversions manually.
|
|
532
|
+
|
|
533
|
+
## Performance Tips
|
|
534
|
+
|
|
535
|
+
- **Store the cache on SSD** if your NAS has an M.2 SSD cache -- thumbnails are I/O-intensive
|
|
536
|
+
- **Use a faster network** -- the 54321 port between the beacon (retold-remote) and the coordinator (ultravisor) is localhost, but media I/O from `/volume1` benefits from good disk speed
|
|
537
|
+
- **Preload thumbnails** by browsing a folder once; subsequent visits hit the cache
|
|
538
|
+
- **Adjust the memory limit upward** if you regularly browse very large images (>100 MP) or convert long documents -- LibreOffice spikes can hit 1.5 GB
|
|
539
|
+
- **Disable hashing** (`--no-hash` in CMD, already the default) for slightly faster URL resolution on resource-constrained NAS units
|
|
540
|
+
|
|
541
|
+
## Architecture Inside the Container
|
|
542
|
+
|
|
543
|
+
```
|
|
544
|
+
┌────────────────────────────────────────────────────────────┐
|
|
545
|
+
│ Container: retold-stack │
|
|
546
|
+
│ │
|
|
547
|
+
│ Node process 1 (main): retold-remote │
|
|
548
|
+
│ ├─ HTTP server on :7777 │
|
|
549
|
+
│ ├─ Orator-Conversion embedded │
|
|
550
|
+
│ └─ Ultravisor Beacon client -> connects to :54321 │
|
|
551
|
+
│ │
|
|
552
|
+
│ Node process 2 (child): ultravisor │
|
|
553
|
+
│ ├─ HTTP server on :54321 │
|
|
554
|
+
│ ├─ Datastore at /data/ultravisor/datastore │
|
|
555
|
+
│ └─ Staging at /data/ultravisor/staging │
|
|
556
|
+
│ │
|
|
557
|
+
│ Shell tools available: │
|
|
558
|
+
│ ffmpeg, ffprobe, sharp (native), convert, 7z, │
|
|
559
|
+
│ pdftk, pdftoppm, soffice, ebook-convert, │
|
|
560
|
+
│ audiowaveform, exiftool, dcraw │
|
|
561
|
+
│ │
|
|
562
|
+
│ Volumes: │
|
|
563
|
+
│ /media (ro, host media folder) │
|
|
564
|
+
│ /cache (rw, named volume: retold-cache) │
|
|
565
|
+
│ /data (rw, named volume: ultravisor-data) │
|
|
566
|
+
│ /config (rw, named volume: retold-config) │
|
|
567
|
+
└────────────────────────────────────────────────────────────┘
|
|
568
|
+
│ │
|
|
569
|
+
▼ ▼
|
|
570
|
+
http://nas:7777/ http://nas:54321/
|
|
571
|
+
(Retold Remote UI) (Ultravisor UI)
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
## Uninstalling
|
|
575
|
+
|
|
576
|
+
In Container Manager -> Project -> `retold-stack` -> **Stop** -> **Delete**.
|
|
577
|
+
|
|
578
|
+
To also remove the cached data:
|
|
579
|
+
|
|
580
|
+
```bash
|
|
581
|
+
# Via SSH
|
|
582
|
+
docker volume rm retold-stack_retold-cache retold-stack_ultravisor-data retold-stack_retold-config
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
The media folder on your NAS is never touched (the container only has read access).
|
|
@@ -23,10 +23,10 @@ brew install ffmpeg
|
|
|
23
23
|
|
|
24
24
|
### Windows
|
|
25
25
|
|
|
26
|
-
1. Download a release build from [gyan.dev/ffmpeg](https://www.gyan.dev/ffmpeg/builds/)
|
|
26
|
+
1. Download a release build from [gyan.dev/ffmpeg](https://www.gyan.dev/ffmpeg/builds/) -- choose the **ffmpeg-release-full** zip.
|
|
27
27
|
2. Extract to a permanent location, e.g. `C:\ffmpeg`.
|
|
28
28
|
3. Add `C:\ffmpeg\bin` to the system PATH:
|
|
29
|
-
- Open **Settings
|
|
29
|
+
- Open **Settings -> System -> About -> Advanced system settings -> Environment Variables**.
|
|
30
30
|
- Edit the **Path** variable under System variables and add `C:\ffmpeg\bin`.
|
|
31
31
|
4. Open a new terminal and verify:
|
|
32
32
|
|
|
@@ -56,7 +56,7 @@ brew install imagemagick
|
|
|
56
56
|
|
|
57
57
|
### Windows
|
|
58
58
|
|
|
59
|
-
1. Download the installer from [imagemagick.org/script/download.php](https://imagemagick.org/script/download.php)
|
|
59
|
+
1. Download the installer from [imagemagick.org/script/download.php](https://imagemagick.org/script/download.php) -- choose the **Win64 dynamic** installer.
|
|
60
60
|
2. During installation, check **Add application directory to your system path** and **Install legacy utilities (e.g. convert)**.
|
|
61
61
|
3. Open a new terminal and verify:
|
|
62
62
|
|
|
@@ -139,8 +139,8 @@ brew install audiowaveform
|
|
|
139
139
|
|
|
140
140
|
audiowaveform does not provide official Windows binaries. Options:
|
|
141
141
|
|
|
142
|
-
1. **WSL** (recommended)
|
|
143
|
-
2. **Build from source**
|
|
142
|
+
1. **WSL** (recommended) -- install Ubuntu via WSL and follow the Ubuntu instructions above. Run the beacon worker inside WSL.
|
|
143
|
+
2. **Build from source** -- requires CMake, Visual Studio, and the Boost, libmad, libsndfile, and libgd libraries. See the [audiowaveform GitHub repo](https://github.com/bbc/audiowaveform) for build instructions.
|
|
144
144
|
|
|
145
145
|
## ebook-convert (Calibre)
|
|
146
146
|
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
retold-remote can offload heavy media processing to a remote machine running an Ultravisor beacon worker. This is useful when the server (e.g. a NAS) has limited CPU and RAM but needs to process large video files, raw camera images, audio waveforms, and ebook conversions.
|
|
4
4
|
|
|
5
|
+
> **Tip:** If you just want to run Ultravisor and Retold Remote together on the same machine without configuring anything, use the [Stack Launcher](stack-launcher.md) -- `retold-stack /path/to/media` spawns Ultravisor as a child process automatically with sane XDG-style data paths. This page covers the case where Ultravisor runs on a *different* machine.
|
|
6
|
+
|
|
5
7
|
## How It Works
|
|
6
8
|
|
|
7
9
|
When configured, retold-remote dispatches shell commands (ffmpeg, ffprobe, dcraw, ImageMagick, audiowaveform, ebook-convert) to a beacon worker via HTTP instead of running them locally. The beacon downloads the source file from retold-remote's content API, executes the command, and returns the result as base64-encoded data.
|
|
@@ -9,13 +11,13 @@ When configured, retold-remote dispatches shell commands (ffmpeg, ffprobe, dcraw
|
|
|
9
11
|
```
|
|
10
12
|
NAS (retold-remote) Fast Machine (Ultravisor)
|
|
11
13
|
┌──────────────────────┐ ┌──────────────────────┐
|
|
12
|
-
│ Request
|
|
14
|
+
│ Request -> Check Cache│ │ Ultravisor Server │
|
|
13
15
|
│ ↓ (miss) │ HTTP │ └─ Beacon Worker │
|
|
14
16
|
│ Dispatch command ───┼──────────►│ 1. Download src │
|
|
15
17
|
│ │ │ 2. Run command │
|
|
16
18
|
│ ◄─ base64 result ◄──┼────────────┤ 3. Return output│
|
|
17
19
|
│ ↓ │ │ │
|
|
18
|
-
│ Decode
|
|
20
|
+
│ Decode -> Cache │ └──────────────────────┘
|
|
19
21
|
│ Serve response │
|
|
20
22
|
│ │
|
|
21
23
|
│ ↓ (dispatch fails) │
|