Serve multiple domains on a single instance #94

Open
opened 2018-06-28 02:06:04 +00:00 by DanielHeath · 9 comments
DanielHeath commented 2018-06-28 02:06:04 +00:00 (Migrated from github.com)

I'd love to be able to run this for a few friends - they just have to point their DNS at my VPS.

That way, users can have a hosted option, but also keep the ability to move to another host easily / host their own in future.

I'd love to be able to run this for a few friends - they just have to point their DNS at my VPS. That way, users can have a hosted option, but also keep the ability to move to another host easily / host their own in future.
elegaanz commented 2018-09-21 17:26:14 +00:00 (Migrated from github.com)

Some ideas of how this feature could be implemented, allowing to have single blogs bound to one domain:

  • each user should have an optional custom_domain property.
  • if this property is present, use it for all URLs related to this user.
  • links like "Login" should redirect to the main domain, not the custom one.
  • when visiting the user specific domain, only display their post, as if it was a single user blog.
Some ideas of how this feature could be implemented, allowing to have single blogs bound to one domain: - each user should have an optional `custom_domain` property. - if this property is present, use it for all URLs related to this user. - links like "Login" should redirect to the main domain, not the custom one. - when visiting the user specific domain, only display their post, as if it was a single user blog.
elegaanz commented 2018-12-16 15:11:10 +00:00 (Migrated from github.com)

We are currently discussing about this feature here: https://framavox.org/d/qF3vNcfw/custom-blog-domains-and-where-to-attach-them (do we really need it, and if yes, how should it be implemented?)

We are currently discussing about this feature here: https://framavox.org/d/qF3vNcfw/custom-blog-domains-and-where-to-attach-them (do we really need it, and if yes, how should it be implemented?)
igalic commented 2018-12-30 18:03:12 +00:00 (Migrated from github.com)

i'll try to summarize the outcome of the discussion

× instance blog author
domain always same same
custom_domain No Yes No
URLs https://blog.eena.me/ https://blog.eena.me/~/words/ https://blog.eena.me/@/meena
https://blog.eena.me/~/thoughts/
Custom URL × https://words.eena.me/ ×
× https://thoughts.eena.me/ ×

to piece together a better idea on how to implement it.

i'll try to summarize the outcome of the discussion × | instance | blog | author -- | -- | -- | -- | *domain* | always | same | same | *custom_domain* | No | Yes | No | *URLs* | https://blog.eena.me/ | https://blog.eena.me/~/words/ | https://blog.eena.me/@/meena | | | https://blog.eena.me/~/thoughts/ | | | *Custom URL* | × | https://words.eena.me/ | × | | × | https://thoughts.eena.me/ | × to piece together a better idea on how to implement it.
elegaanz commented 2019-02-13 21:19:40 +00:00 (Migrated from github.com)

So, to summarize what we have here. We want to add an option to have custom domains for blogs (not users or anything else). In the database this will be materialized by a new nullable/optional custom_domain field on blogs or something like that.

A question that we still need to discuss, and that will have a quite big impact on how this feature is implemented: do we allow only sub-domains of the main domain, only totally custom domains (owned by the same person as the blog), or both? In the first case, most of the configuration will be done by the instance admin: they will have to redirect all subdomains (is it possible to use wildcards in DNS records, or will them have to add each domain manually (which would make this feature far less interesting in my opinion)?) to the correct IP, and configure their reverse-proxy to make the communication between these domains and Plume. In the second case, it will be bloggers' job to configure the DNS, but what about the reverse-proxy? What we allow will also have an impact on the UI to configure custom domains (in one case, you just check something and you are assigned a custom domain, in the other you have to tell Plume what your domain is).

Independently of what of domains we allow, it means that Plume will have to act a little bit like a reverse proxy itself, displaying different pages depending on the domain. To make it easier to implement this feature, I think we should only display a few pages (the homepage with the blog details and the page to read an article basically) under the custom domain. To know if the current route should be interpreted in a general context, or as a custom domain route, I think implementing a request guard that returns the Host header if it is different from BASE_URL could help. This way you could do:

#[get("/")]
pub fn homepage(host: Option<Host>) -> String {
    if let Some(domain) = host {
        format!("Welcome on the {} custom domain", domain.to_string())
    } else {
        String::from("Normal homepage")
    }
}

// or even better
#[get("/", rank = 1)]
pub fn custom_homepage(host: Host) -> String {
    format!("Welcome on the {} custom domain", host.to_string())
}

#[get("/", rank = 2)]
pub fn homepage() -> String {
    String::from("Normal homepage")
}

We should also prefix URLs so that they correctly redirect to the custom domain if it exists, or to the main instance for pages that are not available on custom domains, like login or user profiles. A simple function can probably do that:

fn url(blog: Blog, blog_url: Uri, normal_url: Uri) -> String {
    format!(
        "https://{}{}",
        blog.custom_domain.unwrap_or(BASE_URL),
        if blog.custom_domain.is_some() {
            blog_uri
        } else {
            normal_uri
        }
    )
}

url(blog_that_may_have_a_custom_domain, uri!(post::details_custom_domain, ...), uri!(post::details, ...))

I hope this helps. If something is still not clear, tell me.

So, to summarize what we have here. We want to add an option to have custom domains for **blogs** (not users or anything else). In the database this will be materialized by a new nullable/optional `custom_domain` field on `blogs` or something like that. A question that we still need to discuss, and that will have a quite big impact on how this feature is implemented: do we allow only sub-domains of the main domain, only totally custom domains (owned by the same person as the blog), or both? In the first case, most of the configuration will be done by the instance admin: they will have to redirect all subdomains (is it possible to use wildcards in DNS records, or will them have to add each domain manually (which would make this feature far less interesting in my opinion)?) to the correct IP, and configure their reverse-proxy to make the communication between these domains and Plume. In the second case, it will be bloggers' job to configure the DNS, but what about the reverse-proxy? What we allow will also have an impact on the UI to configure custom domains (in one case, you just check something and you are assigned a custom domain, in the other you have to tell Plume what your domain is). Independently of what of domains we allow, it means that Plume will have to act a little bit like a reverse proxy itself, displaying different pages depending on the domain. To make it easier to implement this feature, I think we should only display a few pages (the homepage with the blog details and the page to read an article basically) under the custom domain. To know if the current route should be interpreted in a general context, or as a custom domain route, I think implementing a request guard that returns the `Host` header if it is different from `BASE_URL` could help. This way you could do: ```rust #[get("/")] pub fn homepage(host: Option<Host>) -> String { if let Some(domain) = host { format!("Welcome on the {} custom domain", domain.to_string()) } else { String::from("Normal homepage") } } // or even better #[get("/", rank = 1)] pub fn custom_homepage(host: Host) -> String { format!("Welcome on the {} custom domain", host.to_string()) } #[get("/", rank = 2)] pub fn homepage() -> String { String::from("Normal homepage") } ``` We should also prefix URLs so that they correctly redirect to the custom domain if it exists, or to the main instance for pages that are not available on custom domains, like login or user profiles. A simple function can probably do that: ```rust fn url(blog: Blog, blog_url: Uri, normal_url: Uri) -> String { format!( "https://{}{}", blog.custom_domain.unwrap_or(BASE_URL), if blog.custom_domain.is_some() { blog_uri } else { normal_uri } ) } url(blog_that_may_have_a_custom_domain, uri!(post::details_custom_domain, ...), uri!(post::details, ...)) ``` I hope this helps. If something is still not clear, tell me.
igalic commented 2019-02-13 23:33:28 +00:00 (Migrated from github.com)

In the first case, most of the configuration will be done by the instance admin: they will have to redirect all subdomains (is it possible to use wildcards in DNS records, or will them have to add each domain manually (which would make this feature far less interesting in my opinion)?) to the correct IP, and configure their reverse-proxy to make the communication between these domains and Plume.

yes, wildcard DNS configs are a thing

In the second case, it will be bloggers' job to configure the DNS, but what about the reverse-proxy?

it means that the user of the blog will have to work in concert with the admin of the blog, to have the ServerAlias, and the Subject Alternative Name updated

What we allow will also have an impact on the UI to configure custom domains (in one case, you just check something and you are assigned a custom domain, in the other you have to tell Plume what your domain is).

could Plume check if the config is correct before trying to serve?

To know if the current route should be interpreted in a general context, or as a custom domain route, I think implementing a request guard that returns the Host header if it is different from BASE_URL could help.

👍

> In the first case, most of the configuration will be done by the instance admin: they will have to redirect all subdomains (is it possible to use wildcards in DNS records, or will them have to add each domain manually (which would make this feature far less interesting in my opinion)?) to the correct IP, and configure their reverse-proxy to make the communication between these domains and Plume. yes, wildcard DNS configs are a thing > In the second case, it will be bloggers' job to configure the DNS, but what about the reverse-proxy? it means that the user of the blog will have to work in concert with the admin of the blog, to have the `ServerAlias`, and the `Subject Alternative Name` updated > What we allow will also have an impact on the UI to configure custom domains (in one case, you just check something and you are assigned a custom domain, in the other you have to tell Plume what your domain is). could Plume check if the config is correct before trying to serve? > To know if the current route should be interpreted in a general context, or as a custom domain route, I think implementing a request guard that returns the `Host` header if it is different from `BASE_URL` could help. 👍
elegaanz commented 2019-02-14 07:08:44 +00:00 (Migrated from github.com)

yes, wildcard DNS configs are a thing

Great!

it means that the user of the blog will have to work in concert with the admin of the blog

I would have preferred a more automated solution, but maybe it's better like that anyway.

could Plume check if the config is correct before trying to serve?

Yes, there are probably crates to resolve a domain name (maybe even in the standard library)

> yes, wildcard DNS configs are a thing Great! > it means that the user of the blog will have to work in concert with the admin of the blog I would have preferred a more automated solution, but maybe it's better like that anyway. > could Plume check if the config is correct before trying to serve? Yes, there are probably crates to resolve a domain name (maybe even in the standard library)
DanielHeath commented 2019-02-18 10:23:27 +00:00 (Migrated from github.com)

The server can use ACME / letsencrypt to get a certificate on-demand (that is, if there aren't too many new own-domain signups; there are rate limits).

The server can use ACME / letsencrypt to get a certificate on-demand (that is, if there aren't too many new own-domain signups; there are rate limits).
trwnh commented 2019-02-18 11:30:37 +00:00 (Migrated from github.com)

I think the flow most users might be accustomed to would be something similar to how Tumblr does it:

  1. create A record to 66.6.44.4 (Tumblr's IP)
  2. create CNAME record to domains.tumblr.com. (optional?)
  3. enter their domain in their blog's settings

Functionally, users should be able to point their domain name at the server IP, and Plume should handle the basic routing (via nginx?). There's no getting around users manipulating their own DNS at some point, so full automation is not possible.

Tumblr also has a "test" button to make sure the domain mapping is correct.

I think the flow most users might be accustomed to would be something similar to how Tumblr does it: 1) create A record to 66.6.44.4 (Tumblr's IP) 2) create CNAME record to domains.tumblr.com. (optional?) 3) enter their domain in their blog's settings Functionally, users should be able to point their domain name at the server IP, and Plume should handle the basic routing (via nginx?). There's no getting around users manipulating their own DNS at *some* point, so full automation is not possible. Tumblr also has a "test" button to make sure the domain mapping is correct.

Could be a more complex change and maybe I haven't considered everything...

  • instead of configure a federation domain the host header could be used? So multiple domains would be possible. Configuration should limit allowed domains?
  • one user is used to login to plume system, maybe should be the primary / first (service) domain
  • each user have flexible number of blogs / virtual users (format: <BLOG>@<CUSTOM_DOMAIN>) which are public and federated
  • Create a post just select the "sender address" as you do with multiple e-mail sender addresses?
  • blog creator is the administrative user and could add additional blog writers (create <ADDITIONAL_USER@<MY_DOMAIN> allowed to friend1@friends_domain.com) or masqueraded users like friend1@friends_domain.com is allowed to write as blog@my_domain.com...

Maybe database schema is similar to blogs of user, but I think it would be a lot of work to do?

Could be a more complex change and maybe I haven't considered everything... * instead of configure a federation domain the host header could be used? So multiple domains would be possible. Configuration should limit allowed domains? * **one user** is used to login to plume system, maybe should be the primary / first (service) domain * each user have flexible number of **blogs / virtual users** (format: `<BLOG>@<CUSTOM_DOMAIN>`) which are public and federated * Create a post just select the "sender address" as you do with multiple e-mail sender addresses? * blog creator is the administrative user and could add additional blog writers (create `<ADDITIONAL_USER@<MY_DOMAIN>` allowed to `friend1@friends_domain.com`) or masqueraded users like `friend1@friends_domain.com` is allowed to write as `blog@my_domain.com`... Maybe database schema is similar to blogs of user, but I think it would be a lot of work to do?
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Plume/Plume#94
No description provided.