I accidently recorded the audio really quietly because of something displaying wrong in my recording software, you may need to turn your volume up a bit. I also went way past the 3-minute mark, but if you are intrigued by or interested in what my software is doing, I'd recommend watching past 3 minutes, up until a bit after that last minute or so.

Inspiration

I've been developing a lot of online tools lately. Many, if not most, of these tools are intended for each person using the tool (usually intended for a company, so that "person" is actually several people) and they are designed for that one person to be running/hosting their own private instance of the programs. The problem is, many of the people within the intended audiences don't have the time, resources, or knowledge to self-host these tools, and those who do often just don't want to. The solution to this is often the cloud, but having the user deploy the program to the cloud only solves a small portion of these problems and hosting them as a PaaS/SaaS can be cumbersome, burdensome, and costly for me. So, I decided this weekend to write a tool to solve all of the problems that were stopping me from making my tools available as a SaaS. With RapiDeploy, I can offer SaaS easily, conveniently, and at a very low cost.

What it does

RapiDeploy is a tool for managing SaaS applications. It can configure and install a new app on your cloud for a user, doing everything from creating a new subdomain and installing the app's files to creating the db and a new user for the db server to writing data into the application at install. Once installed, RapiDeploy handles routing traffic to the installed app/service on the server, and it follows the user's app/service all the way through its lifecycle by also managing the process of cleanly and properly deleting the app/service and all of its data from the server.

How we built it

RapiDeploy is written entirely in PHP. There was also some apache configuration and DNS configuration that are critical to this system working, but all of the actual code is in php.

Basically, when the system receives a get request from the frontend I wrote in bootstrap, although it could also receive this get request from another frontend or even an automated system, it kicks off a chain of events that are each dependent on the last succeeding, unless a step is disabled in the app's config file, in which case it just skips to the next one. The first step taken is copying all the files over from the directory where the available apps are over into a new directory created just for this user's app in the client's directory. This seems like it should be simple, but it did require a custom recursive file transfer system to do it properly. The file copy system also ignores the config file, since the end user probably shouldn't have access to it. Next, we create a new SQL user for the app, since we don't want different client's apps to share a user since then they could access or tamper with data that they should have access to. Then we create a database just for this client's app, and the user we just created is given full privileges for their database, but not for anything else on the SQL server. Both the users and databases have their own namespace so that someone can't overwrite another, non-RapiDeploy database on the server just by choosing a clever name for their service/app. Once the databases are set up, a script runs through files in the app's code and injects variables which are in the by replacing strings that look like %rapideploy-variablename% with their real values, the most common use of this being for inserting the new database user credentials into the code. Finally, RapiDeploy redirects the user to a page in the app, either a set up page if there is final, app-specific setup that needs to be done, or a welcome page. The delete function works very similarly but in reverse.

Challenges we ran into

Configuring apache to allow subdomain based virtualhosts was probably one of the hardest parts of this project, beat out only by trying to get it to do dynamic virtualhosts. Besides my struggles in configuring apache, the biggest problems I faced were editing files in one domain/virtualhost from an entirely different domain/virtualhost because it ruled out some of my normal shortcuts in file I/O, and testing RapiDeploy, because the delete function was the last thing I wrote, and if I didn't fully delete my test service before trying to create it again, because RapiDeploy is designed to prevent people from overwriting an existing service and even one fragment of one remaining will prevent the new one from being created, so I needed to manually delete the services each time was quite tedious until I wrote the delete function.

I also struggled a bit with DNS and trying to use the CloudFlare API to automate creating new subdomains, because I was convinced that a wildcard subdomain would be a security concern. A wildcard subdomain in this case isn't actually a security concern, so I ended up using one and handling the routing from the wildcard on the webserver itself instead of in DNS which was a much more versatile solution.

Accomplishments that we're proud of

Despite how much PHP I've written in the last few years, this may well be some of the best PHP I've written yet, I really made an effort at keeping my code relatively clean and I think I did a pretty good job at that. I'm also quite proud of how simple and straight forward I kept the systems, while still allowing them to be versatile.

What we learned

I learned quite a bit in this project, from all kinds of new apache configuration stuff to a bunch of server administration stuff, to even just better ways to write my php code. I also got to play with a lot of functions and commands that I've never used before in php that ended up being very useful and can definitely improve other things I've written. This is also one of the first times in a while that I've put a focus on writing clean and concise code and from doing that, I've learned a bunch of ways to just improve how I write code.

What's next for RapiDeploy

It's headed for prime time! I'm going to be integrating a fork of RapiDeploy with my site's user management system so that only the person who creates a service can delete it, but once I have that, I'm going to be pushing RapiDeploy to my production servers and configuring most of my tools for it, that way anyone can use them more easily.

I also have plans for a few more features for RapiDeploy, including creating and restoring backups of a user's site, in fact I wrote the code for that this weekend but ended up not including it in this submission because I wanted to keep my demo simpler.

Share this project:

Updates