Local-first setup
Local-first setup
This requires a landing page that works over mDNS.
Key Risk
Can we use HTTPS for a domain like lores.local. If not, will common browsers accept an HTTP connection instead.
Resources and notes
mDNS A Records
I’ve got this working. I built a tool called coop-cloud-mdns-publisher that automatically publishes mDNS records for Co-op Cloud services.
I have the following work to do in ccmdns:
- For apps with hyphens in their names: When I setup the app
lores-node-radish.local-env, it seems to think it’s app name islores-node-radish, and so ccmdns creates a mDNS record calledlores-node-radish-radish.local. I’ve fixed this for now by using recipe name instead
App publishing
I can publish the app in abra, providing I use the -D / --no-domain-checks flag. Otherwise, it’ll try and check the domain on the internet and fail.
I’ve found the following niggles that I’d like to fix in abra, to make things easier:
- Automatic no domain lookup on
.localaddresses - When creating a new app for a
.localaddress, auto-suggestappname-hostname.localinstead ofappname.hostname.local
Self signed certificate
Instructions based on Running an offline co-op cloud server
Step 1: Add the wildcard config to traefik. Run abra app config traefik-radish.local before deploying Traefik (if already deployed, un-deploy it).
Un-comment the lines in the config:
WILDCARDS_ENABLED=1
SECRET_WILDCARD_CERT_VERSION=v1
SECRET_WILDCARD_KEY_VERSION=v1
COMPOSE_FILE="$COMPOSE_FILE:compose.wildcard.yml"
Step 2: Generate a certificate for the local server:
openssl req -x509 -out radish_local.crt -keyout radish_local.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=radish.local' -extensions EXT -config <( \
printf "[dn]\nCN=radish.local\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:radish.local,DNS:*.local\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
Note that the CN (Common Name) is my local Pi hostname (eg radish.local) but it’s critical that there’s also a subjectAltName that is *.local to cover the hyphenated app names, like traefik-radish.local.
Step 3: Add this certificate as docker secrets
abra app secret insert traefik-radish.local ssl_cert v1 radish_local.crt -f
abra app secret insert traefik-radish.local ssl_key v1 radish_local.key -f
Step 4: Deploy traefik
abra app deploy traefik-radish.local -D
Archived notes
- Default Raspberry Pi Ubuntu config does not publish Avahi record. The fix is to enable
publish-workstationand restart the Avahi daemon as per this article - This go program is amazing, and does what it says on the tin. go-avahi-cname
So the go-avahi-cname app uses CNAME mDNS records (as you might expect). When I run that, I can detect the subdomain from my dev computer with a command like avahi-resolve-host-name traefik.radish.local.
However, if I try and ping, I get the following results on different platforms.
- MacOS: Works fine
- Linux (Ubuntu 26.04 LTS): Does not work. Instructions to fix it require a change to the client computer, which is annoying
- Windows: Does not work
Fixing on Ubuntu
/etc/nsswitch.conf — change mdns4_minimal to mdns
Create /etc/mdns.allow containing:
.local.
.local
*.local.
*.local
Switching to mDNS A records
The above approach has two problems. Firstly, mDNS CNAME records aren’t really a thing, they’re an Avahi extension, not supported by all mDNS resolvers.
Secondly, not all platforms support the approach of nesting “subdomains” in mDNS.
The solution is to use A records, and to format them like traefik-radish.local (or perhaps radish-traefik.local).
To test this, run a command like the following on the pi
avahi-publish-address -R traefik-radish.local 192.168.196.232
Where the local IP of the pi is used, or find that dynamically using:
avahi-publish-address -R traefik-radish.local $(hostname -I | awk '{print $1}')
Production ready A-record approach
There’s no well-maintained tool that publishes multiple A records (not CNAMEs) via Avahi dynamically. The ecosystem has mostly converged on CNAMEs for this use case, which is why cross-platform support is patchy.
Either I need to run multiple avahi-publish-address processes, or write a small program to call the Avahi D-Bus API to publish multiple A records in one process.
App Traffic routing
The Co-op Cloud traefik setup insists on HTTPS (sensibly). I need to investigate using self-signed certificates for .local apps, or using (gasp) HTTP.
- Traefik dashboard wont display on insecure HTTP (probably for the best)
- Traefik wont direct traffic to lores-node-radish.local on insecure HTTP (sad face)