Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serve multiple domains on a single instance #94

Open
DanielHeath opened this issue Jun 28, 2018 · 8 comments
Open

Serve multiple domains on a single instance #94

DanielHeath opened this issue Jun 28, 2018 · 8 comments
Labels
C: Feature This is a new feature
Milestone

Comments

@DanielHeath
Copy link

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 elegaanz added C: Feature This is a new feature P: Medium labels Jun 28, 2018
@elegaanz
Copy link
Member

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
Copy link
Member

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
Copy link
Contributor

igalic commented Dec 30, 2018

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
Copy link
Member

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.

@igalic
Copy link
Contributor

igalic commented Feb 13, 2019

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
Copy link
Member

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
Copy link
Author

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
Copy link

trwnh commented Feb 18, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: Feature This is a new feature
Projects
None yet
Development

No branches or pull requests

4 participants