A self-hosted photo frame

A photo frame that answers only to you.

Unlock a PF1007L Wi-Fi photo frame, replace its vendor software with a locked-down kiosk, and run the whole thing from a small PHP and SQLite server you own. No cloud account. No subscription. No framework.

Get started View on GitLab

  • MIT
  • PHP 8.5
  • SQLite
  • No cloud
  • Self-hosted

Why this exists

Most photo frames phone home to a company that may not exist in three years.

Your pictures pass through their servers, the app on your phone is theirs, and when they lose interest, so does your frame. This project takes the same hardware and gives it to you.

No cloud

The frame talks to one server: yours. Phones and frames only ever talk to your server, and your server only talks to the sources you list.

No subscription

Nothing to renew. The code is MIT licensed, and the server is PHP and SQLite on a host you already know how to run.

No one else holds your photos

Photos come from your own album or photo library. Cards from relatives are readable on the frame, not in the admin. That includes you.

What you get

A frame the family forgets about, in the best way.

The person with it on the wall never opens a settings screen. Photos change, the weather is right, and a card from a grandchild shows up.

A dashboard that fills the screen

Clock, weather, calendar, photos and more, laid out for a 10.1-inch panel. No status bar, no navigation bar, no on-screen exit.

Cards from the family

A relative opens a private link on a phone, picks a cover, writes a message and signs it with a finger. It arrives on the frame as a postage stamp over the photos. Nobody needs an account.

Photos that survive a bad day

The day's photos are stored on the frame, so they keep showing when the network or the photo host is down.

Bedtime and wake

A schedule per frame turns the backlight fully off, not just dim, and back on in the morning.

A desktop admin

Claim a frame with a six-digit pairing code, choose what it shows widget by widget, and see what it is showing right now. Two-step sign-in is optional.

Updates that undo themselves

Self-update with a staged rollout. If a new build is not healthy after about 15 minutes, the frame reinstalls the last one that was.

See every widget

How it works

Three acts, done once per frame.

Acts one and two are independent, so start with whichever you like. Act three needs both.

  1. Act one

    Unlock

    Build a patched U-Boot, boot the frame from a microSD card into USB recovery mode, back up the whole storage and verify the backup, then change one line to turn ADB on. One 512-byte sector changes. You never open the case and you never solder.

    Unlock guide
  2. Act two

    Serve

    Put the PHP app on an Apache server, create the SQLite database, create your admin login, and add one cron job. Two-step sign-in is optional.

    Server guide
  3. Act three

    Provision

    Build the kiosk app in a container, install it, set it as device owner, install the boot script, and claim the frame in the admin with the six-digit code it shows on screen.

    Provisioning guide

Yours, not ours

Your server. Your data. Your call.

Photos, cards and settings live in a SQLite database and a photo folder on a server you run. There is no project server, no account to create and no analytics. A frame reports its status to your server, and it loads only the photo and Home Assistant addresses you give it. The kiosk refuses plain HTTP.

Every frame has its own API key, secrets never reach page JavaScript, and ADB on the frame can be limited to your own network.

How the system defends itself

Who it is for

If you are comfortable in a terminal, maybe you.

The curious

You want a photo frame that belongs to you and are willing to learn how it works.

Check the hardware

Builders

You run shell and PowerShell commands, host a PHP site on Apache, and can spend an afternoon on the unlock.

Start here

Family

Someone set a frame up for you. This is the page to print and keep beside it.

The family guide

Developers

PHP 8.5, SQLite, no framework, no Node. Widgets are modules you can add or remove.

Developer docs

Know before you start. Weather is US-only (National Weather Service). This is for one frame model, the PF1007L, and the unlock was verified on one firmware build. The unlock scripts expect Windows with WSL2; the server runs on any Linux host.

Ready

Plan on an afternoon for the unlock.

Most of it is waiting for the backup to be written and checked, about 90 minutes.

Get started What you need

You need: a PF1007L photo frame (where we bought ours), Windows 10 or 11 with WSL2 for the unlock, and a Linux server with Apache 2.4, PHP 8.5 and a valid HTTPS certificate.

Released under the MIT License. The uboot/ directory is GPL-2.0-or-later. Read the license.