How to expose each snap to its subdomain name on the same machine/os ?

My use case:

  • I have Ubuntu Core (on a intel NUC)
  • I have a running nextcloud snap exposed to cloud.mydomain.me (https)

I have moved home an many “things” are connected here, and I want to snap install home-assistant on it to manage them.

  • I now want to run expose home-assistant to home.mydomain.me (https)

Currently I just used my domain name registrar to redirect cloud.mydomain.me to my machine (using CNAME).

What’s next: I should redirect home.mydomain.me too to the same device.

I used to expose manually differents php websites on differents subdomains using apache configuration files for vhost but it was before I use containers or in this case, a confined system

With confined apps on snap, i have no idea where should i do this.
Is it something snapd allows to configure ?
Or somewhere else on Ubuntu Core ?
Do I need to install a snap that its job it to redirect this or that snap ?
Is lord systemd supposed to do that ? :smiley:

Thank in advance for your hints!


(I am not sure where to post it since it is probably part of the solution, so do not hesitate to move it to the best section)

Caddy can probably achieve what you’re looking for; I’m using it on my Ubuntu Core system to act as a reverse proxy to a variety of sites I host on the machine.

But currently, no this is not a functionality snapd directly exposes or makes available itself.

1 Like

Thank for the reply !

I thought caddy was not made for production, just for dev environment, or this status has changed ?

Do you mean caddy the software itself, or the snap?

Caddy itself seems quite production-ready, I would be surprised if the developers would say otherwise.

The snap is unofficial, but I have as a goal this year to make that not be the case; it certainly isn’t a finished project but it’s usable for many use-cases (at least mine, and I guess a thousand other people).

1 Like

Hi I finally found the time to do this!
If I understand well the snap of caddy, should i do something like that ?

 snap set caddy config='{
	nexcloud.mydomain.me {
		reverse_proxy : 443
	}  # note here, there is no comma, not json format as asked by the documentation :/
	home-assistant.mydomain.me, home.mydomain.me {
		reverse_proxy :444
	}
}'

And that’s all ?

If yes, I suppose from nextcloud configurations, nothing to change, and from HomeAssistant i should set up the new port ?
If no, please help !


(I want this thread to be the most explicit as possible as the question to reverse proxy on Ubuntu Core itself without any host layer like vm and others, is quite empty on the internets)

Close. You’ve provided the Caddyfile syntax, which is a sort of json-like. However, Caddy can understand json. So the caddy snap uses the json directly.

What this means in practice is that your caddy config value will be a bit more complicated…

dilyn-corner@mnemosyne:~$ snap get -d caddy
{
	"config": {
		"apps": {
			"dynamic_dns": {
				"dns_provider": {
					"api_key": "xxx",
					"api_secret_key": "xxx",
					"name": "porkbun"
				},
				"domains": {
					"dilyn.cc": [
						"@",
						"www"
					],
					"git.dilyn.cc": [
						"@",
						"www"
					]
				},
				"ip_sources": [
...
}

My config exposes a gitea instance hosted on the Ubuntu Core device (via the gitea snap) on port 3001 to the outside world at git.dilyn.cc, a subdomain of my domain:

								"match": [
									{
										"host": [
											"git.dilyn.cc"
										]
									}
								],
								"terminal": true
							},
							{
								"handle": [
									{
										"handler": "subroute",
										"routes": [
											{
												"handle": [
													{
														"handler": "reverse_proxy",
														"upstreams": [
															{
																"dial": "localhost:3001"
															}
														]
													}
												]
											}
										]
									}
								],

Syntactically, this is a mess to generate. My entire config is over 200 lines. But I do have the config set as a default in my gadget snap so I can freely redeploy with no worries.

All of that is to really say: you need to use json in the config value (and the usage guides in the project readme offer a brief example).

But! Caddy makes this easy. If you provide caddy a Caddyfile, it can convert it to json for you:

sudo caddy adapt --config Caddyfile

Caddy can even do the helpful thing for you. Converting your example, I get this:

dilyn-corner@mnemosyne:/var/snap/caddy/common$ sudo caddy adapt --config i
+ id -u
+ [ 0 = 0 ]
+ _caddy=/snap/caddy/671/usr/bin/caddy
+ snapctl get modified
+ [  = true ]
+ cli adapt --config i
+ arg=adapt
+ shift 1
+ /snap/caddy/671/usr/bin/caddy adapt --config i
{"apps":{"http":{"servers":{"srv0":{"listen":[":443"],"routes":[{"match":[{"host":["home-assistant.mydomain.me","home.mydomain.me"]}],"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":":444"}]}]}]}],"terminal":true},{"match":[{"host":["nexcloud.mydomain.me"]}],"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":":80"},{"dial":"443:80"}]}]}]}],"terminal":true}]}}}}}
2026/05/18 16:24:33.727	WARN	caddyfile	Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies	{"file": "i", "line": 3}
dilyn-corner@mnemosyne:/var/snap/caddy/common$ sudo caddy fmt --overwrite --config i
+ id -u
+ [ 0 = 0 ]
+ _caddy=/snap/caddy/671/usr/bin/caddy
+ snapctl get modified
+ [  = true ]
+ cli fmt --overwrite --config i
+ arg=fmt
+ shift 1
+ /snap/caddy/671/usr/bin/caddy fmt --overwrite --config i
dilyn-corner@mnemosyne:/var/snap/caddy/common$ cat i
nexcloud.mydomain.me {
	reverse_proxy : 443
}

# note here, there is no comma, not json format as asked by the documentation :/
home-assistant.mydomain.me, home.mydomain.me {
	reverse_proxy :444
}
dilyn-corner@mnemosyne:/var/snap/caddy/common$ sudo caddy adapt --config i          
+ id -u
+ [ 0 = 0 ]
+ _caddy=/snap/caddy/671/usr/bin/caddy
+ snapctl get modified
+ [  = true ]
+ cli adapt --config i
+ arg=adapt
+ shift 1
+ /snap/caddy/671/usr/bin/caddy adapt --config i
{"apps":{"http":{"servers":{"srv0":{"listen":[":443"],"routes":[{"match":[{"host":["home-assistant.mydomain.me","home.mydomain.me"]}],"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":":444"}]}]}]}],"terminal":true},{"match":[{"host":["nexcloud.mydomain.me"]}],"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":":80"},{"dial":"443:80"}]}]}]}],"terminal":true}]}}}}}
dilyn-corner@mnemosyne:/var/snap/caddy/common$ 

eta: oh, I see I had already added this suggestion to the Tip at the end of the project README! Nifty. Nice thinking, past Dilyn.

1 Like

I think I start understanding why the internets are empty about what I’m trying to do…
The Home Assistant Snap does not provide the Supervisor store, means you can install integrator, but not apps, and for example, let’s encrypt is an app, so it’s be like: do it yourself :cry:

I can say, with the experience I have to run Nextcloud on Ubuntu Core for years, the job is amazing, user experience awesome… When you try another snap (like HA), you see how far they[Nextcloud] went.

I did not want to have 42 home servers/box/iot devices, but now I’m thinking about it…
Maybe Ill use caddy to redirect Motion Eye or my own blog, and put Home Assistant somewhere else ?