# Immich Drop

**What it is:** Tiny zero-login web app for collecting photos and videos from anyone into your Immich server. Admin users create invite links (public-by-URL, optionally password-protected); anyone with the link can upload without an Immich account. Supports albums, duplicate prevention, chunked uploads for large files, and WebSocket progress updates.

**GitHub:** https://github.com/Nasogaa/immich-drop  
**Docker image:** `ghcr.io/nasogaa/immich-drop:latest`

---

## Compatible Combos

| Infra | Runtime | Notes |
|-------|---------|-------|
| Any Linux VPS/VM | Docker Compose | Single container |
| Raspberry Pi / ARM | Docker | Multi-arch image |

---

## Prerequisites

- A running **Immich** server with an API key

---

## Inputs to Collect

### Phase: Deploy (required)

| Variable | Description |
|----------|-------------|
| `IMMICH_BASE_URL` | Immich API URL — must include `/api` (e.g. `https://immich.example.com/api`) |
| `IMMICH_API_KEY` | Immich admin API key |
| `SESSION_SECRET` | Random secret for session signing |
| `PUBLIC_BASE_URL` | Public URL of this Immich Drop instance (e.g. `https://drop.example.com`) |

### Phase: Optional

| Variable | Description | Default |
|----------|-------------|---------|
| `IMMICH_ALBUM_NAME` | Default album name for uploads | `dead-drop` |
| `PUBLIC_UPLOAD_PAGE_ENABLED` | Enable a public upload page (no invite link needed) | `false` |
| `CHUNKED_UPLOADS_ENABLED` | Enable chunked uploads for large files | `false` |
| `CHUNK_SIZE_MB` | Per-chunk size for chunked uploads | `95` |

---

## Software-Layer Concerns

- **State DB** (`state.db`) — local SHA-1 dedup cache; stored in `/data` volume; persist to avoid re-uploading duplicates
- **Invite links** — generated by admin, public-by-URL; no recipient account needed
- **Invite features:** one-time or multi-use, optional password, optional expiry, optional target album (auto-created if missing)
- **Chunked uploads** — bypasses 100 MB reverse proxy limits; the frontend auto-switches to chunked mode for files larger than `CHUNK_SIZE_MB`
- **Duplicate prevention** — SHA-1 cache locally + optional Immich bulk-check API
- **Privacy-first** — never lists existing Immich media to uploaders; session-local upload tracking only

---

## Example Docker Compose

```yaml
services:
  immich-drop:
    image: ghcr.io/nasogaa/immich-drop:latest
    pull_policy: always
    container_name: immich-drop
    restart: unless-stopped
    environment:
      IMMICH_BASE_URL: https://immich.example.com/api
      IMMICH_API_KEY: your_immich_api_key
      SESSION_SECRET: your_random_secret
      PUBLIC_BASE_URL: https://drop.example.com
      IMMICH_ALBUM_NAME: uploads
      PUBLIC_UPLOAD_PAGE_ENABLED: "false"
      CHUNKED_UPLOADS_ENABLED: "false"
      CHUNK_SIZE_MB: "95"
    ports:
      - "8080:8080"
    volumes:
      - immich_drop_data:/data

volumes:
  immich_drop_data:
```

---

## Upgrade Procedure

1. Pull new image: `docker compose pull` (uses `pull_policy: always` by default)
2. Restart: `docker compose up -d`
3. Dedup cache in `/data` volume persists

---

## Gotchas

- **`IMMICH_BASE_URL` must end with `/api`** — the app calls Immich API endpoints directly; missing this causes all API calls to fail
- **`PUBLIC_UPLOAD_PAGE_ENABLED: false` by default** — enabling it lets anyone upload without a link; only enable if intentional
- **Chunked uploads off by default** — enable if users need to upload files >100 MB through a reverse proxy with size limits
- WebSocket progress requires your reverse proxy to pass WebSocket upgrades (Nginx: `proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade;`)
- Invite links give upload-only access — uploaders cannot browse or download existing Immich content

---

## Links

- GitHub: https://github.com/Nasogaa/immich-drop
- Docker image: https://github.com/Nasogaa/immich-drop/pkgs/container/immich-drop
