Auto import from SD card to Immich
Here's a quick write up on how to import pictures and videos from SD card reader to Immich using systemd on Linux
I recently bought a Fuji mirrorless camera, and want to make it as smooth as possible to upload photos to Immich. After I have imported, I delete the images I do not want.
Labeling the SD card and automount
Fuji does not set a UUID or a label on the SD card when you format it. This is a bit annoying, since it makes is harder to automate the process that all cards formatted with a Fuji camera should automatically mount to /mnt/fuji. The workaround I went for is to create a label on the SD card manually after each format.
First find the path to your memory card with fdisk -l
. Mine was /dev/sdg1
Then I put a label (DCIM) on it with:
sudo exfatlabel /dev/sdg1 DCIM
We can now edit the file /etc/fstab
Add the line:
/dev/disk/by-label/DCIM /mnt/fuji exfat noexec,nodev,nosuid,nofail 0 0
We also need to add a udev rule, to have it automount.
Edit the file /etc/udev/rules.d/99-dcim-mount.rules
With the content:
# Mount when the card appears
ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="DCIM", TAG+="systemd", \
ENV{SYSTEMD_WANTS}+="mnt-fuji.mount"
# (Optional) cleanly unmount when it’s pulled
ACTION=="remove", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="DCIM", RUN+="/usr/bin/umount /mnt/fuji"
Create the dir, reload systemd, and test mount:
mkdir /mnt/fuji
udevadm control --reload
systemctl daemon-reload
mount -a
Creating systemd file to start bash script
Create the systemd service file for running the script:
/etc/systemd/system/auto-upload-immich.service
With the content:
[Unit]
Description=Archive .raf and import jpeg to Immich
BindsTo=dev-disk-by\x2dlabel-DCIM.device # die when the device goes away
After=dev-disk-by\x2dlabel-DCIM.device
RequiresMountsFor=/mnt/fuji # systemd mounts it for us
ConditionPathIsMountPoint=/mnt/fuji
[Service]
Type=oneshot
Environment="IMMICH_API_KEY=<yourAPIkey"
Environment="IMMICH_INSTANCE_URL=https://<yourdomain.immich.domain>"
Environment="MOUNT_DIR=/mnt/fuji/DCIM/100_FUJI/"
Environment="RAW_DIR=/mnt/appdata/rawfiles/"
Environment="WEBHOOK_ENDPOINT=<endpoint if you want to ping a webhook>"
Environment="SD_CARD_MOUNT=/mnt/fuji"
Environment="HA_URL=https://homeassistant.yourdomain.com/api/webhook/-webhookID"
ExecStart=/usr/local/bin/auto-upload-immich.sh --when=inserted --mount-point=/mnt/fuji
[Install]
WantedBy=dev-disk-by\x2dlabel-DCIM.device
Please make sure to edit the environment variables for your environment. Take note that I have set the variable MOUNT_DIR to DCIM/100_FUJI, so Immich doesn't need to scan the whole SD card for the media files.
The environment variable $RAW_DIR
is for moving the .raf
files to a separate directory before running the Immich import. This way I can store my .raf files independently, if I have a banger of a photo that the jpeg did not end up looking nice.
The env $WEBHOOK_ENDPOINT
is for sending a POST to a webhook. I have another service that checks my geolocation from Home Assistant, and ads that data to the images on Immich. This way, I get geolocation on the photos without draining my battery with BLE connecting to the camera when I shoot.
The env HA_URL
is for sending a http PUT request to a Home Assistant automation. (I have a automation that says on my speakers in the kitchen that the import is finished, so I remember to put the SD card back in the camera).
The bash script
So finally it is the script. Create and edit the file:
/usr/local/bin/auto-upload-immich.sh
With the content:
#!/bin/bash
# set immich_cli variable
IMMICH_CLI="docker run --rm --pull=always \
-v $MOUNT_DIR:/import:ro \
-e IMMICH_INSTANCE_URL=$IMMICH_INSTANCE_URL \
-e IMMICH_API_KEY=$IMMICH_API_KEY \
ghcr.io/immich-app/immich-cli:latest upload -r /import"
echo "script started"
echo "Moving raw files"
shopt -s nullglob
for file in "$MOUNT_DIR"*.RAF; do
# the -- protects against filenames starting with “-”
mv -- "$file" "$RAW_DIR"/
done
echo "Starting Immich import"
$IMMICH_CLI
#echo "unmounting sd card"
#umount $SD_CARD_MOUNT
echo "Sending curl"
curl --silent --show-error --fail -X POST $WEBHOOK_ENDPOINT
curl --silent --show-error --fail -X PUT $HA_URL
echo "Done, exiting"
- You need docker (or podman) to run this.
- We also pull=always, so we do not end up with a stale immich cli image.
- We do not delete the files from the SD card, and mount it as read only inside the container.
fin
Finally we need to reaload systemd.
systemctl daemon-reload
systemctl enable /etc/systemd/system/auto-upload-immich.service
You can check your services with:
journalctl -u /etc/systemd/system/auto-upload-immich.service -f