Repository navigation
LocalDrop 1.1.0
LocalDrop 1.1.0
[1.1.0] — 2026-10-01
LocalDrop is now installable on every platform. 1.0.0 shipped a Docker-only
install that worked, but left a Linux server, a Mac, and a Windows desktop with
three different un-documented workarounds. This release closes that gap and makes
the repository releaseable as open source.
Added — installation
- One-line Linux/macOS installer.
curl -fsSL …/install.sh | shdownloads a
checksummed binary, verifies its SHA-256, creates a lockedlocaldropsystem
account, installs a systemd unit (Linux) or a launchd job (macOS), generates a
secret key, and starts the service.--no-serviceinstalls the binary alone;
your data and config are never overwritten. - Windows installer. A proper Inno Setup package (Start Menu and desktop
shortcuts, optional start-at-login, uninstaller) plus a portable zip of the
same payload. Both are checksummed. install.ps1for Windows: fetches, verifies, installs, and runs
localdrop --checkto prove the install works before it reports success.- Homebrew formula for macOS (
brew install abhi-subedi/localdrop) —
per-user, nosudo, no service auto-install. uninstall.shthat keeps your data by default and only deletes it when
you pass--purgeand confirm.- Self-contained installs need no database at all. When
LOCALDROP_DATABASE_URLis unset, the launcher provisions an embedded
PostgreSQL inside the data directory, so a native install is a single binary
with nothing else to install. Point it at your own PostgreSQL and the
embedded cluster is never started. - Frozen binaries for every platform —
linux-x64,linux-arm64,
macos-x64,macos-arm64,windows-x64— with a publishedSHA256SUMS. - Published container image on
ghcr.io/abhi-subedi/localdropfor
linux/amd64andlinux/arm64, tagged:1.1.0,:1.1,:stable,
:latest, with OCI labels and provenance attestation.
Added — operating the server
localdrop --checkverifies an install is self-sufficient and exits: every
bundled resource, the heavy C extensions (psycopg, argon2, Pillow) and the app
factory. It needs no database, so it works when the thing that is broken is
the database. The release pipeline runs it against every artefact before
publishing.localdrop --setup-tokenprints the one-time onboarding token on demand,
so a headless install does not have to dig it out ofjournalctl.localdrop install-service/uninstall-service/service-statusfor a
per-user macOS LaunchAgent — the launchd job Homebrew users need, since
Homebrew will not install one for them.localdrop-migrateapplies migrations programmatically, so the packaged
Alembic environment is found regardless of working directory. Docker, systemd,
the launcher and the frozen binary all use the same path.localdrop.envis read from the data directory when present, so every
platform is configured the same way. Real environment variables still win.GET /api/v1/versionreports the running build (public, and free of any
deployment detail). The Settings "About" panel reads it instead of showing a
hard-coded string./api/v1/health/readyreports the failing subsystem by name, and
LOCALDROP_DB_CONNECT_TIMEOUT/LOCALDROP_DB_KEEPALIVE_SECONDSbound how
long it can take to find out.
Added — working on the project
- Continuous integration (
.github/workflows/ci.yml): lint, types, the
test suite against real PostgreSQL 16, a frontend type-check and build, a
frozen-binary build that self-checks, and a Docker build that must serve
/api/v1/version. - Automated releases (
release.yml): tag a version and get binaries for
five platforms, a multi-arch image, checksums, a Release whose notes come
from this file, an updatedVERSIONfile, and a pushed Homebrew formula. - Nightly checks (
nightly.yml):pip-audit,npm audit, a Trivy scan of
the published image, CodeQL, and an end-to-end pass against the real
stableimage that fails if it is not the versionVERSIONclaims. - Dependabot, grouped by ecosystem so review is a handful of PRs, not
dozens. scripts/check_version.py,scripts/check_config_docs.pyand
scripts/check_fr_traceability.py— the doc-drift gates the spec asked
for and never had. Requirement-to-test traceability is now enforced, with the
remaining gaps registered and visible instead of assumed.SECURITY.md,SUPPORT.md, bug and feature issue templates, a PR
template,CODEOWNERS,.editorconfigand.gitattributes.
Fixed
- Readiness took 130 seconds to report a dead database. The engine had no
connect_timeout, so libpq waited its default ~2 minutes — longer than the
Docker healthcheck's 5-second timeout. Now ~5 seconds, with a regression test
that fails if the bound is removed. - Pool hygiene:
pool_recycleandpool_timeoutare set, and TCP keepalives
close half-open connections instead of letting them pin a pool slot. - Production builds shipped without any CSS.
index.csswas never imported
by the app entry, so the built SPA rendered unstyled. - A pip install could not run. The migrations and the built web UI lived
outside the package, so only the Docker layout — which copied them back in by
hand — worked. Both now ship inside the wheel, andpip install localdrop
and the frozen binary resolve them identically. docker compose pullcould not work. The compose file referenced a
locally built tag that was never published. It now pulls from GHCR, so the
documented upgrade path is real.
Changed
- One version, one source of truth.
__version__in
__about__.pyfeeds the wheel, the binary, the HTTP API, the Settings panel
and the release tooling. The three-way drift between1.0.0,1.1.0and
"unreleased" is no longer possible; CI fails if it comes back. - The repository's own quality gates now pass.
ruffandmypywere
reporting 230 and 37 problems respectively before this release. Both are clean. docs/CONFIGURATION.mdis complete — it was missing 15 settings.
Security
- Release artefacts are SHA-256 verified by every installer before anything is
unpacked, and releases carry a provenance attestation. - The systemd unit runs as a dedicated account with
NoNewPrivileges,
ProtectSystem=strictandReadWritePathslimited to the data directory. - Windows and macOS installs write the config file
0600; the launchd plist
holds the secret key and is not world-readable. - Reports go through private vulnerability reporting, not public issues.
Known limitations
- Single owner account; no multi-user sharing (use public links).
- Files live in folders; no folder or zip download.
- No live cross-device refresh (no SSE): the UI refreshes after your own
actions, and another device's changes appear on reload. - LAN discovery is URL + QR.
LOCALDROP_MDNS_ENABLEDis reserved and unused. - macOS Homebrew ships raw tarballs, not bottles: no
brew installof a
pre-built binary, so the formula builds from the release archive. - Windows binaries are unsigned. SmartScreen will warn on first run.
- 9 of 31 Must-have requirements have no automated test; they are listed with
reasons inscripts/check_fr_traceability.pyunderKNOWN_GAPS. - The embedded PostgreSQL is downloaded from Maven Central on first run and is
not checksum-verified. (Release artefacts are; this one is not yet.)
Full changelog: https://github.com/Abhi-Subedi/LocalDrop/blob/v1.1.0/CHANGELOG.md
Upgrade notes: forward-only migrations. Take a backup first (docs/BACKUP.md).