# What 'https with certificate' local test server do others use?

**URL:** <https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499>\
**Category:** Learn\
**Created:** [December 4, 2025, 3:29pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499 "2025-12-04T15:29:15Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![AlanQ](https://avatars.discourse-cdn.com/v4/letter/a/e9bcb4/32.png) [@AlanQ](https://discourse.elm-lang.org/u/AlanQ)\
**Post date:** [December 4, 2025, 3:29pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/1 "2025-12-04T15:29:15Z")

</div>

**Background**

I developed backup and restore for my app.

While testing I found that it was difficult to persuade some browsers to access files for the restore process.

I decided to tackle the _browser trust_ issue before investigating other causes — that is, to install the app with a manifest, which in turn requires _https_, which in turn requires a TLS certificate that browsers will fully trust (no challenge).

**What I’ve tried**

I discovered [caddy](https://caddyserver.com/): “_The Ultimate Server with Automatic HTTPS_”

Very promising. But it also entailed learning how to start/stop/etc stuff with systemd’s `systemctl`. So I’m learning two things and making slow progress.

**My question**

What do other people use for a ‘_browsers think they’re getting this app from a properly certificated https server_’ test environment?

Do I persevere with caddy, or is there an easier way?

---

<div class="post-metadata">

**Author:** ![dwayne](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dwayne/32/5478_2.png) [@dwayne](https://discourse.elm-lang.org/u/dwayne)\
**Post date:** [December 4, 2025, 9:31pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/2 "2025-12-04T21:31:14Z")

</div>

Just to be clear. You’re currently using Caddy for testing during development but to set it up you’re installing it globally and having to use `systemd` to manage it’s lifecycle?

---

<div class="post-metadata">

**Author:** ![Atlewee](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/atlewee/32/4603_2.png) [@Atlewee](https://discourse.elm-lang.org/u/Atlewee)\
**Post date:** [December 5, 2025, 10:53pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/3 "2025-12-05T22:53:51Z")

</div>

I’m using fiddler classic as a proxy and just set up one simple url rewrite rule. I can then convert any https url like [https://localhost](https://localhost) or even [Microsoft.com](http://Microsoft.com) to actually hit [http://localhost:3000](http://localhost:3000) . This makes the browser think its on the real page so you can even use the regular oauth redirect url. A bonus is that this also works for any Device on your network. this is a great way to Connect iPads or phones directly to your dev server receiving live updates on code save. Just add your proxy server in wifi settings. Really nice to quickly get a feel of the size and how touch control work side by side of the pc screen.

---

<div class="post-metadata">

**Author:** ![AlanQ](https://avatars.discourse-cdn.com/v4/letter/a/e9bcb4/32.png) [@AlanQ](https://discourse.elm-lang.org/u/AlanQ)\
**Post date:** [December 6, 2025, 6:37pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/4 "2025-12-06T18:37:09Z")

</div>

Thank you @dwayne, the implication in your question made me laugh 😃

I’m currently _trying_ to use caddy. It was advice on their forum and, as I discovered later, in the documentation, that said manage it using systemd.

Thank you @Atlewee, that sounds good but, from a brief web search, it appears the free version is Windows only — I develop on Ubuntu.

---

<div class="post-metadata">

**Author:** ![timinou](https://avatars.discourse-cdn.com/v4/letter/t/e9c0ed/32.png) [@timinou](https://discourse.elm-lang.org/u/timinou)\
**Post date:** [December 7, 2025, 2:27pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/5 "2025-12-07T14:27:16Z")

</div>

I use localias for these purposes. It maps ports to local addresses that end with ‘.local’ and the browser accepts the HTTPS connection. Hope it works for you!

---

<div class="post-metadata">

**Author:** ![dwayne](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dwayne/32/5478_2.png) [@dwayne](https://discourse.elm-lang.org/u/dwayne)\
**Post date:** [December 8, 2025, 10:30am UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/6 "2025-12-08T10:30:33Z")

</div>

Actually, I wasn’t trying to imply anything. I really was trying to understand your exact situation. However, from your response, what I described does seem to be the case.

I have also used Caddy in some of my projects. I did it via either Devbox or Nix flakes but I never used the HTTPS support. I used it to serve my SPA locally.

- [Install Caddy with Devbox](https://github.com/dwayne/elm-conduit/blob/69b1cf41d38e34c4bd8b61490d28e224a0481ac2/devbox.json#L4-L7)
- [Configure Caddy](https://github.com/dwayne/elm-conduit/blob/69b1cf41d38e34c4bd8b61490d28e224a0481ac2/Caddyfile) (I believe this is where you’d put the configuration you need)
- [Serve up your application with Caddy](https://github.com/dwayne/elm-conduit/blob/69b1cf41d38e34c4bd8b61490d28e224a0481ac2/bin/serve)

No need to use `systemd`. Everything is scoped to your project.

---

<div class="post-metadata">

**Author:** ![AlanQ](https://avatars.discourse-cdn.com/v4/letter/a/e9bcb4/32.png) [@AlanQ](https://discourse.elm-lang.org/u/AlanQ)\
**Post date:** [December 8, 2025, 6:34pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/7 "2025-12-08T18:34:39Z")

</div>

Thank you, @timinou

Looking at the [github pages for localias](https://github.com/peterldowns/localias): it’s running caddy 🙂 …but it does all the setting up for you 😀

---

<div class="post-metadata">

**Author:** ![mywzQxMJ76](https://avatars.discourse-cdn.com/v4/letter/m/898d66/32.png) [@mywzQxMJ76](https://discourse.elm-lang.org/u/mywzQxMJ76)\
**Post date:** [December 8, 2025, 6:48pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/8 "2025-12-08T18:48:45Z")

</div>

Why don’t you use something like [https://packetriot.com/](https://packetriot.com/) or [https://ngrok.com/](https://ngrok.com/) ?

This makes it pretty easy to run the software locally but also have it exposed to the Internet with HTTPS. I personally prefer Packetriot.

Or doesn’t this work in your case?

---

<div class="post-metadata">

**Author:** ![AlanQ](https://avatars.discourse-cdn.com/v4/letter/a/e9bcb4/32.png) [@AlanQ](https://discourse.elm-lang.org/u/AlanQ)\
**Post date:** [December 8, 2025, 11:18pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/9 "2025-12-08T23:18:29Z")

</div>

@dwayne, I thought you were suggesting that it wasn’t a good idea to run something like caddy globally 🙂

It’s interesting that you say,

> [@dwayne](#):
>
> …but I never used the HTTPS support.

My understanding is that modern browsers are suspicious of anything not served _https with a valid TLS certificate_. So to test locally under real-world conditions requires these.

Thank you for the heads-up on _Devbox_ — Microsoft and cloud-based 🙁 — and _Nix flakes_ — another learning curve 🫤

* * *

Thank you @mywzQxMJ76.

> [@mywzQxMJ76](#):
>
> Why don’t you use something like [https://packetriot.com/](https://packetriot.com/) or [https://ngrok.com/](https://ngrok.com/) ?

Firstly, I guess, because I’ve never heard of them 😆

I’m not looking for run-local/expose-global, or to put anything online yet. I just want to persuade locally run browsers that my locally hosted app is coming from a TLS-signed, https served source, so that the app and browser behave exactly as they will when the app is online.

So far, running caddy via [localias](https://github.com/peterldowns/localias) is the front runner…

---

<div class="post-metadata">

**Author:** ![dta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dta/32/1917_2.png) [@dta](https://discourse.elm-lang.org/u/dta)\
**Post date:** [December 9, 2025, 12:29am UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/10 "2025-12-09T00:29:32Z")

</div>

> [@AlanQ](#):
>
> My understanding is that modern browsers are suspicious of anything not served _https with a valid TLS certificate_. So to test locally under real-world conditions requires these.

My experience has been that (mobile) Firefox works fine on [http://localhost](http://localhost), but (mobile) Chrome will not preserve secure cookies on that scheme/domain, which breaks my site

---

<div class="post-metadata">

**Author:** ![mywzQxMJ76](https://avatars.discourse-cdn.com/v4/letter/m/898d66/32.png) [@mywzQxMJ76](https://discourse.elm-lang.org/u/mywzQxMJ76)\
**Post date:** [December 9, 2025, 12:53am UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/11 "2025-12-09T00:53:19Z")

</div>

> [@AlanQ](#):
>
> > [@mywzQxMJ76](#):
> >
> > Why don’t you use something like [https://packetriot.com/](https://packetriot.com/) or [https://ngrok.com/](https://ngrok.com/) ?
> 
> Firstly, I guess, because I’ve never heard of them 😆
> 
> I’m not looking for run-local/expose-global, or to put anything online yet. I just want to persuade locally run browsers that my locally hosted app is coming from a TLS-signed, https served source, so that the app and browser behave exactly as they will when the app is online.
> 
> So far, running caddy via [localias](https://github.com/peterldowns/localias) is the front runner…

Well, the ability to access the app globally is just a side effect, I simply use Packetriot to avoid CORS issues or to test realistically.

However, when you finally run your software on a machine using Caddy that would probably be the best test setup.

---

<div class="post-metadata">

**Author:** ![dwayne](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dwayne/32/5478_2.png) [@dwayne](https://discourse.elm-lang.org/u/dwayne)\
**Post date:** [December 9, 2025, 2:14am UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/12 "2025-12-09T02:14:16Z")

</div>

> [@AlanQ](#):
>
> Thank you for the heads-up on _Devbox_ — Microsoft and cloud-based 🙁 — and _Nix flakes_ — another learning curve 🫤

That’s the wrong Devbox you’re looking at. It’s this one: [Devbox: Portable, Isolated Dev Environments](https://www.jetify.com/devbox). It’s open source, based on Nix, and works locally. It doesn’t have the steep learning curve of Nix and Nix flakes.

---

<div class="post-metadata">

**Author:** ![maca](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/maca/32/4113_2.png) [@maca](https://discourse.elm-lang.org/u/maca)\
**Post date:** [December 9, 2025, 7:45pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/13 "2025-12-09T19:45:00Z")

</div>

caddy seems like a good option, maybe is possible to just run the binary `$ caddy` at least with nginx that is possible.

There is also a bunch free of services to create tunnels to remote servers providing a subdomain and an SSL certificate, useful for testing Oauth, where a valid domain is required.

`$ cloudflared tunnel --url http://localhost:3000`  
`$ ngrok http 3000 --domain=myapp.example.com`

This will of course expose a local server, and that might not be always desirable, claudeflare tunnel, ngrok and others are free, but they require installing a binary. Its also possible to use ssh to make a reverse tunnel and map a port in running nginx… too complicated.  
But this little service seems very cool, no deps!

`$ ssh -p 443 -R0:localhost:8080 qr@free.pinggy.io`  
`$ curl https://myapp.a.pinggy.link # :) ￼`

> **[Pinggy - Simple Localhost Tunnels](https://pinggy.io/)**
>
> Pinggy is the simplest way to bring your localhost projects online. It the the fastest way to create secure tunnels to localhost with a public url.

---

<div class="post-metadata">

**Author:** ![dirkbj](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dirkbj/32/3162_2.png) [@dirkbj](https://discourse.elm-lang.org/u/dirkbj)\
**Post date:** [December 10, 2025, 9:46pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/14 "2025-12-10T21:46:33Z")

</div>

Maybe I’m looking at this too simply, but here is where my head goes. If I understand your situation, you want to run locally and serve over https. There is no need to expose the URL on the internet.

The simplest approach might be to:

1. Create yourself a Certificate Authority cert
2. Sign a cert with that certificate authority for your webserver
3. Install the CA on your local system as an authorized CA
4. Configure your webserver to use your cert (any webserver that supports https will do - many in node, or use Caddy, etc.)
5. Serve your app through the webserver

There are lots of tutorials on how to generate a CA on linux and how to generate a cert with this CA.

Hopefully I’m not misunderstanding things… 😉

This can be expanded to support others on your local net just by sending them your CA and having them authorize it locally on their systems.

---

<div class="post-metadata">

**Author:** ![AlanQ](https://avatars.discourse-cdn.com/v4/letter/a/e9bcb4/32.png) [@AlanQ](https://discourse.elm-lang.org/u/AlanQ)\
**Post date:** [December 14, 2025, 11:14pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/15 "2025-12-14T23:14:35Z")

</div>

@dta — yes, we have to try to cover all reasonable possibilities.

* * *

Thanks, @mywzQxMJ76 Yes, I’m tending towards caddy 🙂

* * *

Thank you, @dwayne 🙂 Jetify Devbox looks like it might be very useful.

* * *

Thank you, @maca — @timinou’s suggestion of localias effectively runs `$ caddy`.

Lots of interesting ideas there 🙂

* * *

Thank you, @dirkbj

> [@dirkbj](#):
>
> you want to run locally and serve over https

Yes, that’s correct.

Your enumerated list looks to be what I need.

If I understand stuff so far, caddy does 1,2 and 3.

> [@dirkbj](#):
>
> This can be expanded to support others on your local net just by sending them your CA and having them authorize it locally on their systems.

Hmm… I want to avoid having to send anything (except the website) explicitly to another device; I want the local test ‘experience’ to exactly mimic what happens in production.

---

<div class="post-metadata">

**Author:** ![evancz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/evancz/32/16_2.png) [@evancz](https://discourse.elm-lang.org/u/evancz)\
**Post date:** [December 15, 2025, 10:07am UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/16 "2025-12-15T10:07:38Z")

</div>

I recently looked into creating “self signed certs” automatically for things like `elm reactor` since it is much nicer to test with HTTPS. The basic idea is [this](https://letsencrypt.org/docs/certificates-for-localhost/) and they mention [mkcert](https://github.com/FiloSottile/mkcert).

Like @dirkbj says, creating a cert (especially a self-signed cert) is basically a single `openssl` command. The annoying thing is adding it to the list of “trusted certs” on your computer, which is different on Mac, Windows, etc.

So from my perspective, if I had something that gave very nice OS-specific instructions on how to add/remove trusted certs, maybe it’s plausible to support self-signed certs more directly. (I haven’t gone further than “knowing how to create my own certs” because I didn’t want to keep looking into the OS-specific details.

---

<div class="post-metadata">

**Author:** ![AlanQ](https://avatars.discourse-cdn.com/v4/letter/a/e9bcb4/32.png) [@AlanQ](https://discourse.elm-lang.org/u/AlanQ)\
**Post date:** [December 24, 2025, 8:23pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/17 "2025-12-24T20:23:42Z")

</div>

Thank you, @evancz

So getting the browser to trust the cert is the most difficult part.

Interesting question [here](https://stackoverflow.com/questions/4461360/how-to-install-trusted-ca-certificate-on-android-device) — the accepted answer seems to suggest that adding an xml file and a line in the manifest might do the trick (at least on Android). But it’s quite an old thread…

---

<div class="post-metadata">

**Author:** ![dta](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dta/32/1917_2.png) [@dta](https://discourse.elm-lang.org/u/dta)\
**Post date:** [December 24, 2025, 8:58pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/18 "2025-12-24T20:58:30Z")

</div>

That answer describes how to have the Android app you are developing trust a certificate. It is not relevant to getting a browser to accept it, although I can’t rule out that there is some way to do that. (the KitKat through Marshmallow section appears to describe installing a certificate globally, but those devices are practically irrelevant these days)

---

<div class="post-metadata">

**Author:** ![damir](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/damir/32/5549_2.png) [@damir](https://discourse.elm-lang.org/u/damir)\
**Post date:** [December 25, 2025, 5:47pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/19 "2025-12-25T17:47:07Z")

</div>

I used mkcert + one local domain per project for years. After my last laptop move I got tired of juggling local domains, trust stores, and all the little setup gotchas.

These days I use a real domain I bought purely for local dev and get proper Let’s Encrypt certs via DNS-01 (prove you control the DNS record; LE doesn’t need to contact the web server). Because it’s a public domain I can put it in public DNS pointing at `127.0.0.1` (and/or other non-routable IPs for LAN testing). I also picked a short `.dev` since it’s HSTS-preloaded, so no messing around with port 80 / redirects.

This is easy for me because I already run hosting infra and manage lots of certs anyway. For most people it’s probably not worth the hassle just to get nice HTTPS localhost URLs.

So: would the Elm community want a shared setup for this?

Idea:

- I run a domain like `example.dev` (name doesn’t matter, just short-ish).

- You register, grab a tiny CLI, and it gives you a unique subdomain (e.g. `abc123.example.dev`).

- The service handles the DNS records and you get a real LE cert for that hostname, with auto-renewal.

- This CLI tool can be a web server / TLS terminator by itself, so you don’t have to bother setting something up locally.

Now the important part, and the reason this needs _some_ “business” wrapper even though I’m not trying to start a business: to do this at scale the domain must go on the Public Suffix List (PSL). PSL is what makes browsers treat something like `.co.uk` as a top-level domain. If `example.dev` is _not_ on the PSL, then all issued certs are just “subdomains of one domain”, and you run into CA rate limits pretty quickly when you’re handing out lots of certs. The PSL policy expects the operator to provide subdomains to unrelated third parties — i.e., it looks like a service, not a private domain. That’s the only reason the structure has to look official.

I’m not looking for a “business opportunity” here. Happy to run it because it’s low-effort for me _if_ there’s real interest. (And I am anyway looking for a good demo for my pghttp project, so all hosting infra would be an example Elm project)! But it’s not worth building unless the community actually wants it and is willing to chip in for the boring costs (short domains aren’t cheap, and there’s some infra to keep it reliable).

If there’s enough interest, I’d aim for something like ~$15/year per person to cover domain + servers. No upsells, no growth plan. If people prefer it lives under the Elm Foundation (or someone trusted), I can help set it up and hand it off.

Would anyone actually use this? Roughly I’d need ~100 people willing to put in ~$15/yr to make the first year make sense.

---

<div class="post-metadata">

**Author:** ![AlanQ](https://avatars.discourse-cdn.com/v4/letter/a/e9bcb4/32.png) [@AlanQ](https://discourse.elm-lang.org/u/AlanQ)\
**Post date:** [December 29, 2025, 10:47pm UTC](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499/20 "2025-12-29T22:47:45Z")

</div>

Thank you @dta, and apologies for misreading the stackoverflow post. Doubtless an element of wishful thinking on my part.

* * *

Thank you @damir

In trying to understand your reply I find myself plumbing the depths of my ignorance. From yours and all the other replies, this would appear to be a more complex issue than I at first thought.

This isn’t of course an Elm-specific problem. Given that everyone creating web apps (using any the plethora of technologies) must eventually hit this issue, it’s frustrating that there isn’t already a solution.

* * *

Perhaps I might be permitted to _branch_ my question (twice!)…

1. Why would there not be a web app manifest [member](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Manifest/Reference) that tells the browser, ‘_this is a local test site, behave like it’s a live site_’ ?

2. When an app is served on a local https server with a self-signed certificate, apart from the browser complaining about the _self-signed_ certificate, what other inconsistencies have people experienced relative to a live public site?  
In other words, is this actually such a big issue?

[Next page](https://discourse.elm-lang.org/t/what-https-with-certificate-local-test-server-do-others-use/10499.md?page=2)
