Install
Two files, a folder, and Docker. The setup builder writes both files for you; you download them, run one command, and you're up. No cloning, no building. The hardware bar is modest: see what you need.
Two ways to start
- The fast path. Run over plain HTTP and you're using Cobblr in about five minutes. One limitation: scanning from your phone requires HTTPS, so the camera is off until you add it. Adding it later is a two-line edit to the same install; nothing gets redone.
- Right the first time. If you'd rather never touch it twice, set up Tailscale before you install (roughly 30 minutes if it's new to you), pick Tailscale in the builder instead of HTTP, and you arrive with HTTPS, the phone camera, and remote access on day one.
Both paths are the same two files and the same command. The only difference is the HTTPS choice you make in the builder, and it's never final.
The fast path: install over HTTP
-
Generate your files. Open the setup builder. Fill in your email, and under the HTTPS choice pick HTTP (no TLS). Set the address to your box's LAN IP and port, like
192.168.1.50:8088. The builder generates every secret for you. Download.envanddocker-compose.ymlinto one folder on the box.Back up the encryption keyThe builder makes you confirm you've saved
TENANT_CREDS_ENCRYPTION_KEYbefore the download unlocks. Keep that copy off this box. If you lose it, stored integration credentials can't be recovered.Keep data on a NAS or a data diskThe builder's Advanced section has a Data location field. Set it and every mount (database, uploaded files, installed modules, TLS certs) lands under that one path, so Cobblr's data can live on a NAS mount or an appdata root instead of beside the compose file. Leave it blank to keep
./data. See Configuration. -
Bring it up:
docker compose up -dDocker pulls the images (a few minutes the first time) and starts them. Nothing builds.
-
Open it at
http://<your-box-ip>:8088from any device on your network, or athttp://localhost:8088on the box itself. Create your account (signup is open on first run) and look around.
You now have a working instance, with the one limitation from the fork above:
Browsers only allow the camera (barcode scanning, photos) over HTTPS or on
localhost. Scanning works in the browser on the box at localhost:8088, but
not from your phone over http://192.168.x.x. It's a browser rule; nothing in
Cobblr overrides it. The next section fixes it in place.
Turn on HTTPS
This section is both the upgrade from the fast path and the first stop on the do-it-right path; the steps call out where the two differ. HTTPS is what the phone camera requires, and depending on the option you pick here, secure remote access can come along with it.
The catch with a home box: a public certificate authority won't issue a certificate for a private IP, and a public name won't reach your box unless you open a port to the internet or run your own DNS. So getting real HTTPS onto your LAN takes one of the approaches below.
We suggest Tailscale. If you don't already have it (or another solution to this problem), it's worth the roughly 30 minutes to set up. It gives you a real certificate with nothing exposed, and as a bonus you can then reach any of your self-hosted things securely from anywhere, not just Cobblr.
Tailscale (recommended)
Tailscale puts your devices on a private mesh network with real, auto-renewed certificates. Nothing is forwarded, nothing is exposed, and the same URL works at home or away. There are two ways to ride it; the first is easier and gives the nicer URL.
Own hostname (easiest)
Cobblr's bundled proxy joins your tailnet by itself and serves the address you
choose: the first part of the address becomes the node's name, so
cobblr.<your-tailnet>.ts.net joins as cobblr, shop.<your-tailnet>.ts.net
as shop. The box needs no Tailscale install at all; only the devices you
browse from do.
-
Prepare the tailnet (one-time, in the admin console): enable MagicDNS and HTTPS certificates on the DNS page. That page also shows your tailnet name, the
tail1234.ts.netpart of the address. -
Build your files. In the builder, set the address to
cobblr.<your-tailnet>.ts.net, pick Tailscale, and keep Own hostname. Leave the join set to Approve in browser (no key). Fresh install: download both files and bring them up as in fast-path step 2. Upgrading from the fast path: add these to your existing.env(keep your secrets) and remove theWEB_BINDline, thendocker compose up -d:COBBLR_SITE_ADDRESS=cobblr.tail1234.ts.netCOMPOSE_PROFILES=caddyCOBBLR_TLS_MODE=tsnet -
Approve the box. On first start it asks Tailscale to authorize itself and prints a one-time link in the logs. Grab it with
docker compose logs caddy | grep -iE 'to authenticate|login.tailscale', open it, sign in, and approve the new node. This is the same click-to-approve you get authorizing any device, so there is no key to mint. -
Open it at your chosen address from any device signed into your tailnet (install the Tailscale app on your phone and laptop). The camera works everywhere now. One follow-up: find the new node in the admin console and disable key expiry on it, or it signs itself out in about six months.
For a fully unattended box, mint a reusable auth key in the admin console
(Settings, then Keys), choose Auth key (headless) in the builder, and paste
it, or add TS_AUTHKEY=tskey-auth-... to the .env above. The box then joins on
its own with no approval step. Everything else is identical.
The server's own name (tailscale serve)
If the box is already on your tailnet (or you'd rather it be), skip the proxy
and let the machine serve Cobblr under its own name,
https://myserver.tail1234.ts.net:
- Put the box on the tailnet if it isn't:
curl -fsSL https://tailscale.com/install.sh | sh && sudo tailscale up. Its name shows intailscale status. - In the builder pick Tailscale, then Server's name, with the machine's
ts.netname as the address (upgraders: set that address, setCOMPOSE_PROFILES=empty, removeWEB_BIND, keep your secrets), and bring it up. No page appears yet; the app is loopback-bound until the next step. sudo tailscale serve --bg 8088publishes it with a real certificate.
To reach either setup from outside your tailnet without forwarding a port,
sudo tailscale funnel --bg 8088 (the serve variant) puts it on the internet
over Tailscale's edge. Turn signup off first; Funnel must be enabled in your
tailnet's ACL policy and serves only on ports 443, 8443, and 10000.
The Own-hostname mode is exactly this pattern applied to Cobblr: a proxy joins
the tailnet as a virtual node per service. If the box also runs other apps
you'd like at their own ts.net names, the same idea generalizes with a
standalone Caddy built with the tsnet plugin, one block per service. Outside
this guide's scope.
DuckDNS (a free public name)
DuckDNS gives you a free name.duckdns.org and a real Let's Encrypt certificate
through a DNS challenge, so the box never opens port 80 for the certificate. To
actually reach the box, the name points at your public IP and you forward TCP 443
on your router to the box. That puts the instance on the internet, so set
PUBLIC_SIGNUP_ENABLED=false and rely on login.
In the builder pick DuckDNS, claim the name at
duckdns.org, and paste its token. This sets
COBBLR_TLS_MODE=duckdns and DUCKDNS_TOKEN.
To stay off the internet instead of forwarding a port, add a local DNS entry on your router or Pi-hole mapping the name to the box's LAN IP. Do not point the public DuckDNS record itself at a private IP: DuckDNS keeps resetting it to your public address, and many routers block public names that resolve to private ones.
Cloudflare (your own domain)
If you own a domain on Cloudflare, choose Cloudflare in the builder and paste an
API token scoped Zone → DNS → Edit for your zone. It works the same way as
DuckDNS but with your own domain: a real certificate through a DNS challenge, with a
record like cobblr.example.com pointed at your box and a port forwarded to reach
it. This sets COBBLR_TLS_MODE=cloudflare and CLOUDFLARE_API_TOKEN. The local-DNS
option applies here too if you'd rather not expose it.
Offline CA (no domain, no internet, no tailnet)
Choose Offline CA in the builder (COBBLR_TLS_MODE=internal). Caddy runs its own
certificate authority and issues the certificate locally, so nothing leaves the box.
The cost is trusting that CA once per device. After the stack is up, export the CA:
docker compose exec caddy cat /data/caddy/pki/authorities/local/root.crt > cobblr-root.crt
On iOS, install the profile and enable full trust under Settings → General → About → Certificate Trust Settings. On Android, use Settings → Security → Install a certificate → CA certificate. This is the only path that needs no network and no third party at all.
Updating
docker compose pull && docker compose up -d. Details, backups, and
troubleshooting are in Operating.
Once you're in, Your first hour picks up inside the app.