Guides and API documentation to get you up and running.
Approximated helps you connect web domains to your application(s). These are often called custom domains when provided by your users.
This is accomplished by relaying internet traffic to your app(s) and back again for each domain that you configure, using a gloablly distributed set of machines called a Proxy Cluster. This Proxy Cluster also provides and manages SSL certificates for each domain it's responsible for.
Approximated's Proxy Clusters are groups of machines distributed globally that serve traffic for you. When you create one in Approximated, these machines are set aside and dedicated to you, along with your own dedicated IPv4 address.
You can create Virtual Hosts on your Proxy Cluster to tell it which domains to accept traffic from, and where to send it. You can have as many Proxy Clusters as you need, and each one can scale to as many custom domains as you want.
Virtual hosts are entities that you create in Approximated. They tell Approximated how to route requests for custom domains. Each virtual host has an incoming address field that matches the custom domain you want to route. It also has a target address field that tells Approximated where to send requests for that custom domain.
Every custom domain you want to connect needs to be pointed with DNS at your Approximated proxy cluster, so that it can route them for you. This can be done with an A record pointed at your cluster's IPv4 address, or through an intermediary domain/subdomain with a CNAME record.
If a DNS record is pointed at your cluster without a matching virtual host, it will be ignored so that you control what custom domains are routed by your cluster.
Approximated requires an private API key to accept API requests from your application. This API key should never be made public or added to client-side javascript code.
You can create or get an existing API key from the dashboard, and add it to all API requests under the request header "api-key".
The virtual hosts API is how your application will interface directly with Approximated. You can use it to automate custom domains as needed. There are four endpoints to create, read, update, and delete a virtual host.
Note:
Make sure that you include headers for
Content-Type and Accept set to 'application/json' for all requests to the API.
Creating a virtual host is done with a JSON POST request to the Approximated API. It can be created at any time before or after the custom domain is pointed at the cluster with a DNS record.
{ "data": { "id": 445922, "incoming_address": "acustomdomain.com", "target_address": "myapp.com", "target_ports": "443", "user_message": "In order to connect your domain, you'll need to have a DNS A record that points acustomdomain.com at 213.188.210.168. If you already have an A record for that address, please change it to point at 213.188.210.168 and remove any other A records for that exact address. It may take a few minutes for your SSL certificate to take effect once you've pointed your DNS A record." } }
The custom domain that you'd like to route.
The address that you'd like requests for the custom domain to be routed to. Typically another domain or domain with a sub-page.
This sets the port that you'd like requests to arrive at on the target address. By default it is port 443 as that is the port that web traffic secured by SSL is typically served from.
Set this to true if you'd like to have requests be 301 redirected to the target address instead of proxied.
Note: redirects need to have the protocol (http:// or https://) included in the target_address, or they will be appended to the incoming address.
Set this to true if you'd like to have requests that exactly match the incoming address, including paths, be overridden and routed somewhere specific. Typically this is used in combination with another virtual host configured for the base custom domain.
Note: this will ignore any extra user-added paths or queries if it matches, and will override any other virtual hosts for the same domain that don't exactly match.
For convenience, when set to true, Approximated will create a second virtual host as well that will 301 redirect the www version of the incoming address to this address.
Use a GET request with the incoming_address at the end of the URL to retrieve the details of a single Virtual Host. If that Virtual Host was created with the API Key included in the header, it's details will be returned.
{ "data": { "apx_hit": true, // requests are reaching the cluster "created_at": "2023-04-03T17:59:28", // UTC timezone "dns_pointed_at": "213.188.210.168", // DNS for the incoming_address "has_ssl": true, "id": 405455, "incoming_address": "acustomdomain.com", "is_resolving": true, // is this returning a response "last_monitored_humanized": "1 hour ago", "last_monitored_unix": 1687194590, "ssl_active_from": "2023-06-02T20:19:15", // UTC timezone "ssl_active_until": "2023-08-31T20:19:14", // UTC timezone, auto-renews "status": "ACTIVE_SSL", "status_message": "Active with SSL", "target_address": "myapp.com", "target_ports": "443" } }
Updating a virtual host is done with a JSON POST request to the Approximated API. It can be updated at any time before or after the custom domain is pointed at the cluster with a DNS record. Any optional fields not submitted will remain the same as they were previously.
{ "data": { "apx_hit": true, // requests are reaching the cluster "created_at": "2023-04-03T17:59:28", // UTC timezone "dns_pointed_at": "213.188.210.168", // DNS for the incoming_address "has_ssl": true, "id": 405455, "incoming_address": "adifferentcustomdomain.com", "is_resolving": true, // is this returning a response "last_monitored_humanized": "1 hour ago", "last_monitored_unix": 1687194590, "ssl_active_from": "2023-06-02T20:19:15", // UTC timezone "ssl_active_until": "2023-08-31T20:19:14", // UTC timezone, auto-renews "status": "ACTIVE_SSL", "status_message": "Active with SSL", "target_address": "myapp.com", "target_ports": "443" } }
The custom domain for an existing Virtual Host.
A new custom domain you would like to change the existing Virtual Host to.
The address that you'd like requests for the custom domain to be routed to. Typically another domain or domain with a sub-page.
This sets the port that you'd like requests to arrive at on the target address. By default it is port 443 as that is the port that web traffic secured by SSL is typically served from.
Set this to true if you'd like to have requests be 301 redirected to the target address instead of proxied.
Note: redirects need to have the protocol (http:// or https://) included in the target_address, or they will be appended to the incoming address.
Set this to true if you'd like to have requests that exactly match the incoming address, including paths, be overridden and routed somewhere specific. Typically this is used in combination with another virtual host configured for the base custom domain.
Note: this will ignore any extra user-added paths or queries if it matches, and will override any other virtual hosts for the same domain that don't exactly match.
For convenience, when set to true, Approximated will create a second virtual host as well that will 301 redirect the www version of the incoming address to this address.
Use a DELETE request with the incoming_address at the end of the URL to remove a single Virtual Host.
Deleting customdomain.com
When a request for a custom domain reaches your application, you likely want to return content specific to that custom domain. For example, if your app hosts blogs, the custom domain should return content for that particular blog.
Depending on how your application works, you may need to make some changes to your code base. Below are some of the more common scenarios.
With statically generated content, you probably have folders and files sitting on a server for each custom domain. For example, a request to mybloghost.com/some-blog will load the content directly from the /some-blog folder on your server.
In this situation, there's probably no code being run before that content is loaded directly from the files. You might have caching, but the end result is the same.
For statically generated sites, the easiest way to integrate custom domains is likely to target that user's folder URL directly. With Approximated, you can accomplish this by adding a path to your virtual host target address field.
For example:
someblog.com
https://mybloghost.com/some-blog
* Note the https://
in the target address is required when using a path
There are some obstacles to this approach, however:
All paths that are appended to to the custom domain will also be appended to the end of the target, which may cause issues in some cases.
incoming_address:
someblog.comtarget_address:
https://mybloghost.com/some-blog
someblog.com/some-blog/some-post
https://mybloghost.com/some-blog/some-post
someblog.com
https://mybloghost.com/some-blog
someblog.com/assets/app.css
https://mybloghost.com/some-blog/assets/app.css
If your application is using shared assets like app.css or app.js for all custom domains, then your code is probably expecting to find them at:
mybloghost.com/assets/app.css
mybloghost.com/some-blog/assets.app.css
In that case, this URL will 404 on the custom domain because app.css is not located there.
Set URLs for things like assets to be absolute in the generated HTML code.
For example:
href="https://mybloghost.com/assets/app.css"
Instead of:
href="/assets/app.css"
Note: you may run into CORS policy issues with this approach. See below for more information.
If you make a request to your main app, for instance to get assets, you may get a CORS error if you have a CORS policy restricting other domains.
someblog.com
mybloghost.com
<link rel="stylesheet" href="https://mybloghost.com/assets/app.css" />
Allow all origins in your CORS policy for those URLs by setting it to the wildcard "*".
Note: this could have security implications for your application, please consider how loading this content on other domains might impact you first.
Provide those assets relative to your custom domain as well, either by generating them in each user folder or symlinking.
Use a CDN for assets that will allow your custom domains with CORS.
Laravel is one of the best frameworks out there, and can easily use custom domains with Approximated. The best way to learn how to integrate Approximated with your Laravel app is to look at our Laravel custom domains example repo.
That repo is a working example that demonstrates setting a custom domain for a user, routing and middleware for custom domains, and custom domain specific controllers/content.
Ruby on Rails makes integrating with Approximated easy. The best way to learn how to integrate Approximated with your Rails app is to look at our Ruby on Rails custom domains example repo.
That repo is a working example that demonstrates creating pages that can be tied to a custom domain, the routing required, and a class that interfaces with the Approximated API for you.
Apps using Elixir's Phoenix framework can integrate with Approximated easily, including websockets for liveview. We've created an example repo here for you to explore, so that you can see for yourself with a working example.
The example repo is a simple blog hosting platform, where you can create blogs and tie them to a custom domain. It should serve as a reference for how your Phoenix app can handle routing, liveviews/websockets, security features, and more for custom domains.