Files
fuji-photo-processor/README.md
Nick Roodenrijs 04ca39d2be Switch from FTP to FTPS (FTP over TLS)
X-H2 supports FTPS natively with root certificate loading.
Synology DSM supports FTP SSL/TLS encryption.
Updated README and TODO with FTPS configuration steps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 19:05:26 +01:00

116 lines
6.1 KiB
Markdown

# Fuji Photo Processor
Automatic photo processing pipeline for Fuji X-H2 photos: camera uploads via FTPS (FTP over TLS) to Synology NAS, files are automatically resized and organized, then picked up by Immich for library management.
## Architecture
```
┌─────────────┐ FTPS ┌──────────────────┐ watchdog ┌─────────────┐
│ Fuji X-H2 │ ──────────→ │ Synology NAS │ ────────────→ │ Processor │
│ (camera) │ port 21 │ /volume2/photos/ │ polling │ container │
└─────────────┘ (TLS) │ incoming/ │ └──────┬──────┘
└──────────────────┘ │
│ resize + move
┌─────────────┴─────────────┐
│ │
┌─────▼─────┐ ┌───────▼───────┐
│ /originals │ │ /processed │
│ YYYY/MM/ │ │ YYYY/MM/ │
│ (full-res) │ │ (1080px max) │
└────────────┘ └───────┬───────┘
┌───────▼───────┐
│ Immich │
│ external lib │
└───────────────┘
```
## Prerequisites
- Synology NAS with Docker (Container Manager) installed
- FTPS (FTP over TLS) enabled on DSM
- Immich running (for photo management)
## Setup
### 1. FTPS Server (DSM)
1. Open **Control Panel → File Services → FTP**
2. Enable FTP service on port **21**
3. Enable **FTP SSL/TLS encryption** (FTPS)
4. Set passive port range: **50000-50100**
5. Create a dedicated user `fujiftp` with write access to `/volume2/photos/incoming`
### 2. Camera Configuration (Fuji X-H2)
Configure an FTP profile on the camera:
| Setting | Value |
|-----------------|--------------------------|
| FTP Server Type | **FTPS** |
| Server IP | `192.168.175.141` |
| Port | `21` |
| Passive Mode | **ON** |
| Username | `fujiftp` |
| Password | *(your password)* |
| Upload Dir | `/incoming` |
| Auto Transfer | ON (or manual trigger) |
> **Note**: Bij FTPS kun je via **FTP OPTIONAL SETTING → ROOT CERTIFICATE** een self-signed root certificaat laden als je NAS er een gebruikt.
### 3. Deploy
```bash
./deploy.sh
```
The deploy script will:
- Create required directories on the NAS
- Transfer and build the Docker image on the NAS
- Start the container with appropriate volume mounts
### 4. Immich Integration
1. In Immich, go to **Administration → External Libraries**
2. Add a new library with import path: `/volume2/photos/processed`
3. Set scan interval (e.g., every 15 minutes)
4. Mount `/volume2/photos/processed` into the Immich container as a read-only volume
## Container Details
### Volumes
| Container Path | Host Path | Purpose |
|----------------|----------------------------------------|---------------------------|
| `/incoming` | `/volume2/photos/incoming` | FTP upload landing zone |
| `/originals` | `/volume2/photos/originals` | Full-resolution originals |
| `/processed` | `/volume2/photos/processed` | Resized copies for Immich |
| `/data` | `/volume2/docker/photo-processor/data` | SQLite tracking database |
### Environment Variables
| Variable | Default | Description |
|-----------------|---------|--------------------------------------|
| `POLL_INTERVAL` | `30` | Filesystem poll interval in seconds |
| `JPEG_QUALITY` | `85` | JPEG compression quality (1-100) |
| `MAX_WIDTH` | `1080` | Maximum width for resized images |
| `MAX_HEIGHT` | `1920` | Maximum height for resized images |
| `TZ` | `Europe/Amsterdam` | Container timezone |
## Troubleshooting
### Check container logs
```bash
ssh -i ../SynologyDocker/synology_ssh_key ssh@192.168.175.141 \
'sudo /usr/local/bin/docker logs -f photo-processor'
```
### Common Issues
- **Files not detected**: Check that the FTP user has write permissions to `/volume2/photos/incoming`. The processor uses polling (not inotify) so there may be up to a 30-second delay.
- **Permission denied on originals/processed**: Ensure the directories exist and are writable. The deploy script creates them automatically.
- **Duplicate filenames**: The processor tracks files by filename in SQLite. If you re-upload a file with the same name, it will be skipped. Delete the entry from `/volume2/docker/photo-processor/data/processed.db` to reprocess.
- **Container keeps restarting**: Check logs for Python errors. Common cause: missing directories or permission issues on volume mounts.
- **EXIF data lost**: The processor preserves EXIF data from the original. If EXIF is missing, the original file may not have contained it (check camera settings).