Document updated on Apr 11, 2024
The Virtual Host server allows you to run different configurations of KrakenD endpoints based on the host used to access the server.
For instance, you can declare different endpoint configurations for a path /foo
that is accessed through abcd.example.com/foo
or efgh.example.com/foo
. These two could have different rate limits or authorization rules, for example.
To add virtual hosts, add the component server/virtualhost
under the service extra_config
and declare the host names that you will recognize. The hosts can be a simple list or using aliases, as depicted below:
{
"version": 3,
"extra_config": {
"server/virtualhost": {
"hosts": ["abcd.example.com", "efgh.example.com"]
}
}
}
The alias might come in handy to have uncluttered endpoint declarations:
{
"version": 3,
"extra_config": {
"server/virtualhost": {
"aliased_hosts": {
"user_api":"abcd.example.com",
"basket_api":"efgh.example.com"
}
}
}
}
You can use hosts
or aliased_hosts
, but not both simultaneously.
hosts
, or
aliased_hosts
| A map of all recognized virtual hosts where the key is the alias and the value the host name, including the port if it’s not 443 or 80. The values declared here must match the content of the Host header passed by the client. The alias must be an alphanumeric string.Example: {"user_api":"users.svc.example.com:9000"}
| ||
| All recognized virtual hosts by KrakenD must be listed here. The values declared here must match the content of the Host header when passed by the client.Example: ["api-a.example.com","api-b.example.com"] |
When you enable the virtual host plugin, KrakenD first checks the Host
header and tries to match an endpoint with the format /__virtual/{host}/path
in the configuration. For instance, if the user is accessing example.com/path
, you must declare an endpoint /__virtual/example.com/path
.
If the configuration does not have a /__virtual/
endpoint with the requested example.com
host, the gateway resolves to the default endpoint /path
if it exists or returns a 404
otherwise.
You can also create an endpoint for all the recognized virtual hosts using a variable like this: /__virtual/{host}/path
, and unrecognized hosts will fall into /path
.
You can use an alias (using aliased_hosts
) to declare virtual endpoints easily instead of using the full domain name. E.g., instead of /__virtual/example.com:9000/path
, you could write /__virtual/domain1/path
.
Given the following extra_config
configuration:
{
"extra_config": {
"server/virtualhost": {
"hosts": [
"host-a.example.com",
"host-b.example.com"
]
}
}
}
And the following endpoints
:
{
"version": 3,
"endpoints": [
{
"endpoint": "/foo",
"backend": [
{
"url_pattern": "/__debug/no-host",
"host": ["http://localhost:8080"]
}
]
},
{
"endpoint": "/__virtual/host-a.example.com/foo",
"backend": [
{
"url_pattern": "/__debug/host-A",
"host": ["http://localhost:8080"]
}
]
},
{
"endpoint": "/__virtual/host-b.example.com/foo",
"backend": [
{
"url_pattern": "/__debug/host-B",
"host": ["http://localhost:8080"]
}
]
}
]
}
You can check how /foo
hits different endpoints in the following order:
curl -i -H 'Host: anything' http://localhost:8080/foo
: No rewriting placed as host
is unknown. Hits the first endpoint.curl -i -H 'Host: host-a.example.com' http://localhost:8080/foo
: Hits the second endpointcurl -i -H 'Host: host-b.example.com' http://localhost:8080/foo
: Hits the third endpointSometimes, you expose the API on a non-default port (different from 80
and 443
). In these cases, the Host
header comes with the port, for instance, Host: example.com:1234
. When the header contains the port, you must add it as a different entry in the virtual host configuration and the endpoint definition. If the same hostname (e.g., example.com
) uses different ports, you must use aliased_hosts
; otherwise, the gateway will panic during startup.
The following example supports Host
headers with values Host: example.com:1234
and Host: example.com
. Notice that it makes use of aliased_hosts
:
{
"$schema": "https://www.krakend.io/schema/v2.6/krakend.json",
"version": 3,
"echo_endpoint": true,
"host": ["http://localhost:8080"],
"extra_config": {
"server/virtualhost": {
"aliased_hosts": {
"example": "example.com",
"example1234": "example.com:1234"
}
}
},
"endpoints": [
{
"endpoint": "/default",
"backend": [{
"url_pattern": "/__echo/any-non-matching-host",
"allow": ["req_uri"]
}]
},
{
"endpoint": "/__virtual/example/default",
"backend": [{
"url_pattern": "/__echo/virtualhost-without-port",
"allow": ["req_uri"]
}]
},
{
"endpoint": "/__virtual/example1234/default",
"backend": [{
"url_pattern": "/__echo/virtualhost-with-port",
"allow": ["req_uri"]
}]
}
]
}
If you used the static plugin before EE v2.4, eliminate now all entries referring to plugins. This means:
plugin
entry in the root level.plugin/http-server
objects if they only use the static-filesystemvirtualhost
object in the configurationThis can be summarized with a diff as:
"version": 3,
- "plugin": {
- "pattern":".so",
- "folder": "/opt/krakend/plugins/"
- },
"extra_config": {
- "plugin/http-server": {
- "name": ["virtualhost"],
- "virtualhost": {
+ "server/virtualhost": {
For instance, if you had this configuration:
{
"version": 3,
"plugin": {
"pattern":".so",
"folder": "/opt/krakend/plugins/"
},
"extra_config": {
"plugin/http-server": {
"name": ["virtualhost", "some-other-plugin" ],
"virtualhost": {
"hosts": ["host-a.tld", "host-b.tld"]
}
}
}
}
This now becomes:
{
"version": 3,
"extra_config": {
"server/virtualhost": {
"hosts": ["host-a.tld", "host-b.tld"]
}
}
}
No additional changes are required in the endpoints.
The documentation is only a piece of the help you can get! Whether you are looking for Open Source or Enterprise support, see more support channels that can help you.