Self-hosted LAN file transfer server. Share files between any devices on your Wi-Fi — no internet, no cloud, no apps required on receiving devices.
Demo video: Watch on YouTube
You run Lanvan on one computer. Every other device on the same network can then open a browser and instantly upload or download files — no app, no account, no internet connection required.
Works over Wi-Fi, Ethernet, and mobile hotspot — any local network where devices can reach each other.
Typical use case: You want to move a photo from your Android phone to your Windows laptop, or drop a file from your PC onto your tablet, without emailing it to yourself or using a cloud service.
Lanvan stores files on the computer running it. Nothing is sent outside your local network.
| Feature | Notes |
|---|---|
| Browser-based | Receiving devices need no app — any modern browser works |
| Folder upload | Entire folder trees uploaded with subdirectories preserved |
| Clipboard sync | Share copied text between devices in real time over WebSocket |
| QR code connect | Scan the displayed QR code on mobile to open instantly |
| mDNS discovery | Access via http://lanvan.local on supported networks |
| Chunked upload | Large files split and reassembled for reliable transfer |
| Version history | Previous versions of uploaded files retained |
| HTTPS optional | Self-signed certificate auto-generated when enabled |
| Cross-platform server | Runs on Windows, Linux, macOS, Android (Termux) |
| Network support | Wi-Fi, Ethernet, and mobile hotspot (any local network) |
| Docker image | Pre-built image available on Docker Hub |
No authentication is included by default. Anyone on the same local network can access Lanvan while it is running. See Security.
Lanvan has two ways to run. Choose the one that fits you:
| Method | Best for | Requires |
|---|---|---|
| Docker (recommended) | Most users — no Python setup needed | Docker Desktop (Windows/macOS) or Docker Engine (Linux) |
Python (python run.py) |
Developers, Android/Termux, no Docker | Python 3.9+ |
Jump to the right section:
Files stored in
./datasurvive container restarts and updates. Nothing is stored inside the Docker image itself.
- Windows / macOS: Docker Desktop (free)
- Linux:
sudo apt install docker.io docker-compose-plugin
Open PowerShell in any folder where you want to store your files. Run:
# 1. Download the launcher script
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/P7XCKD/lanvan/main/start-lanvan.ps1" -OutFile "start-lanvan.ps1"
# 2. Start Lanvan
.\start-lanvan.ps1The script automatically:
- Detects your PC's Wi-Fi / Ethernet IP address
- Creates a
data\folder for your files - Starts the Docker container
You will see:
LAN IP : 192.168.x.x
LAN URL : http://192.168.x.x
Local : http://localhost
Data : ./data
QR : Ready
Open http://localhost in your browser. Open http://192.168.x.x on your phone (same Wi-Fi).
If the script is blocked by PowerShell execution policy, run this first:
Set-ExecutionPolicy -Scope CurrentUser RemoteSignedOpen a terminal in any folder where you want to store your files. Run:
# 1. Download the launcher script
curl -O https://raw.githubusercontent.com/P7XCKD/lanvan/main/start-lanvan.sh
# 2. Make it executable
chmod +x start-lanvan.sh
# 3. Start Lanvan
./start-lanvan.shYou will see:
LAN IP : 192.168.x.x
LAN URL : http://192.168.x.x
Local : http://localhost
Data : ./data
QR : Ready
Open http://localhost in your browser. Open http://192.168.x.x on your phone (same Wi-Fi).
If you prefer to run the container without the launcher scripts, you need to pass your host PC's LAN IP manually using -e LANVAN_HOST.
Tip
The easiest and most reliable way is .\start-lanvan.ps1 — it already handles all of this automatically. Use the manual commands below only if you specifically need docker run instead of Compose.
Find your LAN IP first:
| Platform | Command |
|---|---|
| Windows (PowerShell) | See Step 1 below |
| Linux | hostname -I | awk '{print $1}' |
| macOS | ipconfig getifaddr en0 |
Then run:
Windows (PowerShell) — auto-detects IP:
# Detect your Wi-Fi / Ethernet IP (skips virtual and loopback addresses)
$IP = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object {
$_.IPAddress -notlike "127.*" -and
$_.IPAddress -notlike "172.*" -and
$_.IPAddress -notlike "169.254.*"
} | Select-Object -ExpandProperty IPAddress -First 1)
Write-Host "Using LAN IP: $IP"
# Run the container
docker run -d --name lanvan-app -p 80:80 -e "LANVAN_HOST=$IP" -v "${PWD}/data:/app/data" devprobs/lanvan:latestNote
If $IP still shows a wrong address, set it manually: $IP = "192.168.1.x" (replace with your actual Wi-Fi IP from Settings → Wi-Fi → Properties).
Linux / macOS — auto-detects IP:
docker run -d \
--name lanvan-app \
-p 80:80 \
-e LANVAN_HOST=$(hostname -I | awk '{print $1}') \
-v ./data:/app/data \
devprobs/lanvan:latestWindows (Command Prompt) — replace <YOUR_LAN_IP> with your actual IP:
docker run -d --name lanvan-app -p 80:80 -e LANVAN_HOST=<YOUR_LAN_IP> -v "%cd%\data:/app/data" devprobs/lanvan:latestIf you prefer the Docker Desktop visual interface:
- Open Docker Desktop, go to the Search bar, type
devprobs/lanvan, and click Pull. - Click Run on the pulled image.
- Expand Optional settings:
- Host port:
80 - Volume — Host path: Choose or create a local folder (e.g.
C:\lanvan\data) - Volume — Container path:
/app/data - Environment variable: Key
LANVAN_HOST, Value = your LAN IP (e.g.192.168.1.x)
- Host port:
- Click Run.
- Open
http://localhostin your browser.
- Start Lanvan on your PC (using any method above).
- Make sure your phone is on the same Wi-Fi network as your PC.
- On your phone browser, go to
http://192.168.x.x(the IP shown in the Lanvan window). - Or scan the QR code shown in the Lanvan connect panel.
The IP shown is your PC's current address on the local network. It may change if your router reassigns it (DHCP). If the URL stops working after a restart, re-run the launcher to get the updated IP.
Phone cannot connect? Check these in order:
| Problem | Fix |
|---|---|
| Phone is on mobile data | Switch phone to Wi-Fi |
| Phone is on a different Wi-Fi band or guest network | Connect phone to the same network as the PC |
| Windows Firewall is blocking | Run fix_guest_connectivity.bat as Administrator |
| VPN is active on either device | Disable VPN |
QR code shows localhost |
LANVAN_HOST was not set — re-run with the launcher script |
| Devices on router with client isolation | Disable client/AP isolation in router settings |
All uploaded files are stored in the data folder in the directory where you ran the launcher script or docker run command.
./data/
uploads/ ← uploaded files
temp_chunks/ ← temporary chunks during large file uploads (auto-cleaned)
clipboards/ ← clipboard sync history
This folder is mounted into the container as a volume. This means:
- Stopping the container does NOT delete your files.
- Deleting and recreating the container does NOT delete your files.
- The Docker image itself does not store your files.
Important
If you delete the data folder on your host, your files are gone. Docker does not protect it.
Backup: Copy the data folder to a safe location.
Restore: Stop Lanvan, replace the data folder with your backup, restart Lanvan.
# 1. Pull the latest image
docker pull devprobs/lanvan:latest
# 2. Stop and remove the current container (your data is safe in ./data)
docker rm -f lanvan-app
# 3. Start fresh with the latest image using your launcher script
.\start-lanvan.ps1 # Windows
./start-lanvan.sh # Linux / macOSOr with Docker Compose:
docker compose pull
docker compose up -dYour data folder is untouched during updates.
Stop:
docker stop lanvan-appStart again (existing container):
docker start lanvan-appRemove the container entirely (data folder untouched):
docker rm -f lanvan-appdevprobs/lanvan:latest — current recommended release
devprobs/lanvan:v1.0.0 — pinned release
Pull the image:
docker pull devprobs/lanvan:latest| Host port | Container port | Protocol |
|---|---|---|
| 80 | 80 | HTTP (default) |
| 443 | 443 | HTTPS (optional) |
The left side (
80) is the port opened on your computer. The right side (80) is the port inside the container. If port 80 is already in use on your machine, change the left side:-p 8080:80— then openhttp://localhost:8080.
| Variable | Purpose | Example |
|---|---|---|
LANVAN_HOST |
Host LAN IP to advertise for mobile/QR access | 192.168.1.34 |
BLOCK_DANGEROUS |
Block .exe, .bat, .dll, .sys uploads |
true |
# View running containers
docker ps
# View Lanvan logs in real time
docker logs -f lanvan-app
# Stop the container
docker stop lanvan-app
# Start the container again
docker start lanvan-app
# Remove the container (data folder untouched)
docker rm -f lanvan-app
# View container health status
docker inspect --format='{{.State.Health.Status}}' lanvan-appThe repository includes a compose.yaml file. If you have the source repository cloned:
Windows (PowerShell) — recommended method (auto-detects IP):
.\start-lanvan.ps1Windows (PowerShell) — manual IP override:
$env:LANVAN_HOST = "192.168.1.x"
docker compose up -dLinux / macOS — recommended method (auto-detects IP):
./start-lanvan.shLinux / macOS — manual IP override:
LANVAN_HOST=192.168.1.x docker compose up -dCommon Compose commands (all platforms):
# View logs in real time
docker compose logs -f
# Stop
docker compose down
# Optional HTTPS profile (port 443)
docker compose --profile https up -d lanvan-httpsWhat Lanvan does:
- Runs entirely on your local network — no data leaves your machine
- No accounts, no registration, no internet connection required
- Files are stored only in your
datafolder on the host
What Lanvan does NOT do:
- No authentication — anyone on the same network can upload or download files while Lanvan is running
- HTTPS is optional and uses a self-signed certificate (browsers will show a security warning)
- No rate limiting or per-user access controls
Warning
Do not expose Lanvan's port to the internet (e.g. via port forwarding in your router) without additional security measures such as a reverse proxy with authentication. Lanvan is designed for trusted local networks only.
HTTPS mode (optional, auto-generates self-signed certificate):
docker run -d --name lanvan-app -p 443:443 \
-e LANVAN_HOST=<YOUR_LAN_IP> \
-v ./data:/app/data \
devprobs/lanvan:latest --httpsBlock dangerous file extensions (.exe, .bat, .dll, .sys, etc.):
docker run -d --name lanvan-app -p 80:80 \
-e LANVAN_HOST=<YOUR_LAN_IP> \
-e BLOCK_DANGEROUS=true \
-v ./data:/app/data \
devprobs/lanvan:latestHTTPS mode enables
BLOCK_DANGEROUSautomatically.
Uploading:
- Drag and drop files or folders onto the browser window
- Right-click to create folders or upload via file picker
- Large files are chunked and reassembled automatically — no size limit beyond available disk space
- Folder uploads preserve the full directory structure
- Uploads can be paused or cancelled from the upload tray
Downloading:
- Click any file to preview or download
- Folders are downloaded as ZIP archives
- Multiple files can be selected and downloaded together
| Method | Typical speed |
|---|---|
| Docker (HTTP) | Good — slight overhead from container networking |
Python direct (python run.py) |
Better — no container overhead |
| Android App / Termux | Best — native or near-native |
To maximize transfer speed with Docker:
- Use HTTP (default), not HTTPS — avoids encryption CPU overhead
- Connect the host PC via Ethernet instead of Wi-Fi
- Ensure your phone connects to 5 GHz Wi-Fi rather than 2.4 GHz
- On Linux/macOS: install
uvloopfor the Python path (pip install uvloop)
| Problem | What to check |
|---|---|
| Lanvan won't start | Run docker ps — check if another container or service uses port 80 |
| Port 80 already in use | Change host port: -p 8080:80, then open http://localhost:8080 |
| Phone cannot connect | Check LAN URL, Wi-Fi, firewall — see Connecting Your Phone |
QR code shows localhost |
LANVAN_HOST not set — use launcher script or pass -e LANVAN_HOST=<IP> |
| Files seem missing | Check the ./data/uploads folder on your host machine |
| Large upload fails | Check docker logs lanvan-app for disk space or timeout errors |
| Container keeps restarting | Run docker logs lanvan-app to see the error |
lanvan.local doesn't work |
Use the direct IP address instead — mDNS may be blocked by Docker bridge networking |
| Windows Firewall blocking | Run fix_guest_connectivity.bat as Administrator |
| Upload fails with 500 error | Check available disk space on the host |
| Server won't respond | Run docker inspect --format='{{.State.Health.Status}}' lanvan-app |
View logs:
docker logs -f lanvan-appCheck container status:
docker ps -aUse this method if you do not want to use Docker, are on Android/Termux, or are a developer contributing to Lanvan.
| Minimum | Recommended | |
|---|---|---|
| Python | 3.9 | 3.11+ |
| Free disk space | 50 MB | 1 GB+ |
| Network | Local Wi-Fi or LAN | Wi-Fi 5 / Ethernet |
# 1. Clone the repository
git clone https://github.com/P7XCKD/lanvan.git
cd lanvan
# 2. Create a virtual environment
python -m venv .venv
# 3. Activate it
# Windows (PowerShell):
.\.venv\Scripts\Activate.ps1
# Windows (Command Prompt):
.\.venv\Scripts\activate.bat
# macOS / Linux:
source .venv/bin/activate
# 4. Install dependencies
pip install -r requirements.txt# Production mode (default — uses minified assets)
python run.py
# With HTTPS
python run.py --https
# Development mode (unminified source assets from app/)
python run.py --devOn Windows you can also use
py run.py.
The terminal displays the server URL and a QR code. Open the LAN URL on your phone.
Stopping the server:
| Method | Action |
|---|---|
| Keyboard | Press Ctrl+C in the terminal |
| Console | Type close, quit, stop, or exit and press Enter |
Setup scripts for Android Termux are available in docs/termux/.
For contributors and developers.
# Fast regression suite (173 tests)
python qt.py --fast
# Full test suite
python qt.py
# Architectural defect scan
python testing/tools/arch_scan.pypython build.pyThis generates minified JS/CSS into dist/. The run.py launcher auto-builds when needed.
lanvan/
├── android/ # Native Android App (Chaquopy)
├── app/ # FastAPI application source
│ ├── core/ # Cryptography, validation, streaming, locks
│ ├── routers/ # API route controllers
│ ├── ws_manager/ # WebSocket managers (clipboard, file events)
│ ├── utils/ # Platform detection, mDNS, network resolver
│ ├── static/ # Unminified CSS/JS source (dev reference)
│ └── templates/ # Jinja2 HTML templates
├── certs/ # SSL certificate config and generators
├── data/ # Runtime uploads and user data (gitignored)
├── dist/ # Minified production output (gitignored)
├── docs/ # Platform setup guides and Termux scripts
├── testing/ # Test suites and regression scripts
├── build.py # Production asset build pipeline
├── compose.yaml # Docker Compose configuration
├── docker-entrypoint.sh # Container boot entrypoint
├── Dockerfile # Container build definition
├── fix_guest_connectivity.bat # Windows firewall helper
├── qt.py # Automated test runner
├── run.py # Server launcher (dev & prod)
├── start-lanvan.ps1 # Windows Docker launcher
└── start-lanvan.sh # Linux/macOS Docker launcher
python build.py
docker build -t devprobs/lanvan:latest -t devprobs/lanvan:vX.Y.Z .
docker push devprobs/lanvan:latest
docker push devprobs/lanvan:vX.Y.ZGitHub Actions (/.github/workflows/docker-publish.yml) handles automated publishing on tagged releases.
Lanvan suppresses verbose client-side console output in production. To enable full debug logging in the browser:
// Open browser DevTools console (F12) and run:
enableDebug();
// To disable:
disableDebug();Debug mode is saved to localStorage and persists across page reloads.
This project is licensed under the GNU General Public License v3.0 — see the LICENSE file for details.
In summary: you are free to use, modify, and distribute this software, but any distributed version must also be open source under the same license.