#55 Subdomain Multitenancy with Ernest Addae

24/09/2021
  • Warming up
  • Start

Watch Ernest Addae create and troubleshoot an application with Subdomain Multitenancy (like shop1.domain.com, shop2.domain.com).

At the end we discuss how to make it work in production with Heroku and SSL.

Second episode with some improvements and deployment to Heroku coming soon, so stay tuned!
Ernest Addae on Twitter: https://twitter.com/Earnaddae

2023 update: we never managed to meet up and record a QUALITY part 2 :(

0:00 Warming up
2:29 Start

create accounts:
https://github.com/corsego/55-subdomain-multitenancy/commit/724bdb88aa4d36c1e2c7a3311eeabb3fce9c0c24
seed accounts:
https://github.com/corsego/55-subdomain-multitenancy/commit/74da6ca2ea6a1155cd04846775d4865ff4923dc8
redirect to subdomain:
https://github.com/corsego/55-subdomain-multitenancy/commit/40040db2f06ca957b29c1a775fa64e6047b0fbb1
accounts module:
https://github.com/corsego/55-subdomain-multitenancy/commit/83eac1f04a91c3b1345e70c456118bceba233b86
scaffold posts:
https://github.com/corsego/55-subdomain-multitenancy/commit/1dca224f136e159797e560d3d06b18da72e1a636
account has many posts:
https://github.com/corsego/55-subdomain-multitenancy/commit/d50cf25f7bfbde6a7a6d3db934e7b9a6a64a7c33
Scoping Posts to Accounts module:
https://github.com/corsego/55-subdomain-multitenancy/commit/1827725e15d779644e0d114cf261dbfc2b777538
Constraints:
https://github.com/corsego/55-subdomain-multitenancy/commit/906c766118c954577f9f1079f5cc06e08d14ea41
Better seeds:
https://github.com/corsego/55-subdomain-multitenancy/commit/bec196da6c1c191545c3b38d04ed3f902ba84abd
Readme for LetsEncrypt SSL with Heroku production:
https://github.com/corsego/55-subdomain-multitenancy/commit/10e889eb16db68a87d5ae19ce21b954f6e5083bc

Transcript
Yeah, because, uh, from like all the rails implementations of subdomains, uh, I liked yours, uh, the best. I was, uh, really surprised, like it broke really smoothly. So I'll create a new app so that we can work, we can work from it from scratch rather than trying to go through an existing app, several moving parts and stuff like that. Yeah, definitely. Yeah. Hmm. Usually create an, a new rail six app is, uh, like five times longer than create, uh, rails, uh, five new application. Yes, it's true. And, and, and the, the, the fact also the app becomes, already, the app becomes already big, you know, like the size is very big, but I, I tried, so I tried Hanami when they announced the version two launch. Mm-hmm. I think it's, it's pretty cool. It's pretty cool. But it is just that everyone is so much addicted to reels that, uh, is difficult. It's quite difficult. Okay. So I opening a text editor. Okay. So let's see if everything works. Oh, wait, sorry about that. I, I remember I use, I'm using Postgre, so as usual, I have to set it up before, and then let's see if we are on course. Okay. It seems everything is set. Okay. So, uh, so let's say you, uh, I think the whole, the whole premise of uh, a multi-tenant tenancy app is to have a main account, uh, whereby you scope all your resources into that account, right? I mean, that is the idea. Or you can use the apartment gym approach, which I find very difficult and I don't even understand. So I'll not even go there. But, uh, the one that you can use ask as tenants or try to scope tenants, uh, I find it quite the best approach in doing things. So let me start by, lemme generating an account. Okay. Well, I mean, the approach where you have just one database is, uh, always, uh, much, uh, more plea than having different schemas or different databases for each tenant. Yes, yes. Uh, I think that is, uh, I mean, if, uh, like you are running a giant business that has billions of records, uh, maybe it makes sense to use, uh, something like, uh, apartment jam and user separate, uh, schemas and, uh, yeah. Yeah. But the, the downside is scoping each one of them by using the, has many relationship is just that, uh, the downside is you always have to remember that whatever new resources you are creating, you have to scope it to account, sort of. Yeah. I think that's the only thing. So let me create my, uh, the root route. I start the server, I make sure that we are in the roots. Uh, our homepage is the same as as we are so that we can go on. Okay, so normally you create a new account. Yeah. So basically, is this right? So the, normally this is the normal route that we go about it, but now we want an account to have sort of like a subdomain so that when we create an account, we will go to a subdomain and assess the, uh, the account. So, uh, how we, how I did it is by having a subdomain first, right? So that we can use the subdomain as the approach in, uh, as the way of scoping each of the resources we have in the account. So, how I went about it is to first create a, a subdomain. So I, I dunno. Yeah. This is better. Yes. So let me create a subdomain, right? So now we know that we have the sub domain. I'll go to my controllers and then make sure I allow the subdomain, and then I'll make sure I have it also in my, my phone. Okay. So now, now that I have it set up, all I have to do is to go to my controller. And whenever I create, um, whenever I create a new account, I will rather redirect to root URL, but I want to be, uh, cumbersome of the subdomain. Mm-hmm. So I have to do the account and then tell them that, okay, whenever you are doing it, I want you to go to the subdomain as well for me. So when I create an account and it's alright, it's come to the subdomain, and if I not, it's not, so the request, the reels request will, when I create it, we'll just route the request to, uh, that, uh, that subdomain for me. So I will against that server, Uh, you have direct two device in your controller, the version? Yes. Yes. Uh, come again. Uh, you have the vote redirect two, twice in line 28. Yeah. Oh, yes. Thank you. Thank you. Yeah. So redirect to the root route, and then I'll go, I'll choose the subdomain, and I want to go to the of that. So I will come to my app now. So now when I create a new account, uh, another and I go to another, it'll redirect me to the subdomain. So you can see the route. Mm-hmm. Yeah. It has moved from the account, the sub domain name I gave, and then the local host and stuff. But usually developing this on local host, this should work. All right. But the problem I discovered is that even though everything worked in the development environment, when I did it this way, um, when I went to production, I had a little pain with that. So I relent that you can actually use L vh me, something of that, of this. Mm-hmm. Because serve as a subdomain already, because we have L vh me already. So this one is seven at the root domain, so we can add your, uh, subdomain to it. So I just go to, um, then go to app, uh, config application, rb mm-hmm. And whitelist. Yeah. And then whitelist. So normally, uh, I whitelist list this, or I would just set it to nil so that I wouldn't have to be updating the route. Anytime I try to, uh, start a new, uh, I try to go to a new route. So with it, I'll start server again, and then when I go to LVH 3000, the link is available for me there, so mm-hmm. When I create a new account. So just reroute that. So here, this is more representative, so I get my sub domain name, my name, and then the this one. So with this one, what I realized when I did it this way, uh, it worked in production as well as in development. So I learned that the L vh me is actually a pseudo for Looker, who's 3000. Mm-hmm. Yeah. So if, if it's an S to local, who's 3000. So I've heard it's a dn, it's a DNS labeled to local who's 3000. So I, I, I must mention that this is very, very important else, everything working local in development, but then when we go to production, everything is something else. Hmm. Okay. So now that we have the subdomain here, we have to consider another thing, because at the end of the day, our app has to be scoped to a particular resource. So let's say we have, uh, like a post or so whatsoever, right? So let me quickly just say we have a post for each of the, uh, a post for each, uh, or account to have many posts, right? So we can generate the reals, uh, scaffold, uh, lemme call it post has a name And it, and it to an account. Yes. Yes. Oh, yeah. Okay. So now I have it this way. So I can go to my, I'll go to the model account and then pass many posts just in case, and then a post will belong to an account. Right. Okay. I think I forgot something to to mention here. Uh, that we have to make the Yeah, well, they domain Definitely. Yeah. Yeah. So, so now we don't end up generating well, south domain that we showed. Okay. So now on this is set up. Now we know that, um, a post will eventually have many, uh, uh, an account will have many posts and a post will belong to, uh, an account. But then we also want to make sure that once we go into a post, we can have the resources that we want, because we don't always have to be generating the post. So we need a way to make the subdomain be required. Which one that we can click a link and then we can go to the subdomain, right? So we need to set, uh, occurrence, a helper method to track the subdomain for us. Mm-hmm. So, because when we will have, let's say you can have several accounts, but when you click on each account, you want to go to a subdomain of that account that is actually pretty much unique to you. Right? So to do that, I normally, I try to set a base, I don't like using authorization like punit and can, can can match. So I normally try to develop a base, a base controller, and I make my key controller inherit from those base controllers. So, but yeah. But, but anyway, but for the, for simplicity's sake, I think I can, um, let's define our route into, uh, in the application controller so that we can control all. So, um, I generate the help permit the like, parent account, and then I'll minimize is to, uh, account find by, I want to find by the subdomain. So whenever you make the request, I want the request to be routed through the subdomain, and I want it to be a help method as well. Hmm. So with this case, what I do that once I list all the accounts that are available, if I want to find a specific account, I can just quickly go to the subdomain of that account, and then I'll just find it so that I wouldn't have to be declaring it, uh, anywhere that I go. This exactly. Am I making, am I making sense? Yeah, yeah, definitely. Oh, okay. Okay. Okay. Wow. Okay. So now, now, uh, now that we have the accounts set up, we need to be able to scope it. We need to scope the, we need to scope the account so that each resource can go into, uh, each, uh, account. So I use the real scoping. So I scope the module count, and then I try to put the resources in there. Okay. So, for instance, I can make, let's say I can declare the beauty of having scope is that I can be, I cannot declare two root routes for myself as well. So I can say that root route of the subdomain, uh, can route to, let's say, post, uh, index, uh, this way, right? So I can now have, uh, two, uh, scoping mechanism, but then the downside is that now that I have a scope, I have to, I have to create the scope as a folder within the controller. Mm-hmm. So I have to create a new folder for accounts, right? And then within it, I have to, um, create a post controller as well. So in this case, I'll just wrap my model. Yeah. So now I, because I have scope it, I cannot wrap everything within it. So it's really not much of a problem, because all I have to do, I can now come here and copy virtually everything as I have here and put it inside the scope Mm-hmm. And make sure I wrap it. Mm. So when I do it this way, it means that now every route that is in here will be scoped to the post, uh, controller as well as the same as as I have without the scope. However, the downside, the reason why I don't really like declaring all my, this controller within the, within, uh, the application main controller, is that I want to be able to control the things that I do within the scopes that I have. So usually what I will do is that I will create sort of like a base controller. So I would do it, I would, I'll use this as my base controller and then fetch everything that I have here and leave the application controller alone, because it's something I don't want to touch. So usually, yeah. So I used to, I, I've declared this so that I know that whatever happens is limited to my, it's limited to, uh, it's limited to my base controller. Then what I'll do is that I'll make my post to inherit from, sorry, I'll make it to inherit from the base controller, so that Not admin, No, sorry, accounts. Sorry. Yeah. Yeah. So once I do you, you made, You made the typo in the word accounts. Yes. Thank you. Thank you. Per programming. Thank you. Yes, yes. Uhhuh. So now that I have, I don't have to worry again, because now everything I want to do is going to be, is going to be inherit from the base account. So my post is inheriting from the base account, which mean that everything I do within the base account, as long as you are inheriting from the base account, you are solid. So I don't have to worry about my, uh, my, uh, how do they call it? My application controller, uh, account, uh, please. I hope I'm make, I'm, I'm making sense so far. Definitely, please. This is my first pair programming, so I'm quite, I'm quite nervous and also talking to you also making me more nervous. You're doing great. Okay. Thank you. So, uh, with that, Dan, I think that another challenge we have to face, another challenge you face is that, um, if we try to go to, we have a route defined here, right? But, uh, we don't, if we want to do it this way, then it means that whenever we have a a subdomain, we have to be calling the subdomain to always be calling, uh, the, uh, the, uh, to always be calling our resource. Which means that when, uh, the point I'm trying to make is that let me go to my accounts controller, right? So, which means that anytime I go to a new route, I may have to define the subin all over again. Mm-hmm. Even when I have an new resource, I have to be defining. So it's kind of like a waste of time. And you may also do the, you may also have a typo, and you may also forget to do some few things. So, uh, I did was that, uh, rails give us the opportunity to actually do the rails, the race routes constraint, so we can actually constrain whatever routes that we want in one place. So for instance, what I mean is if we can call, let's say, posts, uh, in a, under a subdomain, but at the same time, we can also call it, uh, in another, uh, in another place that is not a subdomain. Mm-hmm. So we have to do the res constraint. So that's where res comes in with the, the ROS constraint thing. So what I did was I went to my lip folder, and then I created a, a folder called, sorry about that constraints. And then within that constraint, I defined a file call subdomain must be required. Mm-hmm. So I define a class called subin required, and then I use, uh, there is, um, real offer, I think self Yeah. Real, I, I, it is something I read from here Mm-hmm. Is something Mm-hmm. Yeah. The H-V-P-H-T-T-P constraints. So actually we can use the request as a hack into going to wherever we want to go. So actually when a request is coming through the, the route, we can reroute it to the subdomain that we want. And the way we do that is by using the matches, uh, keyword Mm-hmm. To us to do the matches keyword. So I came here and then I just have to define the, the match. So, uh, I define a match for, okay, def self matches requests. Okay. So what I'm saying is that if the request, uh, has a subdomain present, right? And then the subdomain, uh, the requests subdomain is not directed to www, right? This is what I want. So I want that, okay. Whenever my request is coming, I want that request to be within the subdomain. As long as this request is not within, this is, it's a subdomain, and the subdomain does not directly point from www dot, this is how I said, this is how I wanted to constrain my route for you, for me. Right. So then from after defining it, I'll come to my, uh, my route where the magic is happening, and then I have to require my constraint. Mm-hmm. So I have to require my constraint, which is the name, uh, sub domains Required. Yeah. Sub domain required. Right? Now, this, this is where, uh, it gets better because, because I've been able to define my constraint, now I can use it. So all I have to do is just use the key word constraint, which is the, uh, real key word for constraint, and then I'll call the class, I define some domain required, and then I will just wrap it in this. Mm-hmm. Yeah. So it means that as long as you are within, I hope I define my class right. So normally that's the, yeah. So what I'm saying that, uh, constrain all rev routes that matches this request. So as long as whatever resource I'm looking for is within this request, I want you to show me this links. Mm-hmm. Yeah. So, um, by the downside of this approach is also that you have to make sure that your resources are underneath the constraint first, so that in case it has to pick, in case it ha some account has to be picked first, it'll not override it. So if there's account here before the constraint, that account to be called first. Mm-hmm. But what I'm interested is I want to make sure that my sub domain fields before you can call any other guy within the, uh, the, how do we call it? Any other guy within the subdomain, I don't know if I'm making sense. Yeah, Yeah, yeah. I making sense. Yes. Okay. Okay. So now that I have done it this way, then all that is left for me to do. Now I hope I define, okay, so now that I have finding this way and I can find the account by their subdomain, right? That is all that is, that is all that is nursery for me to do right now. But because I have scoped the accc, the post, right, I also have to scope it in my views. Doesn't make sense because I have scoped the post controller within the, uh, the account. So I have to also create a folder Both. Yeah. Yeah. So in this way, I have been able to constrain it also so that I can call the post, and I, I don't have to be able, I don't have to necessarily be calling, uh, the, I don't have to you be calling it whenever. So now we can restart my server. Let me, let me remove everything again, and then set it up. Mm-hmm. What? Yeah, something in the roots root. See, if I set, it Might work. Okay. So I think this should work. It doesn't screen Okay. Already in use route. Oh, okay. Yeah. Yeah. I, I think, um, because I scope, I have to, uh, in a way do, um, so when I called this one, it is calling, it's calling everyone, right? So one of the things to, uh, when I, when I did this, because the post is already here and the account is already here, I have to segregate each an account by its, uh, particular resource. So here I can define as account route and C. Mm-hmm. I think this will work. Yeah. Because I have to be specific which of the route I'm trying to use, because I have roots here. I have roots within the constraint, but I can't find any cons. I can't find, so Rios is saying that, okay, you are defining two roots in your race route, but you have to define which 1:00 AM I supposed to use? Am I supposed to use the route with the post index, or am I supposed to use the route with the account index? But what I'm interested that whenever you encounter this one, I want you to use this as the root of my account. Mm-hmm. Yeah. So now when I go to my, yeah, so now that I have my, uh, my, now you can see that, I mean the homepage of my subdomain, but the post is still here because I define it to be within the constraint. And I don't need to necessarily go to, if I had not done this, if I had not done it this way, what would've happened is that whenever I go to my, uh, roots controller, uh, my post controller, and whenever I create a route, I have to direct it to the subdomain where I want to go, which not redirect to route subdomain where I have to go, but because I define my routes and then my constraints, this way I don't necessarily have to be worried about the, the specific, uh, route. So here, if you can observe, I am within my account, uh, my account sub domain, right? So I can just create a post, a moment, so here, and then I'll post. Now you see that it's trying to go to this, and by now it is telling me that the account must be present, right? Yes. It's, it's makes sense because the, it needs the account in order to go and then do it. So all, because I've already defined my current account, I don't have to worry about it because all I have to do is just, uh, go to, uh, my post, my post and then call the current account, right? Mm-hmm. Fantastic. And then from then here, I can then use the, uh, post paras. Mm-hmm. Right? Because I've already defined it direct, I've already, uh, defined its, and in my current account, right? So now Mm-hmm. Uh, Yeah. Sometimes rosein helps. Helps, Yeah. Because I have, I've got nothing to lose here. Yeah. So yeah, I can come and so now I can create my new account, how my new account is created, and we the subdomain, so I can create the test posts, what are we not doing, right? Um, okay, we've defined the relationships in account B and post B, and it must be something here. Uh, I would definitely call in the current account method in, uh, the you, The base account, it's inheriting from it, right? It's help permit, permit current account, fine by the doc sub domain. Uh, try to display the current account in the view J just to see if we have it. Which one? Uh, so in the new view, in the post new view, just the call, uh, current account. Oh, Yes, yes, yes. Um, yeah. So, uh, so we made a mistake. Okay? So I think we are, we have scoped the post to the account, right? But then we Oh, Right, We have, yeah, we have scoped the scope to accounts, so we have to call accounts. Mm-hmm. Uh, because we, we have scoped it to, uh, we are saying it's scoped to the account, but what we are trying to do, we are defining the post within the subdomain, but we are not calling the, where it should be scoped to, right. Because we have defined inheritance. I hope I'm right. We about now, uh, No, Uh, and what do the logs say? Okay, it looks like in the logs it didn't pass the, it didn't pass the account id. Yeah. Yes. It didn't pass the account id. Yes. Um, well, it's either the post controller, um, Yes. Uh, I think, oh, okay. So I think we are making a mistake, right? Because, uh, the problem might be coming from, ah, we Get resources both. Yes. I have not defined our resources within the post. Yeah. So it brings us to the regular, Yeah. Yes, yes, yes. And bring that there. And then he's not finding the account that's supposed, but then we want to, we want you to be within the, um, the, the, because of the constraint we defined it is because it didn't find the constraint. I think it was going through the, the second, uh, resources that we declared, right? Yeah. That one. So let's, yeah, let's see if this one works. I like that. Okay. Yeah. So the form, The problem is time from our form. Uh, maybe the, the other form you have it open, uh, further. Yeah. Uh, accounts both form, try to open it, not, not, uh, this One. Yeah. Uh, this one. This one. Both. Oh, yeah. Yeah. Maybe it should not accounts, but account, Uh, account. Okay. Okay. Let's try. No, not much to lose. Uh, Yeah, it's accounts. I think it's, it's our account, because that's the name of the module we use. Mm-hmm. I'm coming in, let's see. Okay. Yeah. Yeah. So it was the, because because we, we, um, I think what happened was that we were already, we have defined as, we have defined the scope, but the scope is not a namespace, it's actually a race constraint. So we, this, this one would've worked if I had defined in my route that this one is a namespace. If it was, let's say, uh, namespace, uh, maybe accounts, right? Then the route define, then that would've made sense. Because I have to first locate at the namespace where I am before I can go to the resource. But you are not asking me to do that. What you're telling me to do here is that I just have to look for, uh, a subdomain required. Once I get a subdomain required, nothing else matters. So you don't need to, uh, define, uh, my, uh, you don't need to define this one over here because I do need it. You are not scoping to a namespace. Mm-hmm. Because I hope I'm making sense. Absolutely. Yeah. I'm not going to a namespace, so this one wouldn't matter. So then now we can now create our, uh, we can now create our, so now we can know that whatever we create is within the subdomain where we are right now. So let's see if we are not aligned to ourself, let's go to Rios console and see if, uh, Yes. So that this thing we declared is still the post we declared is there? Mm-hmm. Yeah. The current account id, yes. Yes. It's within, it's within there. So we can then, so we can actually even come to now, we can move from a subdomain, uh, yeah. And then create another account, right? Yes. Now we are within your subdomain, right? Mm-hmm. So Well, uh, we didn't add, uh, any validation not to display both, uh, across subdomains. Yeah. Yeah. Yes. So what we did, what we did was that we are displaying all the posts within the, uh, resources, right? So Yeah. And we have to Yeah. Account, Current account of both. Yeah. Yes. Now we are within your scope now. So yeah, I think, yes, yes. So I think now it's, it's settled. It's settled now. So, which means that we can go to all the accounts as well. Yeah. Now I have all the accounts and we know that, so here now you can see that it is moving to another one, you know? So here we have to make sure that on our index page, we have to declare where we have the all the accounts, right? So in the, what is the account index page, right? We have to change the route, right? Yeah. So we have to, We have to change that route. So we have to go to route URL, right? And then subdomain Account. Subdomain. Yeah. Oh, current account. Do we have a current account at the moment? Yes. I think we sub domain equals account subdomain. Uh, We, we don't have, uh, the current account helper at the moment. Yeah, we do using because it's within. Yes, yes. So I think once we do it this way, we can then see, now you can see that the u RL has changed at the bottom of my page. Yeah, I see. So now we can go the respective sub domain and then create our stuff there. Mm-hmm. Yeah. So basically that is that, so the idea is just first, uh, adding a subdomain to your account and then making sure that you dec declare, you declare your subdomain constraints so that whenever the URL request to the subdomain and the subdomain is not directly point to www, you use your, uh, route constraint here. So here you can define all your resources within. Then again, the downside is always that you have, have to make sure that you are calling the current account dot the whatever resource you have defined within. Yes. So that is it for, uh, um, the, the subdomain. So this is how I, uh, this is how I went about implementing my subdomain. Uh, I hope I looks Fantastic. Yeah. So the second challenge would be to push it to production and, uh, make it work in production. Yes. Okay. So now the challenge in production is that, uh, the production, the production way, you know, that, uh, hero Heroku does not accept, um, wild card, right? Mm-hmm. Uh, Heroku does not produce excess l for world caps. So, uh, what you have to do is that I actually use, uh, CloudFlare and then less encrypts. So I use CloudFlare, CloudFlare and then less encrypt, right? So, um, CloudFlare automatically gives you the opportunity to have, uh, SLI mean by default, right? But before you can also get the XSL for your sub domain, you have to be in one of their paid, uh, paid tier, right? But luckily for us when we spoke that I introduced the less encrypt, uh, less encrypt, uh, approach to me. So less encrypts has a way where you can actually add your, you can actually generate SL for your subdomain. So it is actually a script I've, I found online, I've forgotten the post, but it was this post where you have to use less encrypts on your local, uh, app. So let me just, um, show you the script I run rather. Yeah. So, um, so if you're using a sub domain, right? This is the script you have to run. So, so first you have to, uh, install set bot on your machine. Then you have to run, uh, so first you have to, uh, define which kind of challenge your, uh, set your certific, the certificate of XL you are using is defined. And then you tell the server that you want to use less encrypts, API server, and then the directory to use. Then from there, you tell them what domain you want to use. So here I told them that I want to use my word card.tutor.com, which mean however you go, you have to use that, right? So, uh, let me just, uh, for illustration sake, let me just copy this and then paste it here, and then I'll use my, It's uh, a password to vote exactly A password to your terminal, like to your, uh, to your terminal. Yes. So you see, once your password is correct, it'll tell you that, uh, you have to paste this in whatever DNS you are using. Okay? So here, in this case, I'm using CloudFlare, right? So I will just copy this one, go to, uh, CloudFlare here, and then add it to the text. Mm-hmm. So here I have to choose the text one, the TST, and then I'll paste in my link here, and then I'll come back and paste the value over here as well. So I'll paste my value here, and then I'll save it. So it means that what I'm saying now, now what I'm telling CloudFlare is that as long as I'm on a subdomain, I want the SSL certificate to be issued by less encrypt. Mm-hmm. Yeah. Once you save, then you just save it, right? Then once you save it, you have to tell Heroku that you want your, uh, you want your subdomains to be protected by XSL. So you want to give them a certificate, right? And how you do that is, so if you want Heroku to give to you, uh, I don't know the machine you are using, but I think it's pretty much, uh, the same. So now this is how you tell Hero Heroku. So when once you finish, once, uh, CloudFlare accepts your, um, accepts your, uh, lesson grade and certificate, they'll give you two files. This one where they'll tell you where they have saved your certificate. Mm-hmm. Less increase will tell you exactly where they have saved. So here, online 13 here, Online 13, they tell me that this is where my first certificate if I want to go live is right. So if I want to use the certificate, all I have to do is just to tell Heroku that Heroku, I'm using certificate. I want you to add this to the certificate, go to where this file is followed by the second file, which is my private. So you can see that I have two keys here, line 13, I have the full life full change screen, and then line 16 I have the private key as well. Yeah. So here what I'm telling Heroku is that Heroku, I want, I'm adding a new set of certificates, but I want you to find the certificate from this file as long also from this file, you can choose to do it individually. You can actually do it one after the other. So you can say, Heroku had the first one, and then Heroku add the second one. It's also accepted. Yes. Once you do this, whenever you point to a subdomain, let's encrypt will automatically pick the, uh, who add the XSL to it for you, but then Uhhuh. Yeah. Okay. So once again, to clearly understand, uh, where are these let's encrypt, uh, uh, certificates, uh, held at the moment before I run the Commander to add them to Haruku. Oh, okay. So the, when, so, you know, the, the steps we followed, right? Where we copied everything here, right? Yeah. So once you finish, they'll give you, uh, less clicks will tell you, congratulations. Your certificates and chain have been saved at, this is the first piece on your machine. So I think the machine, depending on the, yes, so depending on the, what machine you are using, whether line Windows or Mark, it'll tell you where the file has been saved. So here it is telling me that if I want to look at my chain, it is located in ETC less encrypt folder, live folder. They created the URLI created here for them for my, so they created the folder for the URL as well, and then added the full chain. Mm-hmm. So this is the first certificate for the food chain. And then they added, they also created the certificate for me with the private key. So your key file has also been saved at, uh, less increased folder. And they, so they, they save, they give you two files, both they tell you the location where they have saved it. So all that you are telling Heroku is that it should go on your computer where those files are saved, and then you just copy it. But again, you can decide to go to the directory and copy it and post it in a place where it's easily accessible. So maybe you can post it on your desktop or wherever, and then just tell Heroku to just purchase from wherever it is located. But I found less Encrypts folder Christian quite Okay. So I just use it that way. Hmm Hmm. So that's about it, right? Yes, yes. Basically that's about it. But then, uh, for Heroku at least you have to make sure that you, you are on a paid, you are on a paid tier before you can use XSL. I found it the hard way. I had this up and I, I didn't, I was on the free tier. So you need to have, you need to be at least on the, uh, basic tier before you can use any kind of certificates. And, uh, do you need to manually refresh the certificates from time to time, or no? Okay. Yes. Yes. So Less Encrypts, uh, gives you the certificate for three months. So every three months you have to repeat this process. But I think I was reading a few days ago that they want to extend it to six months, but I'm not sure. But so far it is only last for three months. But when your three months is about to expire, think about a week or so, less than Great will send you an email to remind you that your certificate is expiring. Mm-hmm. So, uh, you should, uh, uh, go about it. Like you should find a way to, uh, renew it. Yeah. Sounds great. So yeah, I'm just looking forward to repeating it and replicating it as fast as possible. Yeah, Yeah, yeah. Yeah, it's, it's, it's, it's pretty awesome. It's pretty awesome. So that is it for the subdomain, uh, declaration. But the key point that I want to drive home is that, one, you need to make sure that your account has a subdomain, and then you have to also ensure that you have defined your constraint very well. I think the bread and butter of it all is this constraint, so that wills will route every request that's not directly followed with www to link to your subdomain. And then you have to make sure that in your, you have to make sure that in your route file, you define the constraint as well, so that, uh, whatever you scope will be within, uh, that space. Yes. Yeah. Great. So, so Yeah, so basically that, mm, so we, with this one, the beauty is that we don't have to necessarily always be defining our route, because here we can just go to this place and then we can go outside the sub domain and declare a post. So maybe if you have users that you want them to declare certain kind of post or something, you can give them that option. And then maybe the users who are on your app and app or something, you have to give them each of the subdomain. Mm. Mm-hmm. Okay. And it would be great if you saved it as a repo and, uh, possibly also those commands, uh, that need to run, uh, for let's Encrypt and for Heroku. And, uh, I am really looking forward to trying to replicate it. Yeah, Sure, sure, sure, sure. That's, that's pretty much, uh, that's pretty much it to me.
0
Join the conversation
Sign in to access PRO lessons, access private repos, leave comments, create watch lists.
We collect your email address, name and username to create your account. We do not share your email address with anyone else.