top | item 39765630

Lcl.host: fast, easy HTTPS in your local dev environment

247 points| todsacerdoti | 2 years ago |anchor.dev | reply

98 comments

order
[+] JimDabell|2 years ago|reply
Warning: This checks if it’s running the latest version and refuses to run if it isn’t up to date. They just released v0.0.16 15 minutes ago and the update hasn’t hit Homebrew yet, so it has completely disabled itself and won’t run. There doesn’t seem to be any option to skip the version check.

So don’t use this unless you don’t mind it breaking randomly whenever there’s an update.

[+] benburkert|2 years ago|reply
Sorry about that, we're working on switching this to a warning and not an error, that slipped by us before release. After the next update, it will only show a warning if you're not on the latest release.
[+] mholt|2 years ago|reply
When I first announced Caddy, our website downloaded everything as .gz due to high traffic load -- a lesson I learned very quickly and a mistake I never made again.

This probably falls in the same boat. :)

[+] hipadev23|2 years ago|reply
That's an absurd tactic I've not seen since last time I used Firefox.
[+] jollyllama|2 years ago|reply
Gross. Thanks for the heads up!
[+] peter_l_downs|2 years ago|reply
I like the interactive setup. I think this is solid but if you want something even faster and easier to use, try my project localias [0]. The parent project, lcl.host, has some annoying restrictions:

> This CA has some restrictions though: it can only issue certificates for subdomains of lcl.host and localhost, but that’s all you need for local development.

Localias, on the other hand, lets you use any custom domain you'd like. And if you use a domain ending in .local, it will broadcast over mDNS so that you can easily connect to that server from any other device on your wifi network (like your phone.)

Localias also allows you to share your configuration with your entire development team by committing a .localias.yaml file to the root of your git repo. This makes sharing links with each other super convenient.

Always nice to see another competitor in the space; if you're interested in this, please check out Localias as well!

[0] https://github.com/peterldowns/localias

[+] mholt|2 years ago|reply
Neat! I hadn't seen this before, and it uses Caddy :D
[+] maxcoder4|2 years ago|reply
>This CA has some restrictions though: it can only issue certificates for subdomains of lcl.host and localhost, but that’s all you need for local development.

This sound like a security feature, not (just) an annoying restriction. Though an attack model for a local CA is a bit flimsy.

[+] gvkhna|2 years ago|reply
This looks fantastic! Does it support node extra ca cert etc? I’ve had that issue with mkcert in the past and it’s easy to fix but another thing to keep track of in these already complex dev setups if you’re doing local https.
[+] globular-toast|2 years ago|reply
This would be perfect if combined with Traefik's method of config via docker tags.
[+] elzbardico|2 years ago|reply
Oh man, I was up and running in my project in less than one minute. Thanks!
[+] dspillett|2 years ago|reply
It surprises me how few people dev/test against HTTPS, given that it isn't exactly hard to setup manually (with tools like this making it even easier). Just point a wildcard DNS entry at 127.0.0.1 or some other useful address if your dev copy is actually not that local, and chuck a web server there acting as a proxy to what-ever apps, with a LetsEncrypt wildcard cert. It isn't zero work, but saves time in the long run as soon as you hit unexpected issues caused by small differences between dev and prod.
[+] afavour|2 years ago|reply
> It surprises me how few people dev/test against HTTPS

For dev at least it’s mostly because web browsers treat localhost as a special domain that gets the HTTPS treatment even when loaded over HTTP.

I have set up local HTTPS certs before now, can’t remember exactly what required it. But I still load most web projects on localhost over HTTP just out of habit.

[+] knallfrosch|2 years ago|reply
It is hard to set up. Creating a cert and trusting it is easy – a Powershell script can do that in 3 lines.

But then, trouble begins. You have to configure every server to use the certificate (or use a proxy) and every client to accept the certificate. Sometimes the proxies eat headers, or they have trouble with WebSockets and hot reloading or whatever.

We also use IPs instead of domains to find our locally running prod servers so that our customers don't have to configure anything DNS on their maybe-offline WiFi network. We also have to test with external devices, such as iPads. How do you automate getting your certificate onto them?

..And then your IP changes and all is lost again.

Yeah, if you have a 50 line Svelte "app" that you serve as site it's easy. But who does that?

[+] holoduke|2 years ago|reply
I never work locally. Always remote. Dev.xxx.com, stg.xxx.com etc
[+] blopker|2 years ago|reply
I don't see OrbStack mentioned here much, but it's completely replaced Docker Desktop for me. Aside from having a better UI, faster and uses less battery, it also gives local https with custom domains for free [0].

[0] https://docs.orbstack.dev/features/https

[+] drewbitt|2 years ago|reply
OrbStack was mentioned often with all the Docker Desktop / Docker open-source organization drama in the last year or two. But that was when it was free for all, now it's paid for commercial licenses which is less attractive for organizations to switch over. We're all on Colima. But the local https feature is a nice little feature for sure.
[+] ensignavenger|2 years ago|reply
It looks nice, but it is MacOS only, and it is really expensive at $96 per year! Probably why it doesn't get mentioned often.
[+] BroomOfSYS|2 years ago|reply
How is this different from something like Caddy which supports https://localhost instead of something like https://lcl.host
[+] its_stolt|2 years ago|reply
localhost gives you a different security context in your browser than using a full domain name. Typically to use a full domain name locally you'd either need to mess with /etc/hosts (which can bite you later) or mess with DNS. lcl.host just makes things work out of the box.
[+] mholt|2 years ago|reply
I want to point out that Anchor.dev sponsors the Caddy project and we're very grateful for that! Anchor devs have also made code contributions to Caddy and CertMagic.

Anchor has a neat product. They're making internal TLS more accessible to more developers who don't necessarily need a separate web server. They're doing local TLS just about as best as possible from what I can see.

IMO this has more utility than mkcert -- which is a great tool by Filippo and Caddy shares some of its underlying library for its own auto-trusted internal CA -- because, like Caddy, Anchor fully automates the certificates instead of just generating them and needing a cron job. It's more hands-off and higher-level, allowing you to get more done with less effort.

[+] austin-cheney|2 years ago|reply
Some things I learned about trusted localhost HTTPS:

* Windows is the easiest... by far. There is only one trust store and its extremely easy to access at different levels of trust. Firefox has its own trust store so you can either add your certs to both the Windows store AND the Firefox trust store or flip a config in Firefox to tell it to use the Windows trust store like everyone else.

* Linux is a challenge because you have to add your certificates to the OS trust store and then each browser has their own trust stores.

* MacOS is pretty close to impossible, at least fully automated. If the cert is not registered with a third party of the OS's choosing the cert will not be trusted in the browser. The way around this is to manually add your localhost cert chain to the MacOS keychain.

If anybody wants an example here is something I wrote a ways back in JS (but please be warned its specific to my application:

* Build the certificate chain - https://github.com/prettydiff/share-file-systems/blob/master...

* Install the cert by OS type - https://github.com/prettydiff/share-file-systems/blob/master...

That second sample also installs pcap so that I can serve on localhost over ports 80/443.

[+] everforward|2 years ago|reply
> * Linux is a challenge because you have to add your certificates to the OS trust store and then each browser has their own trust stores.

I could be wrong, but I could have sworn Firefox trusts the OS' certificate store. Maybe it's just been too long since I've done it.

[+] zachrip|2 years ago|reply
Off topic but I find this font for the body very hard to read.
[+] Wingy|2 years ago|reply
Why modify the trust stores with the personal CA? Is there any risk to just publishing a globally valid wildcard cert for *.lcl.host, since it always resolves to 127.0.0.1 anyway?
[+] benburkert|2 years ago|reply
We install the CA certificates into the trust stores so that the certificates are trusted by your browsers and clients, otherwise they will (rightfully!) get connection errors. We also set the CAA records for all lcl.host subdomains to anchor.dev, so no public CA will issue certificates for *.lcl.host. The only valid certs for lcl.host subdomains you will encounter are for your account's CAs. If we gave everyone a cert+key for *.lcl.host, besides the security concerns, we'd have to keep redistributing them every ~45 days, but with lcl.host you can setup ACME to automatically renew certs before they expire.
[+] 8organicbits|2 years ago|reply
Some sites have tried this before, but I dont think they stay online long. The certificates are "leaked" when they are shared, so the CA will revoke them.

I think a better approach is to get a domain name and a Let's Encrypt certificate. There's lots of tooling for this, and it matches production. I built https://www.getlocalcert.net/ to act as free, Let's Encrypt compatible subdomain service specifically for these sorts of challenges.

[+] nickphx|2 years ago|reply
"Try for free", no mention of pricing anywhere.. I'll stick to what I'm already doing that's free.. :D
[+] jpambrun|2 years ago|reply
I have another personal solution [0]. It's a DNS server that also gets a wildcard certificate and make it available with a secret. This is definitely in the convenience over security relm, but it resolve any pattern prefix-123-123-123-123-suffix.example.com to the enclosed ip (e.g. 123.123.123.123). It will resolve to 127.0.0.1 or any other ip happily. Now you just need to use the associated cert and enjoy https. Works great from with k8s ingress, caddy, node.. You don't have to fiddle with your trusted store and it works for everybody. I took inspiration from https://nip.io/ for the dns part.

[0] https://github.com/jpambrun/dnsssl

[+] binwiederhier|2 years ago|reply
I've used this service in the past, http://local-ip.co/ which provides downloadable private key and certs and they run a dns service that resolves to any IP address.
[+] d_meeze|2 years ago|reply
I’m skimming the docs looking for how “in containers” is handled and so far I can only see a one liner in the release notes. One problem in local environments I keep having and building tricks for is for services inside containers getting certs for other containers. From within the container, resolving to 127.0.0.1 isn’t helpful as that’s the internal loopback not the host.
[+] benburkert|2 years ago|reply
we're going to say more about how lcl.host works between containers in the future since it ends up pulling in Anchor's package features, but I can give a quick rundown of what we've done in the past with docker-compose: start a service in container A and expose port 44300, and configure the service with an ACME client to provision a `service-a.lcl.host` certificate. The clients in that container won't trust the cert, but that no problem, since your system/browser will trust the cert if you've run `anchor lcl`. In container B, install an anchor built package for the language of the server, and setup the HTTPS/TLS client to use the set of CAs in that package. Now app B can connect to `service-a.lcl.host:443300` over HTTPS/TLS.
[+] robertclaus|2 years ago|reply
In my experience a lot of developers ignore the concept of dev/prod parity like this because a different team (ex. Deployment) ends up dealing with the integration issues it causes. That being said, its also traditionally a balance between effort and output - so I can see a "make it easier" tool like this helping lower the barrier to actually get devs to use it.
[+] WesolyKubeczek|2 years ago|reply
I've just got me a domain and am using letsencrypt. The hostnames resolve to LAN addresses. Still unsure what I'm doing wrong.
[+] jokull|2 years ago|reply
I just use cloudflare tunnels (cloudflared) - don't have to install any certificates, it's all handled by cloudflare. Yes, it exposes globally, but that's often convenient to share a link to my dev with colleagues. And it has been fast enough. Downside is that you need internet connectivity.
[+] redder23|2 years ago|reply
Can you not use Letsencrypt locally? I think I actually saw something about that recently here on HN.

What is the difference between this and LE if true?

I would like to use a .test domain. I use that currently and just click "proceed anyway" whenever the warning pops up and It's pretty often lately.

[+] k__|2 years ago|reply
Congratulations on shipping!

Just yesterday, I needed it for a hackathon, but had to switch to a cloud IDE instead.