Offline Device-to-Device File Sharing
I was recently travelling abroad and needed to transfer a large file from my Android phone to my wife’s iPhone. Waiting in the security queue in the airport with a patchy internet connection, no computer or USB cable, I was stumped. I was sure there were plenty of shady devs on the Play Store queuing up to offer file-sharing apps crammed full of ads and other abusive behaviour or worse… but I hoped to avoid all that.
After a few minutes a thought came to me, what about running a Wi-Fi hotspot and web server on my phone for my wife’s to download from?
Enter Termux and Caddy #
Termux is a nifty Android app that provides a terminal emulator to a Linux environment where you can install APT packages as normal. It’s also available through F-Droid, which runs reproducible builds for a ton of useful FOSS apps from source.
Caddy is actually the web server running this very website. It’s an open-source web server with some very helpful automatic TLS magic, useful workflows for local development and (fairly) easy configuration.
Getting Started #
Packages in Termux are typically installed via pkg
as a wrapper around apt
so let’s get Caddy installed with pkg install caddy
:


âšī¸ Warning
Before proceeding turn on airplane mode, then re-enable your Wifi hotspot with a secure password. Otherwise you’ll potentially share these files with anyone on the same network as you.
Without root, Termux does have some limitations as to what it can access on your phone and these became more restrictive with Android 11 (useful docs here). If that’s TL;DR, run termux-setup-storage
and you should be prompted for the permissions needed to give Termux access to read files in your Downloads folder (you can obviously share files from other places but that was all I needed).
We can then launch Caddy. In a proper production setting, we’d create a config file or use the admin API for Caddy but for this scenario (I was getting closer to the front of the queue!) it was sufficient just to use the file-server
CLI option.
caddy file-server `
--root ./storage/downloads `
--listen :8080 `
--browse
But wait! Don’t blindly copy paste commands from the internet! Let’s check what this does and understand it:
caddy
: the Caddy server executable,file-server
: spins up a simple but production-ready static file server,--root ./storage/downloads
: tells Caddy which directory to serve to clients,--listen :8080
: the default port 80 is reserved and not usable without root access so we’ll use 8080 instead,--browse
: enable directory listing to show all the files available (if no index file is present)
If you’re trying to troubleshoot the setup, the --access-log
option is also handy to output any requests coming in.
So let’s fire up the hotspot, connect the iPhone to it and see what we get. First we’ll need to know the IP address of the Android phone. I’m sure it’s simple to find the gateway IP from the iPhone but I chose to do it from the Android and ran into another interesting limitation. Normally I’d use ip addr
but that gives a permission error. Instead the older ifconfig
tool can give partial information (with a warning). There was further discussion in termux/termux-app#2993.


Once we’ve got the IP, we can browse to it from Safari on the iPhone, for example, http://192.168.178.21:8080/
(replacing the IP address with the one we found above) and download away!
Tidy Up #
Turn it off when you’re done, this isn’t secure.
Seriously, you’re sharing your downloads folder with any devices on the same network as you đ . Only use it with the trusted devices on your password-protected hotspot.
To terminate the Caddy server, just hit the CTRL button and then type C.


Future Explorations #
If you’re running Tailscale, Caddy can get HTTPS certificates from the local Tailscale daemon so this setup can work securely across devices on different networks. Something like this worked for me from a Linux desktop environment but I’ve not explored it on Android:
caddy file-server `
--root ./ `
--domain machine-name.domain-alias.ts.net `
--browse
Perhaps even cooler (if you want to go deeper into Tailscale’s ecosystem) is Taildrive, an alpha feature letting you create a WebDAV file server that can be accessed from another client. Bonus here is that it will presumably allow a client to read and write (Caddy file-server is read-only).