A self-hostable photo & video gallery with a built-in editing studio — crop, rotate, flip, color/light adjustments, filter presets, and video trimming. Runs entirely on your own machine with no login and no cloud account required.
Fotoğraf ve video galeriniz + düzenleme stüdyosu. Kendi bilgisayarınızda, giriş yapmadan çalışır.
| GalleryWeb | |
|---|---|
| Who | Anyone, on their own PC |
| Login | ❌ None — open the app and go |
| Data | Stays on your disk. No account, no telemetry, no outbound calls by default¹ |
| Setup | Double-click run.sh / run.bat (or docker compose up) |
| Database | None to install — the thumbnail cache uses SQLite (stdlib) |
| Cost | Free forever |
There is one mode: local. No external service is required.
¹ The one exception, and it is opt-in. The map view can draw an OpenStreetMap basemap. That basemap is off by default: the app shows a consent panel explaining that requesting tiles reveals where your photos were taken to
openstreetmap.org(the photos themselves are never uploaded), and the map works without it — markers on a blank canvas. Turn it on and it is remembered per device; you can reset the choice from the footer. Fonts and Leaflet are vendored locally, so nothing else leaves the machine. Verified against the code, 2026-08-07 (frontend/js/gallery.js, theimg-srcallow-list inbackend/main.py).
Note (2026-08-07): earlier versions of this README also advertised a multi-tenant "hosted/cloud mode" (Supabase + PostgreSQL). That layer never shipped — it was an unfinished scaffold, and the setup guide pointed at it. Both have been removed so the documentation matches what the software actually does.
- Editing studio — rotate, flip (H/V), aspect-locked crop, live-preview adjustments (brightness, contrast, saturation, sharpness, temperature, gamma), and one-click filter presets (B&W, sepia, vintage, cool, warm, vivid).
- Video trimming — cut start/end with a two-handle timeline (ffmpeg). Non-destructive: originals are backed up and revertible.
- Fast browsing — thumbnails (SQLite cache), EXIF display, duplicate finder, favorites, tags, albums, ratings, map view (GPS EXIF).
- PWA — installable, works offline², optional phone access on your local network (
GALLERYWEB_LAN=1).
² Measured, not assumed (2026-08-07): with the network fully cut, a reload still renders the full UI from the service-worker cache — 43 KB of DOM, 506 CSS rules,
gallery.jslive, zero console errors. Scope, fromfrontend/sw.js: the app shell (HTML/CSS/JS/fonts/Leaflet) and previously viewed thumbnails are served from cache; live API calls fall back to cache and otherwise return503 offline. So an offline reload gives you the interface and what you already looked at — not a fresh read of your folders.
Grab an installer from Releases — no Python, no terminal, no browser tab:
| Platform | File | Notes |
|---|---|---|
| Windows 10 / 11 | GalleryWeb_x.y.z_x64-setup.exe |
Includes the WebView2 runtime — installs without internet |
| Linux (Debian 12+ / Ubuntu 22.04+) | GalleryWeb_x.y.z_amd64.deb · _amd64.AppImage |
Requires glibc ≥ 2.35 — see the note below |
Linux packages are built in CI, not on a developer's machine — and that is the whole point. A Linux package inherits the glibc of the machine that built it. Up to and including v1.1.0 they were built on Arch (glibc 2.44), which made them undistributable: the published
.debneedsGLIBC_2.39(won't start on Debian 12 / Ubuntu 22.04, andaptinstalls it anyway because the package declared nolibc6lower bound), and the v1.0.0 AppImage bundled Arch's system libraries and opened on no LTS at all. As of v1.1.1, both are built by GitHub Actions on Ubuntu 22.04 (glibc 2.35), the.debdeclareslibc6 (>= 2.35)soaptrefuses rather than installing something broken, and every build is installed and started inside adebian:12container before it may be published. If you're on something older, use Option B below (runs from source, no glibc constraint).
🇹🇷 Linux paketleri artık CI'da derleniyor. Bir Linux paketi, derlendiği makinenin glibc'sini taban alır. v1.1.0 dahil paketler Arch'ta (glibc 2.44) derlendiği için dağıtılamazdı: yayındaki
.debGLIBC_2.39istiyor (Debian 12 / Ubuntu 22.04'te açılmaz, üsteliklibc6alt sınırı beyan edilmediği için apt sessizce kuruyordu), v1.0.0 AppImage'ı ise hiçbir LTS'te açılmıyordu. v1.1.1'den itibaren ikisi de GitHub Actions'ta Ubuntu 22.04 (glibc 2.35) üzerinde üretiliyor,.debartıklibc6 (>= 2.35)beyan ediyor ve her paket yayınlanmadan öncedebian:12kabında kurulup çalıştırılarak sınanıyor. Daha eski bir dağıtımdaysanız aşağıdaki Option B kaynaktan çalışır, bu kısıt yoktur.
Windows: “Windows protected your PC” — the installer is unsigned (a code-signing certificate costs $200–400/year and this is a free, open-source project). Click More info → Run anyway. You can verify what you're running: the package is built in public by GitHub Actions from this repository, not on a developer's machine.
🇹🇷 Windows'ta “Windows bilgisayarınızı korudu” uyarısı normaldir — paket imzasızdır (sertifika yıllık $200-400, bu ücretsiz açık kaynak bir proje). Ek bilgi → Yine de çalıştır deyin. Paket GitHub Actions'ta herkesin görebileceği şekilde derleniyor.
Video trimming additionally needs ffmpeg on your system; everything else works without it.
Download the project, then double-click the launcher for your system:
- Linux / macOS →
run.sh - Windows →
run.bat
It sets everything up on first run (creates an isolated environment, installs
dependencies) and opens the gallery in your browser at http://localhost:5000.
You only need Python 3.10+ installed first
(on Windows, tick "Add Python to PATH" in the installer).
Kolay yol:
run.sh(Linux/macOS) veyarun.bat(Windows) dosyasına çift tıklayın — gerisini kendisi halleder, tarayıcıda galeri açılır.
Güncelleme / Updating: en son sürümü almak için güncelleyiciyi çalıştırın —
Windows: guncelle.bat · Linux/macOS: ./guncelle.sh. GitHub'dan son sürümü
indirir; fotoğraflarınız, ayarlarınız ve sanal ortamınız korunur. Sonraki
run.bat / run.sh çalıştırmasında değişen bağımlılıklar otomatik kurulur —
yani güncelleme için hiçbir şeyi silmenize gerek yok. (git ile klonladıysanız
run zaten açılışta otomatik git pull yapar.)
git clone https://github.com/ihsandeniz/galleryweb.git
cd galleryweb/backend
pip install -r requirements-selfhost.txt # lightweight — no heavy ML deps
python main.py # → http://localhost:5000Then open http://localhost:5000, click Klasör Aç / Open Folder, and pick a photo directory. That's it — no account, no database setup.
Video editing needs
ffmpegon your system (apt install ffmpeg/brew install ffmpeg/pacman -S ffmpeg).
git clone https://github.com/ihsandeniz/galleryweb.git
cd galleryweb
mkdir photos # put your photos/videos here
docker compose up --build # → http://localhost:5000Inside the app, open the /photos folder. ffmpeg is already included in the image.
| Problem | Fix |
|---|---|
| Port 5000 already in use | Start on another port: PORT=5001 python main.py (or set PORT in docker-compose.yml). |
| Video trimming does nothing | ffmpeg isn't installed. apt install ffmpeg / brew install ffmpeg / pacman -S ffmpeg. Photos work without it. |
| HEIC / iPhone photos don't open | The pillow-heif dependency covers this — reinstall with pip install -r backend/requirements-selfhost.txt. |
python: command not found |
Install Python 3.10+. On Windows, tick "Add Python to PATH" during install. |
| Phone can't reach the gallery | Network access is off by default. Start with GALLERYWEB_LAN=1, then use the 📱 Telefon erişimi: URL it prints, and make sure the phone is on the same Wi-Fi. |
| Phone says “connection timed out” | That's a firewall, not a bug — the server is listening correctly but packets are dropped. The app shows the exact command to fix it. Windows (run as Administrator): netsh advfirewall firewall add rule name="GalleryWeb" dir=in action=allow protocol=TCP localport=5000. Linux: see the 🧱 box in the app. |
| Windows: editing a photo does nothing | Check Defender's Controlled folder access (Ransomware protection). It blocks writes to Pictures/Documents for unrecognised apps — usually silently. Either allow GalleryWeb or keep photos in an unprotected folder. |
| Windows: “file is used by another program” | Windows won't move an open file. Stop video playback (or close the other program) and retry — the app deliberately refuses rather than pretending it deleted the file. |
| Want developer auto-reload | GALLERYWEB_DEV=1 python main.py (off by default for faster startup). |
- Backend: FastAPI (Python), Pillow, ffmpeg. A single self-contained app (
backend/main.py) with an SQLite thumbnail cache — no server database. - Frontend: Vanilla JS (no framework), PWA.
- External services: none. The app makes no outbound calls (map tiles are opt-in and off until you enable them).
-
Local mode stores everything on your machine and makes no outbound calls for auth.
-
⚠️ Local mode has no authentication — this is by design (single-user desktop use). Because of that the server now binds to127.0.0.1only: nothing leaves your machine unless you ask for it. Network access is opt-in:GALLERYWEB_LAN=1 python main.py # phone / same-Wi-Fi accessWhen you enable it, anyone on that network can read, tag, and delete your photos via the API — the server prints a warning to remind you. Only do it on a network you trust, and never expose GalleryWeb directly to the internet — it has no authentication layer, so there is no safe public deployment mode.
🇹🇷 Yerel modda giriş/parola yoktur — bu bilinçli bir tasarım (tek kişilik masaüstü kullanımı). Bu yüzden sunucu artık yalnızca
127.0.0.1dinler; hiçbir şey makinenizden dışarı çıkmaz. Ağa açmak isteğe bağlıdır:GALLERYWEB_LAN=1 python main.py. Açtığınızda aynı ağdaki herkes fotoğraflarınızı görebilir, etiketleyebilir ve silebilir — sunucu bunu açılışta uyarı olarak yazar. Yalnızca güvendiğiniz bir ağda açın, yerel modu doğrudan internete açmayın. -
If you put it behind a reverse proxy, set
ALLOWED_ORIGINSto your exact domains (never*— the server rejects*and falls back to localhost). -
Never commit your
.env(it's git-ignored). Copy.env.exampleif you want to change the port or data directory. -
See SECURITY_AUDIT.md.
GNU AGPL-3.0 — see LICENSE.
You are free to use, modify, and self-host GalleryWeb. If you run a modified version as a network service, the AGPL requires you to make your source code available to its users. This keeps the project open for everyone who builds on it.
Issues and pull requests welcome. Please keep the frontend framework-free (Vanilla JS) to match the existing codebase.