128 lines
No EOL
3 KiB
Markdown
128 lines
No EOL
3 KiB
Markdown
---
|
|
title: Immich on ZFS
|
|
description: Moving Immich to its own ZFS dataset
|
|
published: true
|
|
date: 2026-02-06T15:57:04.261Z
|
|
tags: service zfs immich dataset
|
|
editor: markdown
|
|
dateCreated: 2026-02-06T15:57:04.261Z
|
|
---
|
|
|
|
# Moving Immich to a ZFS Dataset
|
|
|
|
## Overview
|
|
This guide covers moving an existing Immich installation to its own ZFS dataset to enable `zfs send` backups.
|
|
|
|
## Prerequisites
|
|
- ZFS pool mounted at `/srv/vault`
|
|
- Existing Immich installation at `/srv/vault/immich`
|
|
- Immich running via Docker Compose
|
|
|
|
## Steps
|
|
|
|
### 1. Stop Immich Services
|
|
```bash
|
|
cd /srv/vault/immich # or wherever your docker-compose.yml is
|
|
docker compose down
|
|
```
|
|
|
|
### 2. Create the New Dataset
|
|
```bash
|
|
sudo zfs create vault/immich
|
|
```
|
|
|
|
### 3. Move Existing Data Temporarily
|
|
```bash
|
|
sudo mv /srv/vault/immich /srv/vault/immich_old
|
|
```
|
|
|
|
### 4. Set Mountpoint and Mount Dataset
|
|
```bash
|
|
sudo zfs set mountpoint=/srv/immich vault/immich
|
|
sudo zfs mount vault/immich
|
|
```
|
|
|
|
### 5. Copy Data to New Dataset
|
|
```bash
|
|
sudo rsync -avxHAX /srv//immich_old/ /srv/immich/
|
|
```
|
|
|
|
Flags preserve permissions, ownership, and special attributes.
|
|
|
|
### 6. Verify Data Copy
|
|
```bash
|
|
sudo du -sh /srv/vault/immich_old
|
|
sudo du -sh /srv/vault/immich
|
|
```
|
|
|
|
Sizes should match closely.
|
|
|
|
### 7. Start Immich
|
|
```bash
|
|
cd /srv/vault/immich
|
|
docker compose up -d
|
|
```
|
|
|
|
### 8. Test and Clean Up
|
|
Verify everything works, then remove old data:
|
|
```bash
|
|
sudo rm -rf /srv/vault/immich_old
|
|
```
|
|
|
|
## ZFS Dataset Properties
|
|
|
|
### Recommended Settings
|
|
```bash
|
|
# Compression - helps with photos and database
|
|
sudo zfs set compression=lz4 vault/immich
|
|
|
|
# Record size - balance for mixed workload
|
|
sudo zfs set recordsize=128K vault/immich
|
|
|
|
# Better database performance
|
|
sudo zfs set primarycache=all vault/immich
|
|
sudo zfs set atime=off vault/immich
|
|
```
|
|
|
|
### Property Explanations
|
|
- **compression=lz4**: Fast, low CPU overhead, works well for both photos and database
|
|
- **recordsize=128K**: Good compromise between database (8K blocks) and photos (larger files)
|
|
- **atime=off**: Disables access time updates, reduces unnecessary writes
|
|
- **primarycache=all**: Keeps both metadata and data in ARC cache (default)
|
|
|
|
## Backup with ZFS Send/Receive
|
|
|
|
### Create Snapshot
|
|
```bash
|
|
zfs snapshot vault/immich@backup-$(date +%Y%m%d)
|
|
```
|
|
|
|
### Send to Remote Server
|
|
```bash
|
|
zfs send vault/immich@backup-$(date +%Y%m%d) | ssh backup-server zfs receive tank/backups/immich
|
|
```
|
|
|
|
### Incremental Backups
|
|
```bash
|
|
# After first full backup
|
|
zfs snapshot vault/immich@backup-$(date +%Y%m%d)
|
|
zfs send -i vault/immich@previous-snapshot vault/immich@backup-$(date +%Y%m%d) | \
|
|
ssh backup-server zfs receive tank/backups/immich
|
|
```
|
|
|
|
## Optional: Separate Datasets for Database and Photos
|
|
|
|
For optimal performance, split into separate datasets:
|
|
```bash
|
|
sudo zfs create vault/immich/database
|
|
sudo zfs create vault/immich/photos
|
|
|
|
# Database optimized
|
|
sudo zfs set recordsize=16K vault/immich/database
|
|
sudo zfs set logbias=latency vault/immich/database
|
|
|
|
# Photos optimized
|
|
sudo zfs set recordsize=1M vault/immich/photos
|
|
```
|
|
|
|
Then update your Docker Compose volume mounts accordingly. |