Immich Digital Photo Frame
There are a few blog posts out there about this sort of thing, but I figured I'd add mine to the pile. I already had a Raspberry Pi 4 with 2gb ram running a couple self-hosted things, but it was mostly sitting idle, so I decided to put together an Immich frame for my mom for Christmas.
I chose ImmichFrame for this project from the very start. Learning about this project was the inspiration for the gift in the first place.
Immich Kiosk looks like it does something similar, but I haven't played with it just yet. One of these days.
The server
So, of course for this, I'll need an Immich server. I already had one of those running, and writing about that's a little outside of the scope of this post. However, I also needed an Immich Frame server.
This wasn't too bad. I made a copy of their docker-compose.yml. I changed the port, added my server url, set my timezone, added api keys for my immich server and openweathermap and tweaked the appearance a little bit.
name: immichframe
services:
immichframe:
container_name: immichframe
image: ghcr.io/immichframe/immichframe:latest
restart: on-failure
ports:
- "8080:8080"
environment:
TZ: "Europe/Berlin"
# Required
ImmichServerUrl: "URL"
ApiKey: "KEY"
# Image
ImageZoom: "true"
Interval: "10"
TransitionDuration: "2"
# Filters
Albums: "ALBUM1,ALBUM2"
ExcludedAlbums: "ALBUM3,ALBUM4"
People: "PERSON1,PERSON2"
ShowMemories: "false"
ImagesFromDays: ""
ImagesFromDate: ""
ImagesUntilDate: ""
# Clock
ShowClock: "true"
ClockFormat: "HH:mm"
# Weather
WeatherApiKey: "API-KEY"
UnitSystem: "imperial"
Language: "en"
ShowWeatherDescription: "true"
WeatherLatLong: "40.730610, -73.935242"
# Metadata
ShowImageDesc: "true"
ShowImageLocation: "true"
ShowPhotoDate: "true"
PhotoDateFormat: "yyyy-MM-dd"
# Caching
RenewImagesDuration: "30"
DownloadImages: "false"
RefreshAlbumPeopleInterval: "12"
# UI
PrimaryColor: "#FF5733"
BaseFontSize: "17px"
# Misc
ImmichFrameAlbumName: ""From there, I was able to open: http://pi-ip:port and view a slideshow in my browser without issues.
The client
Of course, I didn't want to view it on my computer, I wanted a dedicated screen. So, I ordered a little 7" display off Amazon, scrambled to get a mini-hdmi to hdmi adapter from Walmart when I realized it didn't come with one, and talked my brother into making a simple wooden frame around it.
I plugged it all in, and got a nice framed picture of the tty1 login screen. Nice for the Linux nerd in your life I suppose, but in need of a bit more work otherwise.
I was already running Ubuntu Server, and didn't want to reinstall my operating system with something else (maybe DietPi?) So, we were going to need to get a gui running on Ubuntu Server.
sudo apt install xinit xdotool
I think that did the trick. I installed openbox, but decided I didn't need it.
Anyway, I tried running the .deb file and the AppImage that were available on the ImmichFrame releases page, but kept running into crashes. No criticism of the ImmichFrame dev, I'm sure it was user error, but I eventually opted for the web version.
sudo apt install chromium-browserNo matter, one browser install later, and we're off. Now... we just have to figure out how to open it at startup.
First things first, we're going to need to get auto logged in. Now, my user has sudo privileges and ssh keys and the like, so, automatically logging that account in would be a pretty bad idea.
sudo adduser kiosk
sudo usermod -aG users kiosk
sudo usermod -aG kiosk kiosk
sudo usermod -aG video kiosk
sudo usermod -aG audio kioskOk, user created, let's log them in at startup. A quick internet search says that's handled by something called getty.
sudo mkdir -p /etc/systemd/system/getty@tty1.service.d/autologin.conf
sudoedit /etc/systemd/system/getty@tty1.service.d/autologin.conf[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin kiosk --noclear %I 38400 linux
autologin.conf
sudo systemctl enable getty@tty1.service
sudo rebootThat gets me signed in at startup. Now we need to start an x server. Dropping this into kiosk's ~/.bashrc did the trick.
[ "$(tty)" = "/dev/tty1" ] && startx -- -nocursor/home/kiosk/.bashrc
Now, instead of a console, we have a black screen. Let's fix that with an .xinitrc (again, in kiosk's home directory).
Here I just made a couple tweaks to ncornette's gist:
#!/bin/sh
# invoke global X session script
#. /etc/X11/Xsession
# HOW-TO :
# 1. Disable any Display Manager (lightdm/gdm/gdm3) from executing on startup
# 2. Allow user to start X :
# a. Edit /etc/X11/Xwrapper.config
# b. Set value : "allowed_users=anybody"
# 3. insert "su kiosk -c xinit &" into /etc/rc.local
#
#Disable dpms to prevent screen from blanking
xset -dpms; xset s noblank; xset s off
#Configure displays (man xrandr for more options)
xrandr --output DP1 --prefered
xrandr --output HDMI1 --prefered
#Start matchbox wm (man matchbox-window-manager for more options)
#exec matchbox-window-manager -use_titlebar no -use_cursor no &
xdotool mousemove 0 0
#Open browser
chromium-browser --start-fullscreen --kiosk --window-size=800x480 immich-frame-ip:port
# Launch xterm after browser has been closed
# xtermI set my screen resolution, and the url I wanted chromium to open. I noticed that the default cursor position on the center of the screen triggered a distracting hover menu, so I used xdotool to move it out of the way.
I think that's everything. Of course, I tried to skip some of the various dead-ends and pitfalls I found myself running into as I tried putting this together. If it turns out I left out something important or you run into pitfalls yourself trying to follow my steps, feel free to leave a comment!