Skip to content
tafseeriqbalPublic

About

iPhone to laptop org-mode sync through a home server. WebDAV inbox, git, and a systemd timer.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

org-sync

How a note typed on my iPhone ends up on my laptop, through my home server. No third-party cloud, just WebDAV, git and a systemd timer.

phone ── WebDAV ──> server ── git push ──> GitHub ── git pull ──> laptop

The server itself (hardware, firewall, SSH, Pi-hole) is in homeserver-barebasics.

How it works

  1. I use an org-mode app on my iPhone for quick notes. It saves them to mobile-inbox.org on the server over WebDAV
  2. Every 5 minutes, org-sync on the server moves anything new from that file into my notes repo, and empties the phone's copy
  3. Then it commits, pulls and pushes
  4. My laptop runs the same script on the same timer, so it pulls the note down

A note typed on my phone shows up on my laptop in under 10 minutes.

If two machines edit the same lines at the same time, git can't merge them. The script then stops, logs an error, and waits for me to fix it by hand.

WebDAV (phone inbox)

WebDAV is file sharing over HTTPS.

  • Apache serves one folder, ~/webdav. The only file in it is mobile-inbox.org
  • Port 8443, because Pi-hole already uses 80 and 443
  • Password protected, and only reachable over the tailnet
  • HTTPS certificate comes from Tailscale (tailscale cert). It lasts 90 days and I renew it by hand
Port Who can reach it RAM used
8443 Tailnet only 12 MB (Apache)

RAM measured with systemd-cgtop -m.

Setup: server

Needs the base setup from homeserver-barebasics done first.

1. WebDAV

Apache, over HTTPS, tailnet only. Pi-hole already has ports 80 and 443, so Apache can't use them.

sudo apt install -y apache2 apache2-utils
sudo cp apache/ports.conf.example /etc/apache2/ports.conf
sudo a2dissite 000-default
sudo a2enmod dav dav_fs auth_basic ssl
sudo htpasswd -c /etc/apache2/webdav.htpasswd <user>
mkdir -p ~/webdav && chmod 775 ~/webdav
sudo usermod -aG <user> www-data

Get a real certificate from Tailscale. iPhones won't accept plain HTTP or a self-signed one:

sudo tailscale cert \
    --cert-file /etc/ssl/<host>.<tailnet>.ts.net.crt \
    --key-file /etc/ssl/<host>.<tailnet>.ts.net.key \
    <host>.<tailnet>.ts.net

Copy apache/webdav.conf.example to /etc/apache2/sites-available/webdav.conf, fill in the placeholders, then:

sudo a2ensite webdav
sudo apache2ctl configtest
sudo systemctl restart apache2
sudo ss -tlnp | grep 8443

The certificate lasts 90 days. To renew, run the tailscale cert command again and restart Apache.

2. git mirror

The server needs its own SSH key for GitHub:

ssh-keygen -t ed25519 -C "<host>"
cat ~/.ssh/id_ed25519.pub     # add this to GitHub, Settings > SSH keys
ssh -T git@github.com

Clone your notes repo and set who the commits come from:

git clone git@github.com:<you>/<notes-repo>.git ~/org
git config --global user.name "<n>"
git config --global user.email "<email>"

Then this repo, and install:

git clone git@github.com:<you>/org-sync.git ~/src/org-sync
~/src/org-sync/install.sh server

install.sh server links the script into ~/.local/bin, installs the timer, opens 8443 on the tailnet, and turns on linger. Without linger the timer stops when you log out.

Setup: laptop

Same notes repo in ~/org, then:

git clone git@github.com:<you>/org-sync.git ~/src/org-sync
~/src/org-sync/install.sh

The laptop has no ~/webdav, so the script skips the phone part and just syncs.

Things that went wrong

1. Two programs, one port

Apache wouldn't start. sudo ss -tlnp showed Pi-hole already using port 80. I turned off Apache's port 80 and moved it to 8443. Then turning on HTTPS in Apache quietly added port 443 back, and it failed again on that. I turned that off too.

2. The iPhone that never sent the request

The phone app wouldn't sync, and Apache's log was empty. The request never left the phone. iOS blocks apps from using plain HTTP, and it also rejected a self-signed certificate. A real certificate from Tailscale fixed it.

Known gaps

  • The HTTPS certificate has to be renewed by hand every 90 days
  • A conflict stops the sync on that machine until I fix it by hand

Useful commands

systemctl --user list-timers | grep org     # is the sync timer running?
journalctl --user -u org-sync -n 20         # last sync runs and errors
sudo ss -tlnp | grep 8443                   # is Apache listening?
sudo openssl x509 -in /etc/ssl/<host>.<tailnet>.ts.net.crt -noout -enddate   # cert expiry

What's in this repo

org-sync                    the sync script
org-sync.service            runs it once
org-sync.timer              every 5 minutes, starting 1 minute after boot
install.sh                  links the script, installs the timer
apache/ports.conf.example   Apache with 80 and 443 turned off
apache/webdav.conf.example  the WebDAV site on 8443

About

iPhone to laptop org-mode sync through a home server. WebDAV inbox, git, and a systemd timer.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages