updates to compose file .env file final one_time_linke release
This commit is contained in:
188
README.md
188
README.md
@@ -1,20 +1,24 @@
|
||||
# Immich Drop Uploader
|
||||
|
||||
A tiny, zero-login web app for collecting photos/videos into your **Immich** server.
|
||||
A tiny web app for collecting photos/videos into your **Immich** server.
|
||||
Admin users log in to create public invite links; invite links are always public-by-URL. A public uploader page is optional and disabled by default.
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- **No accounts** — open the page, drop files, done
|
||||
- **Invite links (public)** — create upload links you can share with anyone
|
||||
- **One‑time link claim** — first browser session claims a one‑time link; it can upload multiple files, others are blocked
|
||||
- **Optional public uploader** — disabled by default; can be enabled via `.env`
|
||||
- **Queue with progress** via WebSocket (success / duplicate / error)
|
||||
- **Duplicate prevention** (local SHA‑1 cache + optional Immich bulk‑check)
|
||||
- **Original dates preserved** (EXIF → `fileCreatedAt` / `fileModifiedAt`)
|
||||
- **Mobile‑friendly**
|
||||
- **Mobile‑friendly**
|
||||
- **.env‑only config** (clean deploys) + Docker/Compose
|
||||
- **Privacy‑first**: never lists server media; UI only shows the current session
|
||||
- **Dark mode support** — automatically detects system preference, with manual toggle
|
||||
- **Album integration** — auto-adds uploads to a configured album (creates if needed)
|
||||
- **Privacy‑first**: never lists server media; UI only shows the current session
|
||||
- **Dark mode** — detects system preference; manual toggle persists across pages
|
||||
- **Albums** — add uploads to a configured album (creates if needed)
|
||||
- **Copy + QR** — copy invite link and display QR for easy sharing
|
||||
|
||||
---
|
||||
|
||||
@@ -34,10 +38,10 @@ A tiny, zero-login web app for collecting photos/videos into your **Immich** ser
|
||||
|
||||
---
|
||||
## Quick start
|
||||
Copy the docker-compose.yml and the .env file to a common folder,
|
||||
update the .env file before executing the CLI commands to quick start the container.
|
||||
You can run without a `.env` file by putting all settings in `docker-compose.yml` (recommended for deploys).
|
||||
Use a `.env` file only for local development.
|
||||
|
||||
### docker-compose.yml
|
||||
### docker-compose.yml (deploy without .env)
|
||||
```yaml
|
||||
version: "3.9"
|
||||
|
||||
@@ -48,15 +52,25 @@ services:
|
||||
container_name: immich-drop
|
||||
restart: unless-stopped
|
||||
|
||||
# Optional: Set album name for auto-adding uploads
|
||||
# Configure all settings here (no .env required)
|
||||
environment:
|
||||
IMMICH_ALBUM_NAME: dead-drop # Optional: uploads will be added to this album
|
||||
# Server (container port is 8080 by default)
|
||||
HOST: 0.0.0.0
|
||||
PORT: 8080
|
||||
|
||||
# Load all variables from your repo's .env (PORT, IMMICH_BASE_URL, IMMICH_API_KEY, etc.)
|
||||
env_file:
|
||||
- ./.env
|
||||
# Immich connection (must include /api)
|
||||
IMMICH_BASE_URL: https://immich.example.com/api
|
||||
IMMICH_API_KEY: ${IMMICH_API_KEY}
|
||||
|
||||
# Expose the app on the same port as configured in .env (defaults to 8080)
|
||||
# Optional behavior
|
||||
IMMICH_ALBUM_NAME: dead-drop
|
||||
PUBLIC_UPLOAD_PAGE_ENABLED: "false" # keep disabled by default
|
||||
PUBLIC_BASE_URL: https://drop.example.com
|
||||
|
||||
# App internals
|
||||
SESSION_SECRET: ${SESSION_SECRET}
|
||||
|
||||
# Expose the app on the host
|
||||
ports:
|
||||
- 8080:8080
|
||||
|
||||
@@ -76,18 +90,7 @@ volumes:
|
||||
immich_drop_data:
|
||||
```
|
||||
|
||||
### .env
|
||||
|
||||
```
|
||||
HOST=0.0.0.0
|
||||
PORT=8080
|
||||
IMMICH_BASE_URL=http://REPLACE_ME:2283/api
|
||||
IMMICH_API_KEY=REPLACE_ME
|
||||
MAX_CONCURRENT=3
|
||||
IMMICH_ALBUM_NAME=dead-drop # Optional: auto-add uploads to this album
|
||||
STATE_DB=/data/state.db
|
||||
```
|
||||
|
||||
### CLI
|
||||
```bash
|
||||
docker compose pull
|
||||
@@ -97,6 +100,17 @@ docker compose up -d
|
||||
|
||||
## New Features
|
||||
|
||||
### 🔐 Login + Menu
|
||||
- Login with your Immich credentials to access the menu.
|
||||
- The menu lets you list/create albums and create invite links.
|
||||
- The menu is always behind login; logout clears the session.
|
||||
|
||||
### 🔗 Invite Links
|
||||
- Links are always public by URL (no login required to use).
|
||||
- You can make links one‑time (claimed by the first browser session) or indefinite / limited uses.
|
||||
- Set link expiry (e.g., 1, 2, 7 days). Expired links are inactive.
|
||||
- Copy link and view a QR code for easy sharing.
|
||||
|
||||
### 🌙 Dark Mode
|
||||
- Automatically detects system dark/light preference on first visit
|
||||
- Manual toggle button in the header (sun/moon icon)
|
||||
@@ -133,19 +147,25 @@ docker compose up -d
|
||||
|
||||
```
|
||||
immich_drop/
|
||||
├─ app/ # FastAPI application (Python package)
|
||||
│ ├─ __init__.py
|
||||
│ ├─ app.py # uvicorn app:app
|
||||
│ └─ config.py # loads .env from repo root
|
||||
├─ frontend/ # static UI served at /static
|
||||
│ ├─ index.html
|
||||
│ └─ app.js
|
||||
├─ main.py # thin entrypoint (python main.py)
|
||||
├─ requirements.txt # Python deps
|
||||
├─ .env # single config file (see below)
|
||||
├─ app/ # FastAPI application (Python package)
|
||||
│ ├─ app.py # ASGI app (uvicorn entry: app.app:app)
|
||||
│ └─ config.py # Settings loader (reads .env/env)
|
||||
├─ frontend/ # Static UI (served at /static)
|
||||
│ ├─ index.html # Public uploader (optional)
|
||||
│ ├─ login.html # Login page (admin)
|
||||
│ ├─ menu.html # Admin menu (create invites)
|
||||
│ ├─ invite.html # Public invite upload page
|
||||
│ ├─ app.js # Uploader logic (drop/queue/upload/ws)
|
||||
│ ├─ header.js # Shared header (theme + ping + banner)
|
||||
│ └─ favicon.png # Tab icon (optional)
|
||||
├─ data/ # Local dev data dir (bind to /data in Docker)
|
||||
├─ main.py # Thin dev entrypoint (python main.py)
|
||||
├─ requirements.txt # Python dependencies
|
||||
├─ Dockerfile
|
||||
├─ docker-compose.yml
|
||||
└─ README.md
|
||||
├─ .env.example # Example dev environment (optional)
|
||||
├─ README.md
|
||||
└─ screenshot.png # UI screenshot for README
|
||||
```
|
||||
|
||||
---
|
||||
@@ -156,25 +176,49 @@ immich_drop/
|
||||
- An **Immich** server + **API key**
|
||||
|
||||
---
|
||||
## Configuration (.env)
|
||||
# Local dev quickstart
|
||||
|
||||
## Development
|
||||
|
||||
Run with live reload:
|
||||
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
|
||||
The backend contains docstrings so you can generate docs later if desired.
|
||||
|
||||
---
|
||||
|
||||
## Dev Configuration (.env)
|
||||
|
||||
```ini
|
||||
# Server
|
||||
HOST=0.0.0.0
|
||||
# Server (dev only)
|
||||
HOST=0.0.0.0
|
||||
PORT=8080
|
||||
|
||||
# Immich connection (include /api)
|
||||
IMMICH_BASE_URL=http://REPLACE_ME:2283/api
|
||||
IMMICH_API_KEY=ADD-YOUR-API-KEY #key needs asset.upload (default functions)
|
||||
|
||||
IMMICH_API_KEY=ADD-YOUR-API-KEY # needs: asset.upload; for albums also: album.create, album.read, albumAsset.create
|
||||
MAX_CONCURRENT=3
|
||||
|
||||
# Optional: Album name for auto-adding uploads (creates if doesn't exist)
|
||||
IMMICH_ALBUM_NAME=dead-drop #key needs album.create,album.read,albumAsset.create (extended functions)
|
||||
# Public uploader page (optional) — disabled by default
|
||||
PUBLIC_UPLOAD_PAGE_ENABLED=TRUE
|
||||
|
||||
# Album (optional): auto-add uploads from public uploader to this album (creates if needed)
|
||||
IMMICH_ALBUM_NAME=dead-drop
|
||||
|
||||
# Local dedupe cache (SQLite)
|
||||
STATE_DB=./data/state.db
|
||||
|
||||
# Base URL for generating absolute invite links (recommended for production)
|
||||
# e.g., PUBLIC_BASE_URL=https://photos.example.com
|
||||
#PUBLIC_BASE_URL=
|
||||
|
||||
# Session and security
|
||||
SESSION_SECRET=SET-A-STRONG-RANDOM-VALUE
|
||||
LOG_LEVEL=DEBUG
|
||||
|
||||
# Local dedupe cache
|
||||
STATE_DB=./data/state.db # local dev -> ./state.db (data folder is created in docker image)
|
||||
# In Docker this is overridden to /data/state.db by docker-compose.yml
|
||||
```
|
||||
|
||||
|
||||
@@ -197,52 +241,20 @@ You can keep a checked‑in `/.env.example` with the keys above for onboarding.
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Mobile notes
|
||||
|
||||
- Uses a **label‑wrapped input** + short **ghost‑click suppression** so the system picker does **not** re‑open after tapping **Done** (fixes iOS/Android quirks).
|
||||
- Drag‑and‑drop is desktop‑oriented; on touch, use **Choose files**.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Uploads don't start on phones / picker re‑opens**
|
||||
– Hard‑refresh; current UI suppresses ghost clicks and resets the input.
|
||||
– If using a PWA/WebView, test in Safari/Chrome directly to rule out container quirks.
|
||||
|
||||
**WebSocket connects/disconnects in a loop**
|
||||
– Match schemes: `ws://` for `http://`, `wss://` for `https://`.
|
||||
– If behind a reverse proxy, ensure it forwards WebSockets.
|
||||
|
||||
**413 Request Entity Too Large**
|
||||
– If running behind nginx/Traefik/etc., bump body size limits (`client_max_body_size` for nginx).
|
||||
|
||||
**/assets returns 401**
|
||||
– Check `IMMICH_API_KEY` and ensure the base URL includes `/api` (e.g., `http://<host>:2283/api`).
|
||||
|
||||
**Duplicate detected but you expect an upload**
|
||||
– The proxy caches SHA‑1 in `state.db`. For a fresh run, delete that DB or point `STATE_DB` to a new file.
|
||||
|
||||
---
|
||||
|
||||
## Security notes
|
||||
|
||||
- The app is **unauthenticated** by design. Share the URL only with trusted people or keep it on a private network/VPN.
|
||||
- The menu and invite creation are behind login. Logout clears the session.
|
||||
- Invite links are public by URL; share only with intended recipients.
|
||||
- The default uploader page at `/` is disabled unless `PUBLIC_UPLOAD_PAGE_ENABLED=true`.
|
||||
- The Immich API key remains **server‑side**; the browser never sees it.
|
||||
- No browsing of uploaded media; only ephemeral session state is shown.
|
||||
- No browsing of uploaded media; only ephemeral session state is shown.
|
||||
- Run behind HTTPS with a reverse proxy and restrict CORS to your domain(s).
|
||||
|
||||
---
|
||||
## Usage flow
|
||||
|
||||
## Development
|
||||
|
||||
Run with live reload:
|
||||
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
|
||||
The backend contains docstrings so you can generate docs later if desired.
|
||||
- Admin: Login → Menu → Create invite link (optionally one‑time / expiry / album) → Share link or QR.
|
||||
- Guest: Open invite link → Drop files → Upload progress and results shown.
|
||||
- Optional: Enable public uploader and set `IMMICH_ALBUM_NAME` for a default landing page.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user