Linux
wget https://github.com/MultiX0/LocalDrive/releases/latest/download/server
chmod +x server
./server
Windows, in PowerShell
Invoke-WebRequest https://github.com/MultiX0/LocalDrive/releases/latest/download/server.exe -OutFile server.exe
.\server.exe
That is the whole install. One file, no runtime, nothing to configure first. It
asks a few questions, generates its own secrets, and starts. Setup then offers
to put it on your PATH, and after that you type localdrive from anywhere.
On a Raspberry Pi or an ARM server, use server-arm64 in place of server.
Local Drive is a private alternative to Google Drive that runs on a computer you own. Your files stay on your machine. There is no account to make with anyone, no subscription, and no company in the middle.
The server is the product. The apps are just windows onto it.
Everything lives in the server: your files, the accounts, the permissions, the versions, the sharing. Every rule is decided there and enforced there, on every request. That is the piece you install, the piece you back up, and the piece that is actually yours.
The phone and desktop apps hold nothing of their own. They ask the server what exists and show it. Uninstall every one of them and you have lost nothing, because none of them were ever where your files were. Point a fresh one at the same address and everything is back.
Links you share are the exception. Those open in any browser, served by the server itself, so the person you sent one to installs nothing.
The command at the top does this. To do it by hand instead, take server for
Linux or server.exe for Windows from
the latest release.
There is no published macOS build yet. The server does run on macOS, so on a
Mac build it from source with cd server && go build ./cmd/localdrive.
On Linux, a fresh download is not executable yet, so allow it to run first:
chmod +x ./server
./server
On Windows, run server.exe or double-click it.
That is the whole command. There is nothing to configure first. It asks a few questions, generates every secret it needs, and starts. You never have to invent a password for anything internal.
During setup it offers to put itself on your PATH, so that afterwards
localdrive works from any directory. If you skip that, run
./server install-path later.
To keep it running after a reboot, see Keeping it running: systemd on Linux, Task Scheduler on Windows.
The server has no web interface. It serves an API, so http://localhost:7443
in a browser answers with a 404 and
{"error":{"code":"not_found","message":"no such endpoint"}}That is correct behaviour, not a broken install. The only page it renders for a browser is a share link.
Install a client from the latest release:
| Android | localdrive-client.apk |
| Windows | localdrive-client-setup.exe, or localdrive-client-windows.zip |
| Linux | localdrive-client-linux.tar.gz |
Open it and point it at the address setup printed. On the same machine that is
localhost, otherwise it is the machine's address on your network, for example
192.168.1.10. The app also scans the network and usually lists the server on
its own.
The first account created becomes the admin. That is you. Afterwards the server refuses to create another one that way.
If you installed with Docker, setup offers to make that account for you during
install, and if you skip it the temporary login is admin / admin12345,
which has to be changed before anything else works.
Plain HTTP is the default, because no certificate authority will issue a
certificate for an address on your own network. If you have a domain pointing
at the machine, set LD_DOMAIN in .env and it gets a real certificate on its
own, Docker or not. That needs ports 80 and 443 open, since those are the only
two Let's Encrypt will connect back on. See
HTTP and HTTPS.
- On the computer running the server, find its address on your network. On
Windows run
ipconfig, on macOS or Linux runifconfig. Look for something like192.168.1.10. - Install the Local Drive app on your phone.
- The app scans your network and should find the server on its own. Tap it.
If it does not appear, type the address, for example
192.168.1.10. - Sign in with the account you just made.
localdrive set everything up, asking a few questions
localdrive serve run it in this terminal
localdrive status where it is, and whether it is running
localdrive logs follow the log
localdrive backup copy your files and database somewhere safe
localdrive update check for a new release and install it
Every command is in the CLI reference. It runs on Windows, macOS, and Linux.
Probably not, and the binary is the better default. One process instead of three, a start measured in milliseconds, and a memory footprint in the tens of megabytes. On an old laptop or a Raspberry Pi with 1 GB of RAM that matters: the Docker daemon by itself costs more than this entire server does.
A docker-compose.yml ships in server/ and is worth using when you want one
of three specific things, all of which are separate services the bare binary
cannot provide:
- The browser client. Caddy serves it. The bare binary answers the API and nothing else, so use one of the apps with it, or run Docker.
- Drive management from inside the app, which is Linux only
- Network discovery, so phones find the server without typing an address
HTTPS is no longer one of them. Set LD_DOMAIN and the binary requests and
renews its own certificate, with nothing in front of it.
cd server
docker compose up -d
See Running without Docker for exactly what each option costs you.
Local Drive does not let strangers sign up. To give someone an account:
- Open Settings, then Users.
- Tap Invite someone and give the invite a name, like "Mom".
- Send them the code, the link, or the QR code however you normally talk.
- They enter it on their own device and pick their own username and password. You never see or handle either.
Each person gets their own private space. Being an admin means you manage accounts, storage, and settings. It does not mean you can read anyone else's files.
- Files, folders, versions, and a trash that holds things for 30 days.
- Share a link with anyone, with an optional password, an optional expiry, and view only or download. Change any of that later without the link changing.
- Share with someone on your server by tapping their face. No usernames to type. They keep access on every device they own.
- Plug in a USB drive and tap "Use this drive". Eject it safely from the app when you are done, or combine several drives into one big one.
- Uploads survive a dropped connection. They continue from the exact byte they stopped at, not from the beginning.
- English and Arabic, each with its own typeface and full right to left layout.
| Problem | Answer |
|---|---|
| Browser says "Not secure" | Expected with no domain name. It is plain HTTP on your own network, not a broken certificate. See HTTP and HTTPS. |
| The app cannot find the server | Type the address instead. Both devices need to be on the same network. |
| The app says the server is unreachable | Check you did not type https://. With no domain it serves HTTP, and an HTTPS request fails during the handshake. |
| Forgot the admin password | Run localdrive reset-admin |
| A USB drive does not show up | Drive management needs Linux. On Windows or macOS, plug it in, then point Local Drive at the folder. |
More in Troubleshooting, every command in the CLI reference, and every setting in Environment variables.
The files browser on desktop. Folders and files carry their own type colour, and the badges say what is shared, starred, or kept on this device.
Every photo in one timeline, grouped by month and ordered by when it was taken rather than when it was uploaded. The grid is masonry, so a panorama stays a panorama instead of being cropped to a square.
These are screenshots of the running app, not mockups.
| Folder | What it is |
|---|---|
server/ |
The Go backend. One binary, several modes. This is the product. |
localdrive/ |
The Flutter app. One codebase, every platform. |
docs/ |
The full documentation, rendered by the site. |
landing/ |
The website, which reads docs/ directly. |
e2e/ |
End-to-end tests, run on TestSprite against a deployment. |
cd server && go test ./... && go vet ./...
cd localdrive && flutter analyze && flutter test
cd landing && npm run build
Start with Architecture overview and Development setup.
Those three commands are the whole local loop and need no account anywhere.
Unit tests prove the pieces. They cannot tell you that a screen sits empty because the client is calling a route the server does not serve, because from inside the code nothing is wrong. That is the gap this layer covers, and it found exactly that bug in this repository.
npm install -g @testsprite/testsprite-cli
testsprite setup
testsprite test run --all --project "$TESTSPRITE_PROJECT_ID" --wait
The suite is in e2e/testsprite/: ten workflows written as
sentences, and five checks on the API contract.
Recommended, never required. TestSprite is a development dependency. The server does not call it, CI does not run it, and no key is needed to clone, build, test or send a pull request. The three commands above this section remain the whole contribution loop.
Testing with TestSprite has the rest,
including authentication, reading a failure, the AI agent workflow, and why the
CLI cannot point at localhost. TestSprite's own documentation is at
docs.testsprite.com.
| Vision | Why the project exists, what it refuses to become, and how to judge whether a change belongs. |
| Contributing | How to get it running and what makes a change easy to accept. |
| Testing | The layers, what belongs in each, and what must not break. |
| TestSprite | The end-to-end layer: installing the CLI, running the suite, and reading a failure. |
| Security review | What to check before merging, and the concerns currently open. |
| Code of conduct | Be decent to people. |
| Security policy | How to report a vulnerability privately, and what is in scope. |
| Disclaimer | What this is and is not built for. Worth reading before you trust it with anything. |
| Notes for coding agents | Context for an AI assistant working in this repository. |
MIT. See LICENSE.

