Using Caddy to create Virtual Hosts for your Multi-Domain Names as a Reverse-Proxy from a single server
While this particular technique should work on the internet, personally this article is for:-
- Making it work on a permanently air-gapped network
- Reverse Proxy without root privilige
- Installing without root privilige
- Single Domain but Reverse-Proxying to different servers
Advantages
- Host multiple domains from the same server
- Reverse Proxy to Multiple Domains hosted on different servers
- Reverse Proxy to Multiple Domains based on path provided
- Internal servers hosting our items need not be made public or even be accessible from the user’s machines.
- Host API and Server on different machines or ports but based on URI routes make it look like they are being hosted on the same server
This could be by having a ui.company domain hosting the UI on localhost:8989 whil ui.company/api hosting the internal API server on 127.0.0.1:8787 - Do it using easy to read and understand Caddyfile.
- Do it securely without root unless you need to access priviliged ports
What is a Virtual Host?
- Traditional idea regarding domains and DNS is that a domain maps to an IP
- The HTTP and HTTPs protocol traditionally operate on priviliged port 80 and 443 respectively
- Hence, each and every domain needs to be hosted on a separate IP and machine
- Okay Point 3 is wrong
- Thanks to virtual hosts, we can do without that requirement by making our Caddyfile host all our domains on 1 IP itself
Installing
For me Caddy was pretty easy to install. All you really need to do is go here and download the Caddy release for your platform and extract it.
Simple Virtual Hosts Caddyfile
http://code.internal:8080 {
# Could be another domain/IP as well
reverse_proxy {
to localhost:8081
}
}
http://stage.internal:8080 {
# Could be another domain/IP as well
reverse_proxy 127.0.0.1:8082
}
http://dev.internal:8080 {
# Proxy with a DNS Server name instead
reverse_proxy internal-site:8083
}
No server setup for this kind of task would be complete without showcasing a way to host static files (to kinda make it easier to showcase the power of Caddy)
http://site.internal:8080 {
root * /home/caddy_test/internalweb
file_server
}
Using Curl to Validate
curl --resolve dev.internal:8080:127.0.0.1 http://dev.internal:8080
Using Domains within Paths
You are probably thinking something like this would work:-
http://web.internal:8080 {
handle /code/* {
# Could be another domain/IP as well
reverse_proxy {
to localhost:8081
}
}
}
Nooo
If we use that approach then what we end up is a good old 404
The reason must be pretty obvious. Caddy currently redirects our code to localhost:8081/code/index.html which does not exist.
As we wish to redirect it to localhost:8081/index.html, instead of modifying our entire server to suit our requirements,
http://web.internal:8080 {
handle /code/* {
# Could be another domain/IP as well
uri strip_prefix /code/
reverse_proxy {
to localhost:8081
}
}
}
This leads to all the URLS prefixed with web.internal:8080/code to be redirected to localhost:8081