CLI tool for migrating photo albums between Immich servers
Project description
๐ธ Immich Migration Tool
Migrate your photo library between Immich servers with confidence.
โจ Features
- ๐ฏ Interactive Album Selection: TUI for choosing albums to migrate
- ๐ฆ Batch Processing: Downloads and uploads in configurable batches
- ๐ Progress Tracking: Real-time progress bars for downloads and uploads
- ๐พ State Persistence: Resume interrupted migrations seamlessly (state saved to
~/.immich-migrator/state.json) - โ Checksum Verification: SHA1 verification for data integrity with configurable retry attempts
- ๐ Error Handling: Graceful recovery from network failures with retry logic
- ๐ท Unalbummed Assets: Migrate photos not organized in albums (presented as virtual album in selection)
- ๐ EXIF Preservation: Maintains all photo metadata; original capture dates are injected into downloaded files before upload
- ๐ธ Live Photo Support: Automatically detects and links iPhone Live Photos (image + video pairs)
- ๐๏ธ Failed Assets Recovery: Assets that fail verification are saved to
./immich_failed_assets(configurable) for manual review
๐ฆ Installation
[!TIP] Use uvx to run the tool instantly without installation โ perfect for one-time migrations:
uvx immich-migrator migrate
Install with uv (persistent)
uv tool install immich-migrator
Traditional pip install
pip install immich-migrator
From Source
git clone https://github.com/kallegrens/immich-migrator.git
cd immich-migrator
uv sync
๐ Quick Start
Prerequisites
Before you begin, ensure you have:
-
Python: 3.11 or higher โ
-
Disk Space: At least 5GB free for temporary storage of downloaded batches ๐พ
-
ExifTool: For EXIF metadata handling ๐
# Ubuntu/Debian sudo apt-get install libimage-exiftool-perl # macOS brew install exiftool
1. Prepare a unified credentials file
The tool expects a single credentials file containing both old and new server details. By default, it looks for ~/.immich.env.
Create ~/.immich.env (or copy from .immich.env.example):
# ~/.immich.env
# OLD server
OLD_IMMICH_SERVER_URL=https://old.immich.example.com
OLD_IMMICH_API_KEY=your-old-server-api-key-here
# NEW server
NEW_IMMICH_SERVER_URL=https://new.immich.example.com
NEW_IMMICH_API_KEY=your-new-server-api-key-here
[!NOTE] You can provide an explicit path with
--credentials(or-c). When specified, the default~/.immich.envlookup is skipped.
2. Run migration
Run with the default credentials file (~/.immich.env):
uv run immich-migrator migrate
Or specify a custom credentials path:
uv run immich-migrator migrate -c /path/to/your/credentials.env
What happens next? ๐ฌ
- ๐ Connects to your old Immich server
- ๐ Discovers all albums (including unalbummed assets)
- ๐ฏ Displays an interactive menu for album selection
- โฌ๏ธ Downloads selected albums with progress tracking
- โฌ๏ธ Uploads to the new server with album organization intact
- ๐พ Saves state for resume capability
๐ฏ Usage Examples
View Available Commands
immich-migrator --help
immich-migrator migrate --help
Basic Migration
immich-migrator migrate
Custom Batch Size
immich-migrator migrate --batch-size 30
Custom Configuration
immich-migrator migrate --config config.toml
Debug Mode
immich-migrator migrate --log-level DEBUG
Quiet Mode (Warnings/Errors Only)
immich-migrator migrate --quiet
Custom Failed Assets Directory
immich-migrator migrate --failed-output-dir /path/to/failed/assets
Adjust Verification Retries
immich-migrator migrate --verify-retries 5
โ๏ธ Configuration
Create a config.toml file for advanced configuration. All settings are optional and have sensible defaults.
Available Configuration Options
# Batch processing
batch_size = 20 # Assets per batch (1-100, default: 20)
# Performance tuning
max_concurrent_downloads = 5 # Parallel downloads (1-20, default: 5)
max_concurrent_requests = 50 # Parallel API requests (1-200, default: 50)
download_timeout_seconds = 300 # Download timeout in seconds (default: 300)
# Storage locations
state_file = "~/.immich-migrator/state.json" # Migration state persistence
temp_dir = "~/.immich-migrator/temp" # Temporary download directory
# Logging
log_level = "INFO" # DEBUG | INFO | WARNING | ERROR (default: INFO)
Using Configuration File
immich-migrator migrate --config /path/to/config.toml
[!NOTE] CLI flags take precedence over config file settings. For example,
--batch-size 30overrides the config file value.
โ Compatibility
- Python: 3.11, 3.12, 3.13
- Operating Systems: Linux, macOS, Windows (WSL recommended)
- Immich: Tested with Immich v1.119 โ v2.x.x servers
๐ง Troubleshooting
๐ Authentication Errors
[!WARNING] If you encounter authentication errors:
- โ Verify your API key is correct and has not expired
- โ Check that the server URL is accessible (include https://)
- โ Ensure you have the necessary permissions on both servers
๐พ Storage Errors
[!NOTE] If you see insufficient storage errors:
- Reduce batch size:
--batch-size 10- Specify a different temp directory:
--temp-dir /path/to/large/disk- Free up disk space before retrying
๐ Network Errors
The tool automatically retries failed downloads with exponential backoff.
[!TIP] If errors persist:
- Check your network connection stability
- Verify both servers are accessible from your location
- Try reducing
max_concurrent_downloadsinconfig.toml- Use
--log-level DEBUGto see detailed error messages
๐ ๏ธ Development
Setup
uv sync
[!CAUTION] Never commit your
.immich.envfile to version control! Add it to.gitignoreto protect your API keys.
Run Tests
uv run pytest
Linting
uv run ruff check .
uv run ruff format .
๐ Changelog
See CHANGELOG.md for release history and breaking changes.
Latest Release
[!NOTE] Version 0.4.7 is the current stable release.
๐ Contributing
Contributions welcome! Please read CONTRIBUTING.md for:
- ๐ Development workflow
- โ Testing requirements
- ๐จ Code style guidelines
- ๐ Security practices
๐ License
GNU Affero General Public License v3.0 โ see LICENSE file for details.
This ensures that any modifications to this tool, especially if hosted as a service, remain open source.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file immich_migrator-0.4.7.tar.gz.
File metadata
- Download URL: immich_migrator-0.4.7.tar.gz
- Upload date:
- Size: 6.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e2d2d05649346da685a0ab45b46d750e5e2c1ad3d8e45592ec71cb4475f4256
|
|
| MD5 |
40be2411337aabf04da925f245952a2b
|
|
| BLAKE2b-256 |
5a95b637dd0f9c40a73007f886b8d3d17fe172af9f839f03e8b691e26e765015
|
File details
Details for the file immich_migrator-0.4.7-py3-none-any.whl.
File metadata
- Download URL: immich_migrator-0.4.7-py3-none-any.whl
- Upload date:
- Size: 58.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
252485379c5a6d16f78f019c926a192b90c0e174de4d2fa53521258d444dbcb3
|
|
| MD5 |
7bf5cbb5cd8f6d4693c45f9cda015f83
|
|
| BLAKE2b-256 |
29a65b20d80059d55650e70370fcd25d78a578ac5ce4be5f8397bebd677f3a27
|