go podcast()

My upcoming SaaS product at first wasn't suppose to be rolled out as a product, but was for my own usage. Turns out as I was using it and selling my online courses that it appears to me as being fairly usefull and could compete against existing course selling platform.

The hic is that it wasn't built as a SaaS in mind, so I have to deploy one application per customer. It's completely multi-tenant. To help with automating the deployment of a new tenant, I wrote and orchestrator with agents to facilitate the deployment of a new application. I thought this part could be interesting to hear about as it's written in Go.

Want to support the show? The best way is by purchasing my courses Build SaaS apps in Go and Build a Google Analytics in Go. Listeners of this show get a 50% discount on all store product.

Creators & Guests

Host
Dominic St-Pierre
Go system builder - entrepreneur. I've been writing software systems since 2001. I love SaaS, building since 2008.

What is go podcast()?

15 minutes news, tips, and tricks on the Go programming language.

Dominic:

Hello there. I'm Dominic Saint Pierre and you're listening to Go Podcast. Today I talk about a small piece in my next sass that is written in Go. Hello, gophers. So this is another episode.

Dominic:

This week I will be alone, so there's no guests. So I think I'm going to talk about something I'm working on these days which I think it's worthy of mention and could be interesting. So let me give you a quick background. So I'm I'm building a a software as a service. So basically this project started as me building a a platform to sell my own online courses.

Dominic:

So, yeah, I I I was using something and, they, they change, they they they made some some changes to their plan their their pricing plan. And, you know, I thought, you know, it could be nice to build my own thing. And then it's it's a project I'm I'm trying to build for a long time now. I've iterated that over multiple version, SaaS at first. So what that means is well, obviously I built it for myself.

Dominic:

I did not really add any commercial, plan in in mind and whatnot. So once I started to to use that and I I launched my, my last course on on it basically in December. So basically I I launched a platform, at the same time as I launched my last course. And, you know, I said to myself, you know what? This thing's, this thing is is nice.

Dominic:

But I I did not add any UI. So it was it was it was all like common base and and just just, you know, just the front end. Basically, the the the the blog and the the place where, where, you know, people can buy my course and and and the the course viewer itself and whatnot. I mean, everything from a public facing point of view is done. But I was not having any kind of administration, dashboard and things to create new courses and whatnot.

Dominic:

I mean, so but, you know, long story short, so this, not being a SaaS at first. So how how do you, you know, how do you turn a web application that that was built for one person, basically one one company and and you want to turn that into into a software as a service. So at first I I thought, you know what? This could be, this could be sold as a self hosted, kind of platform. So people could, you know, a creator of some that want to launch courses with with community and affiliate program and whatnot.

Dominic:

They could, you know, they could purchase the, the, you know, the application itself and self host it. And, yeah. So that that thought, kind of worked for sometimes, but I I at the end of the day, I I I I decided to go with a traditional software as a service model, but I I still have I still have this single tenant, you know, web application and rewriting it, or I mean, introducing a fact that I would be able to host multiple tenant on the same application was out of the question. So it was, you know, it was not designed like that at first. So that, that, that would, that would change so many things at the core level that I don't think it would be worth.

Dominic:

So my other choices was, you know, what from the point of view of someone that is, you know, buying a subscription for a software basically, how can I make that somewhat transparent for them? But for me, continue to have have this, you know, single tenant web application and isolated database and everything like that. So I decided to to try and and and build myself some, very, very, you know, something extremely simple. So I again, I'm I'm I'm just I'm just a simple person. And I I I just like things that works, that I can explain.

Dominic:

And I, you know, I can return to that very quickly and do some modification, especially when I'm building SaaS. So when I'm building a SaaS, for myself, you know, I don't go into too much over engineering thinking and trying to make things, you know, scale and things like that. Because at the end of the day, you know, when I'm building a SaaS, the the thing that I want to scale is my marketing is how to acquire new customers, everything like that. So it's it's not at all related to the code. I still really enjoy, building SaaS and go because it kind of gives you even, you know, you can go very quick and go and and still be somewhat.

Dominic:

I don't know, reassured that the code that you're putting in production is still decently, decently, go going to perform well, first of all, but not not only that, but I mean, you should not have too many runtime exception or not exemption, but errors, of course. But, and, especially as you as you continue to, to get some experience with Go, I mean, this, you know, it it's basically just point, you know, pointer and and some kind of, you know, some kind of of of nil, pointer that can, that can happen in production. But at some point at some point you don't do those things anymore. And, and you are left with with a code base that is great. Unfortunately, I've built that, I've built this thing in in Django.

Dominic:

So again, I was doing that for me and I I knew I did not want it to build any kind of administrative dashboard, you know. So I was using the Django admin interface to create my product and and manage all my backend database, if you will, or or every, you know, everything that needs to be done. And I I have a I have a module to send some, some newsletter to, you know, to people that purchase my courses and also people that just register for the newsletter. It's, it's all done, you know, via the command line and whatnot. So I basically create a manual HTML page, and this is this is what is going to be sent and things like that.

Dominic:

So, I mean, I I was I was very far for from adding a acceptable, you know, software as a service from the the point of view of of someone that, you know, wants to buy this thing and wants to start trading their their product and sell their products. So the administration was was wasn't done. But I decided to write the, the orchestration part in Go. And this is, you know, this is where things will will get a little bit more interesting. So after after all this, this, you know, background story and whatnot, we can finally start to talk about what, you know, what what I'm talking about here.

Dominic:

So the orchestration part is in Go. So what what it is? So like I was saying, since I do have kind of a single tenant application, so every customer that that would purchase this SaaS. So that that was that that would start a subscription will need to, first of all, get some kind of installation of their own, on on the on the server. Get get the application up and running.

Dominic:

So it needs to be installed. It needs to be, added to as a service. It needs to provision an SSL certificate and all of that. And I, you know, I want I want everything everything to be automated, of course. So I I beef before going with Joe, I started to check at, so, you know, I I have one one friend that that was talking, to me about, py infra.

Dominic:

So, I almost, went with that. And, I think it could could have worked. But again, I mean, it it it was I find I I found I found that it was maybe a little bit too much for my needs. So again, I I have probably less than than 8, 8 steps, which which are, you know, kind of easy when you think about that. Deploying a Python Django application is not, is is not the hardest thing in the world.

Dominic:

So I just need to to architect that. And I wanted an easy way as well to, to be able to scale. So what I did is, well, I'm, I'm deploying everything on DigitalOcean. So for that project, I I decided to, to manage my, my servers and whatnot. So this this is this is mostly what I do often.

Dominic:

This is I I already did an episode and myself done that. So I I do really enjoy, you know, platform as a service things like render.com, for example. And maybe, maybe fly. Io these days. But again, fly.

Dominic:

Io is another, another interesting things that in my opinion, you know, if you don't really need to have, your application deploy, on the data center close to, to the user that are using that. I mean, the added complexity of having to, you know, to sync the all the databases, everywhere. It's I I don't know. I I know that they they are they are having a lot of, library to help you do that. And and to be frank, you know, I'm not, I'm not super, versed with Fly.

Dominic:

I never used that, yet. It's just that on paper it seems to be I don't know. Again, it seems to be a little bit too much. But but again, I'm probably wrong here. And, Yeah.

Dominic:

I I need I need to give them, some, some time. That's that's another problem. I mean, we there's so many things to check sometimes that, I mean, how how can you how can you do it all? It's it's crazy. You need you need to take decisions sometimes and you need to, to just accept the fact that, you know what?

Dominic:

For now this this is not going to happen. But, I'm diverging again. So we were talking about the, the fact that I, you know, yes, I I wanted to have some kind of control over what's going on and, having small VMs that I can, provision as needed. So, what I'm doing is that so the idea will be to have the marketing website, directly linked to Stripe. So bear with me a little bit in here.

Dominic:

So if, you know, if you don't care about SaaS at all, this, this, yeah, this might not be the episode for you. But again, I'm, I'm, I'm a huge fan of of software as a service. This is what I'm I've been doing for the last, I don't know, since 2008. Yeah. This is this is my passion to be frank.

Dominic:

I really, really like this, this this this kind of business model. It's it's not about building for me. It's it's all about, you know, the overall customer, customer development, marketing, sales, support. I I like really, really enjoy when, you know, when when you put something together and you, you just try to grow it. It's interesting.

Dominic:

Granted I have not I have You know, it's never happened to me to have a huge success. So for it to come I'm still I'm still confident. So yeah. Closing that parenthesis. So continuing.

Dominic:

So I I wanted to have something very very very scalable, but, easy to maintain and and not, you know, not having to introduce too many 3rd party and whatnot. So far, it's pretty straightforward, I think. So again, like I like I'm I'm saying in my course, I always split my marketing site, you know, from my application. But for for this it's it's interesting because the application is a multi tenant web application. So you don't really have a backend available to, you know, to perform some kind of account creation and whatnot.

Dominic:

So, I I wanted to, to not have to deploy a a go back and probably in in this instance to just accept, new sign up. So what I what I thought was, you know, why not just use the new, Stripe payment link? So if you don't if you don't know, Stripe did some crazy changes, in in the last, I don't know, 3, 4, 5 years. This is this is incredible. The amount of things that they have built.

Dominic:

And one of them is well, well, first of all, you have this this great, customer, customer portal that, that really helps. Because if, you know, if you, if you're familiar a little bit with my, with my, build a SaaS course. When when I wrote it, basically, all all of that all of that things, they they were not existing. So back then, even though Stripe was was kind of very easy to use, it always has been kind of easy to use. You still add to to build a lot of functionality for your, you know, billing subscription management and whatnot.

Dominic:

Especially if you if you add some, some interesting, you know, distinction of what the the built in functionality of Stripe was was offering. You know, I've I've I've built a lot of billing, system myself on top of Stripe. But now, I mean, now you you do have a lot of things. And the customer portal is is very great. Basically, you just generate some kind of session on your on your back end and you redirect the customer there and they can, you know, they can print their their invoice history.

Dominic:

They they can they can change their plan, change change their cards. So all of that you needed to do that yourself back then. And not only not only the back end, you you had to to do the front end as well, which, if you if you know me a little bit, you know, be being blind, but you know, everything front end is is always, not very interesting to be, to be to be frank. So. So they, the idea was, you know what, let's, let's leverage this payment link.

Dominic:

So a payment link is, is a little bit more easier again. It's it's a little bit up the stack if you will. And now you just add a link. So you don't even need a back end for that. So you generate you generate that on the Stripe, dashboard itself.

Dominic:

You put that on your pricing page on your marketing website. So the button directly direct them to a payment link. And now you can leverage the webhook from Stripe. And this is what I'm doing. So basically, I'm leveraging the, I think it's the customer subscription created something like that.

Dominic:

So one, one of their event, and this is, you know, this is where I start the orchestration of the deployment of this single tenant web application. So the webhook is going to be called as soon as the customers, you know, a new customer is, you know, entering their credit card and and do doing doing the onboarding process on Stripe. So this will this will call my, my orchestrator if you will. So for that, I I I knew that I was going to have 2 parts. So there there's this orchestrator that that will be responsible for receiving the Stripe webhook and initializing some kind of deployment and, and and a lot of things that I I will go over in in a couple of minutes.

Dominic:

But, the second component of this was, you know, to have have some kind of agent on all of the droplets. So, droplets are DigitalOcean VMs, if you will. So all of the servers that that I want to, to be offering some space for Tenant to, to host their application. So every so let's say let's say I have 3 droplets for example. So the our orchestrator will need to first decide, well, where am I going to send this new customer?

Dominic:

So after receiving the web book, there's some kind of decision to be made. So the orchestrator has a very, very is a, you know, a local database. It's it's a CSV file. Yeah. Yeah.

Dominic:

I know. I know. I mean, but but I I don't need anything more. There's a little bit of CSV file, which I think there's 4 columns. So a a dynamic customer name, which I'm picking from a list of 5 letters English keywords.

Dominic:

So this is going to be used for all of the things that we will we will mention. But let's say, the system D services for example, and the, the the directory where this application will be deployed. Anyways. So there there's a CSV file that attach a tenant with an IP address. So the IP address of the droplet and a couple of other, other information like the the Stripe, Stripe customer ID, for example.

Dominic:

A very, very simple CSV file. And I know, I know. I mean, there's there's some probably some of you that that are saying, Wow. This guy is crazy. But no, I mean, I'm building a SaaS.

Dominic:

I'm not building a multimillion, you know, multibillion whatever organization. This is the beauty of software as a service. You are not having your, oh man I I'm a software engineer. I need I need to do things, you know. I need to over engineer.

Dominic:

Because let's face it. I mean I I will I will be totally I don't know. Maybe maybe maybe it will it will not, get through or I don't know. The you know, warning warning sign. This this is going to be a an opinion, but I I think that sometimes we are over in engineering our our solution.

Dominic:

I don't know if it's just me or but Yeah. Again, I'm building a SaaS. I'm building it for myself. I'm a one person company. This is this is going to to work.

Dominic:

And the day that I I do have, I don't know, let's say 5,000 customers, then yes. I could, I could then have the the money and the probably more resources to do anything more complicated. For now, the goal is to validate this idea. This product, is it going to work? Is it going to, you know, bring me any money?

Dominic:

So there's no reason for me to, to, to put anything else there. So again, we, we have this webhook from Stripe. The orchestrator is is being called. There's some a new entry that is added to the CSV file. And this thing, this thing is like round robin, deciding where, where this deployment will go.

Dominic:

So based on the usage of of the, the, you know, the VMs that the a that that the agent is deployed to. So which are the less the less busy if you will. So the one with the the last installation. And this is the target. So now there's there's a simple HTTP call that is done to this IP address to this agent and tells them, you know what?

Dominic:

This is this is a new tenant. So it's it's it's sending, sending a tenant over, a JSON payload. So via HTTP post, very simple. And, and this agent is is is running a a Bash script. And everything everything is, is inside is embedded into, into the, the program itself.

Dominic:

So the binary. So I'm using the the embed package from Go. So the nice thing about that is I'm I'm building the orchestrator and the agent on the same, the same code base. So there's there's a couple of, you know, web handler, if you will, some kind of endpoint that only, only are there if if you are in the orchestrator mode. I I just have a flag.

Dominic:

So basically, I'm passing a dash o just to indicate, you know what? You are in the orchestrator mode. And otherwise, you you are an agent and it's the same code base. I find out and I, I I find find out, you know, it's good. It's good it's good enough for now.

Dominic:

So the agent is receiving some kind of of data. And, again, they are using they are using the same the same exact same project. So this is the same Go module. This is the same, so they are all sharing structure and whatnot. So so again, it's it's nice.

Dominic:

So the agent is responsible for making sure that everything is going to deploy correctly. So in my case, I, I'm I'm embedding some, some files in in this binary. Executed. The, the system, the services, the system, the socket, because, Django application use a unique socket to, to communicate. So from the service, not from the service, but from the from your, your HTTP proxy.

Dominic:

So instead of calling a HTTP endpoint to do the reverse proxy, do you you are calling a a UNIX service? UNIX socket. Excuse me. So again, I mean those files are there. It's it's very very clean.

Dominic:

I'm just, you know, I'm just having, you can you can imagine having a an HTTP handler that just received you know what? You you you are receiving a new tenant. You need to do it set up. So what I'm doing for the communication. So again, did not wanted to go with with gRPC for that.

Dominic:

I mean, it's crazy. I I just have one endpoint for now. Very simple. And this endpoint is called, is is receiving some kind of action. So I I wanted one endpoint and, it's going to always be the same kind of data that that will be sent to an agent.

Dominic:

So it's an action with a tenant actually. So, you know, like create this tenant for example or delete this tenant or update this, this tenant. So very, very simple, HTTP handler just receiving, this action and, and it performs the, you know, the desired action. So in our case, we are still inside the create tenant flow that that I'm explaining. So so, yes.

Dominic:

This, this small agent just you know write the system default. I'm using Kaddy as the HTTP server to do the the the reverse proxy and all the the TLS the TLS termination and whatnot. I mean, you know, I'm I'm using an NGINX, Most of the time. It it it will be the first time I'm using Kaddy. If you don't know Kaddy, it's, it's a very nice, Go HTTP server.

Dominic:

So it's it's in it's in the Nginx, you know, realm I would say. So so yes. I'm using that. It's it's going to, it's going to serve me well versus having to, to do a new NGINX blocks. A block with the with the Let's Encrypt manual registration and and things like that.

Dominic:

So so, so normally, this is what I'm I'm using Nginx with Let's Encrypt because I I only do that once and after that there there's some cron that that automatically renew the the certificate. But now, you know, I I wanted something more automated and not really have to, to mess with with this process of, renewing and, you know, getting this certificate and Kaddy is is is great. I also was a little bit curious to to discover that. I've been hearing about that for a long time and, yes. It's nice.

Dominic:

It's a very it seems to be a very nice, nice go project. So so yes. So, I mean, some some files are generated. The like I was saying, the system file and the the Caddy block that will that will need to be inserted into the Caddy configuration file. And, and after that, it's just a matter of moving those files to the, the Etsy system, the system.

Dominic:

So my services are are using the the five letters, word that I that I was talking about. And, so so same for the directory. So you can imagine the, the the bash script being, you know, again, not not very complicated. So you basically create the directory, you copy the latest version of, of the application. So it's taking that from Git directly.

Dominic:

So from GitHub. And, and from there, I mean, it's it's, it's a typical, you know, Python Django application of getting the dependencies installed, migrating the database, and, you know, registering the system, the, daemon, enabling it, starting it. Then, you know, the same same cool things that, that if you if you have managed a server, at some point you you are familiar with that. If not, then, I I don't know what to to tell you. This is, this this is interesting.

Dominic:

So sometimes if you if you haven't done that, it's it's nice. I I think, for yeah. For me, infrastructure is is as fun as as programming, to be frank. Sometimes I I do enjoy going there and, you know, I've I've been I've been doing that on on, you know, all my career, if you will. So, but I I understand that sometimes, some programmers, don't really want to, to go there, mess around and things like that.

Dominic:

It's totally fine. But, you know, let let's just say that this agent is is just responsible for doing some kind of DevOps manipulation, and, you know, infrastructure things. And after that, I mean, that's it. That that's mostly it for for, you know, from a new customer point of view. So what's going on?

Dominic:

So after that, they, they, they are receiving an email and, and, and something like this is, this is your you know, this is your store URL and whatnot. And they go there and they start they start, managing their their store, creating their product. So they have their completely own, isolated installation database, every everything. Everything is self contained. Very easy to back up.

Dominic:

Very easy to, to maintain. So the sad part is that because there is there is downside for that. And and again, let's let's remember why I I did it like that. And I'm I'm not recommending that, at all. I mean, if you are going to build a SaaS and you don't need the to have multi tenant at first, you know, don't don't go that route.

Dominic:

It's it's it's way more complicated than just having a back end and having, you know, all are your all of your users using the same, the same back end and database. It's easier to to go from single tenant to multi tenant than than going the, the other way around to be to be completely frank. So yeah. So so this is this is why, you know, this is why. And and the reason why I'm I'm in that situation is that because I I built that for me.

Dominic:

I did not add, any intention to to publish that that application as a product at all at first. I did it because, yes. You know, the product that I was using was was changing their pricing. They they they removed a paid price and they made it, paid. So I mean, it, it was, it was not working for me anymore.

Dominic:

And, you know, being a programmer at some point and being someone that I've been building so many application. So I I did that with with my invoicing package as well. So I was using FreshBooks and I, at some point I said, you know what? You know, screw that. Let's let's build it.

Dominic:

And, it took me one weekend and now I do have my own invoicing software. Am I going to publish that as a product? No. Not at all. But so yes.

Dominic:

So that's the story of of this, this. I I think it's interesting, to, you know, couple of things to keep in mind. Some sometimes you don't need to to have a super complicated solution to, to fix a problem. And, you know, what what I've I have done that inside an organization that that needs to, of course not. I mean, this this this is not this this is not the same situation.

Dominic:

And I I I've experienced both. And, you know, my my experience is is more on the smaller project side. But I, you know, I I've seen I've seen the enterprise as well. And and to be to be honest, sometimes, I don't know. Things get a little bit more complicated than what they should be in my opinion sometimes.

Dominic:

And, Yeah. The over engineering is is real. It's real. And and it's something that you you don't really do in in, you know, small bootstrap startup software as a service world. Because at the end of the day, you're not there to build something.

Dominic:

You're there to sell it. You're there to make a living out of what you want to build and and have have the life that that comes with it. So, for me it's it's all about that. It it it always has been and always will be. It's not about, you know, building my project or it's not it's not about the fact that, oh, you might not want to like to work with other people.

Dominic:

It's not that at all. For me it's all about, you know, waking up on the morning and working on my own things, my own company. Things that brings me money, brings money to, you know, to my family and whatnot. So, and not having. Yeah.

Dominic:

It's it's well, it's might not be about control as much as just just having the the choice of saying, you know what? Today I'm not feeling well. I I I I will not work. Or, you know what? This week let's let's do that.

Dominic:

Let's let's add the ABC feature or let's try to reach a new, a new audience. So so so it might it might sound like, okay. You you are a control freak. You want to well, you, you know, you don't you don't have any any other choice, but to to have some control when you are building your own things. It's it's not it's not that at all.

Dominic:

It's just to have yes. The, the sentiment of achievement is is so great when you finally succeed. And, I and and you know, I I I touched some some kind of success at some point with LeadFuse. So it was a SaaS I've built in, 2015, 16, something like that. So we, we are the 6 employee at some point.

Dominic:

So, I mean, I I know a little bit what it what it feels to have, some kind of success. And this is this is great. It's it's also very, very hard, you know, because now you you have everything on your on your shoulder. And, you know, if you want to, to put some, some food on the table at the end of the day then, you know, your product needs to needs to bring money and and this, you know, this is this is this is really what I what I like about that. So, I have kind of my own destiny on my end.

Dominic:

So, I will see. It's, the product is not launched yet. So, but I'm I I I thought it it would it would be interesting to, to just explain explain what what I have for for the orchestration because yeah. I mean, again, it's probably very simple. So if you were to to talk to to some infrastructure people, and and told them, about this this this thing, they would probably say something like, wow, this is, this is probably not going to scale or this is this is not how I would do that.

Dominic:

I would have used, whatever, Jenkins or any kind of, you know, Terraform with AWS and things. No. That's not that. You you you don't do that when when you are building a SaaS. You're not over engineering the solution as a technical problem.

Dominic:

Because the problems that you need to solve first is how to sell this product. How to get money. And this is not done via technology. This is not done via coding. Does that mean that I I'm I'm doing shitty code?

Dominic:

Not at all. It's not it's not what I mean, but you still need to draw the line. And and, you know, I'm kind of paraphrasing a little bit what what I'm saying in in my course. So build Sass app. So, again.

Dominic:

So hopefully that was a little bit interesting. It's it's very hard sometimes to, to know exactly, what what, you know, what kind of story that that would would be interesting in this podcast and whatnot. So I mean, I'm trying some things. I'm still trying to line up some some guests as well. So so from here it will be a mix of guests and me going solo in between.

Dominic:

So, So right on that. Thank you, thank you for listening and see you next week. Alright. That's it for this week. I would really appreciate if you can talk or share about this podcast.

Dominic:

It's it's always helpful. Also, another way to support this show is by purchasing my course. There's always a link in the show notes. So on that, see you next week.