gPhotos2Immich
Docker app from Nackophilz's Repository
Overview
Readme
View on GitHubgPhotos2Immich
Sync photos from Google Photos shared albums to your Immich instance- automatically, on a schedule.
Quick Start
Run with Docker Compose:
# compose.yml services: gphotos2immich: image: ghcr.io/warreth/gphotos2immich:latest container_name: gphotos2immich network_mode: "host" # Fixes DNS resolution and natively exposes port 8080 for the Web UI restart: unless-stopped environment: - PORT=8080 # Port for the Web UI - DISABLE_WEBUI=false # Set to true to fully disable the Web UI # - IMMICH_API_KEY=your-key # Overrides config.json when set (e.g. for key rotation) # - IMMICH_API_URL=http://immich-server:2283/api # Overrides config.json when set volumes: - ./config.json:/app/config.json # Optional, will be created by Web UI if omitted - ./data:/app/data # Persistent dedup cache (survives container restarts)docker compose up -dOpen http://localhost:8080 in your browser to configure your Immich API details and Google Photos shared album links via the Web UI! The app will automatically hot-reload when you save changes.
Docker image tags
The image is published to ghcr.io/warreth/gphotos2immich with these tags:
| Tag | Description |
|---|---|
latest |
Newest stable release. Pre-releases never get this tag. |
beta |
Newest pre-release (e.g. v1.7.0-beta1). Updated on every pre-release. |
vX.Y.Z |
Exact release version, e.g. v1.7.0. |
sha-<hash> |
Build pinned to a specific commit. |
To test a pre-release, use ghcr.io/warreth/gphotos2immich:beta in your compose file. Stable users should stay on latest or a pinned vX.Y.Z tag.
Permissions Note: The container runs as an unprivileged user (
app, UID 1000).
- Default behavior: If you run the container without specifying a
user:, it will automatically fix permissions on mounted files at startup and drop to theappuser.- Explicit user: If you specify
user: "1000:1000"in your compose file, ensure the mountedconfig.jsonanddata/on the host are writable by UID 1000 (chown 1000:1000 config.json data).
[!IMPORTANT] The built-in Web configuration UI is not password-protected. Do NOT expose the port to the public internet or untrusted networks!
Heads Up! If you prefer not to use a Web UI, you can fully disable it by setting
DISABLE_WEBUI=trueand configuring viaconfig.json. See the Configuration Document for details on formatting and settings.
API Key Permissions
To sync photos, generate an Immich API key with the following permissions (or just select "All"):
asset.read · asset.upload · album.create · album.read · album.update · albumAsset.create · user.read
Frequently Asked Questions
Can this sync albums I don't own, or private albums? Only public shared album links work. The tool scrapes shared-album URLs without any Google authentication by design, so an album must be viewable by anyone with the link (test it in an incognito window). Private albums and links that require signing in return 404 and cannot be supported without full Google account authentication, which is out of scope.
Why do I get duplicates in Immich when I already have the same photos? Google Photos serves re-encoded (compressed) copies for shared albums, so their checksums differ from your originals and Immich's content-hash duplicate detection cannot match them. Nothing can be fixed on this tool's side; use Immich's built-in duplicate review after syncing to clean them up.
Features
- No Google API Keys: We scrape directly from shared album URLs, so there's no complex Google Cloud setup required!
- Web UI & Hot Reloading: Manage your albums from a sleek web interface on port 8080. Check live logs, trigger an instant sync with "Sync Now", and tweak settings; everything applies instantly without restarting the container.
- Trigger Sync API: Trigger a sync on demand outside the regular schedule via
POST /api/syncorGET /sync_now(ideal for Home Assistant buttons, webhooks, or automation scripts). See home-assistant.yaml for a ready-to-use Home Assistant configuration. - Smart Syncing: We pull down the full images and videos (no compressed thumbnails), extract the correct "taken" dates, and smoothly avoid Google's rate limits.
- Speed & Deduping: Concurrent workers speed through downloads, while a persistent local cache skips over photos that Immich already has, saving you bandwidth.
Development
# Run directly
go run main.go
# Run with Docker (build from source)
sudo docker compose up --build --remove-orphans
# Run tests (offline; integration tests are skipped)
go test ./...
# Run tests including live integration tests against the real test album
GP2IMMICH_INTEGRATION=1 go test ./... -timeout 15m
Requirements
mkdir -p /mnt/user/appdata/gphotos2immich
echo '{}' > /mnt/user/appdata/gphotos2immich/config.json
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/warreth/gphotos2immich:latestRuntime arguments
- Web UI
http://[IP]:[PORT:8080]/- Network
bridge- Shell
sh- Privileged
- false
Template configuration
WebUI port (must match PORT)
- Target
- 8080
- Default
- 8080
- Value
- 8080
Settings file written by the WebUI (create it first, see Requires)
- Target
- /app/config.json
- Default
- /mnt/user/appdata/gphotos2immich/config.json
- Value
- /mnt/user/appdata/gphotos2immich/config.json
Sync state used to skip items already uploaded
- Target
- /app/data
- Default
- /mnt/user/appdata/gphotos2immich/data
- Value
- /mnt/user/appdata/gphotos2immich/data
Timezone
- Default
- Europe/Paris
- Value
- Europe/Paris
Internal listen port (must match WebUI Port container port)
- Default
- 8080
- Value
- 8080
true turns the WebUI off (config.json must then be written by hand)
- Default
- false
- Value
- false