Back in the day, you either put your static or PHP website into shared hosting. If you were a really special snowflake, the site went onto a dedicated server. With real, physical, touchable, hardware. If keeping your OS up to date to prevent hackers didn’t keep you on your toes, the threat of the real hardware failing would. Someone would have to be ready to swap out a dead CPU fan in the middle of the night to restore operational status.
Nowadays, running your site directly on local hardware has fallen by the wayside; instead, the vast majority of people make their websites available to the general public through… the cloud. It’s the word on everyone’s lips, and it’s also making it easier to do business on the net than ever before. More on this later. The point is, when it comes to putting your app online, there are two main options available; Virtual Machines (VMs) and App Hosting Services. There are in-between approaches such as containerisation, but they’re outweighed by the other two options; we’ll discuss them briefly later.
VMs are computers bundled up inside other computers; basically, one computer takes a chunk of the CPU and RAM and memory it has available, boxes it off from the rest of the system, and then starts up another operating system in that box while the original is still running. With cheap virtual servers able to be implemented in minutes, hardware failure is basically a thing of the past, having been abstracted away by cloud providers who have systems in place to provide live, real-time migrations away from decaying nodes.
App Hosting Services (AHSs), on the other hand, are solutions provided by tech companies like Amazon, Google and Salesforce. You add configuration files to your project which tell it how to set up the hosting environment. Then, you can (re)deploy your application by typing just a couple of (vendor-provided) commands.
There’s a lot of different products and services in each respective sphere, and a lot of debate about which ones are better than others… but before picking a product, it’s best to pick a method. Are you better off setting up your app to run on a VM, or an AHS? At first glance, it seems like a no-brainer. It’s a choice between, on the one hand, having to set up and manage a whole server, be responsible for keeping it secure and up to date, and rebooting it – plus set up all the supporting infrastructure. On the other hand, I type a few commands and my application is magically deployed. It’s that simple… isn’t it?
In this post we talk about the pros and cons of standardised app deployments like AWS Elastic Beanstalk (EB), AWS Lambda, Google App Engine and Heroku compared to setting up your own server, installing it all yourself and configuring it manually.
The Cloud doesn’t exist
Before we jump into the whole “VM vs. AHS” debate, let’s talk about what they share. If there’s one buzzword that drives a lot of tech people nuts, it’s “the cloud” (and also “agile”, but that’s a whole different story). If there’s one thing you need to remember about the cloud, it’s that:
There’s no “cloud”, it’s just someone else’s computer.
For those of you who don’t know the background, I’ll go into a bit more detail.
The term “cloud” dates back to the prehistoric days of the internet, back when it was still ARPANET and the concern of the day was nuclear mushroom clouds. (That’s not where the term comes from, though.) The idea was that given the major differences between computers hooked onto the network, the computers could pool and share their resources; a computer with extra processing power could handle some of the computations for other devices, while a device with free megabytes of storage capacity could store data from other computers. They’d have formed a diffuse collective capable of more together than could be achieved apart, in the same way that fog droplets form a much bigger cloud. (That’s where the name comes from.)
These days, cloud computing isn’t particularly… cloudy. Most cloud computing ends up in one massive room or another filled with the whirring of dedicated servers. When you’re pushing some code up to the cloud, it’s just going up to one of these massive computer banks. Sure, it’s probably a little more reliable and there’s a nice interface with shiny buttons, but at the end of the day it’s not magic.
I think understanding how your code is actually being run inside one of these abstraction systems can help immensely with your overall understanding of how applications are really hosted.
With that cleared up, let’s look at some pros, cons and comments about each method of deployment.
To clarify, I’ll lump Elastic Beanstalk, App Engine and Heroku together as AHSs, and statements I make should generally apply to them and other similar setups.
Likewise, when discussing VMs, I’m referring to services like AWS EC2 and Lightsail, Google Compute, Digital Ocean droplets or even a colocated or dedicated server. Any service where what you get is little more than a remote computer with an OS.
Ease of setup
It can be hard, or at least tedious, to set up a bare VM to host your application. Normally you need to know which packages to install, where to set up the configuration files, how to keep it secure, and so on. Once you’ve done it a couple of times it can become routine, and you can even write scripts or use tools like Ansible, Salt Stack or Puppet to automate it.
On the contrary, vendors often tout how easy it is to get your app up and running on their system. Usually they claim something like “run these [1-5] commands and you’re off”. They can even automatically set up a testing hostname and database for you.
However, if things don’t work immediately, you might spend a lot of time debugging without much idea where to start, especially if you don’t already have the underlying knowledge of how things are supposed to work. You’ll probably need at least passing knowledge in load-balancing health checks, file paths, system logs and DNS in order to get your application up and running.
Furthermore, if all you’ve done is learned how to type command
Z to deploy, you’ve only learned one system. You can’t expect to use the same commands from EB with App Engine, for example, and get the same thing up and running. Which brings me to my next point.
Standardisation and vendor lock-in
We now know that, according to vendors, deploying to their app hosting system is simple. Simple, that is, once you’ve learned the command and how to troubleshoot their specific collection of technologies.
Unfortunately, those commands aren’t consistent across all providers. For deployment, Elastic Beanstalk uses
eb deploy, whereas App Engine’s command is
gcloud app deploy. Pretty similar, but obviously you’ll need to learn the right commands for each specific provider. And the deeper you get and the more time you invest into the intricacies and specifics of each vendor’s services, the harder it gets to justify switching to a different service.
This can actually be an asset, depending on what you’re aiming for in your career; specialisation sells, and being a guy who knows the intricacies of a system can serve you well as a consultant or troubleshooter for when someone really needs help with their implementation on that system. Conversely, that degree of specialisation can hurt you if that particular service starts going out of fashion, or even goes under. It’s a tradeoff.
Compare that with learning how to actually set up a server. An Ubuntu Linux machine on AWS is the same as an Ubuntu Linux machine on Digital Ocean. You can use the same commands, configuration files and setup scripts, whoever your provider is. This means it’s pretty easy to move your application to a different server/host without too much trouble. And Linux server setups are extremely widespread these days, even if the consumer market is dominated by Windows and macOS, making that sort of know-how much more widely applicable.
App hosting is easier to manage
When you have your own server that you manage, you’re responsible for keeping it up to date. That means applying security patches and sometimes even rebooting. This isn’t necessarily a difficult task, but it is something that needs to be done. It also involves shutting down the server for a bit, which can be an issue if your app is something that needs to be in more-or-less constant operation.
App hosting systems take care of this for you – or at least you trust the vendors to be running the most up to date version of all the software. Also, the updates are not always automatic, as “upgrading” is actually restarting your app in a new container. Remember – there’s no cloud, it’s just someone else’s computer. That being said, when you do decide to re-deploy, and thus update, usually it can be done with no downtime.
VMs have easier data persistence
App hosting systems have a nasty habit of being forgetful. That is, you can SSH to them and tweak config files or make edits to files, and everything looks fine. Re-deploy, or restart the service, and you may very well find all those things lost in the proverbial shuffle.
One example of this is the process of getting system services to run. On a virtual machine, you’d be able to SSH in, create the init scripts, start the service and… that’s it. Next time your server has to restart, the init script will still be there and your service will start automatically.
To achieve the same persistent script on an app hosting system, you have to write scripts that write out even more init scripts when the deployment is done.
This approach does work, once you figure it out. The hardest part is working out how to escape or double escape all the variables to they get written out appropriately. It’s not necessarily as beginner-friendly or intuitive as being able to directly manipulate the file system.
VMs can be cheaper, depending
The cost of app hosting platforms are (roughly) comparable to the virtual hardware on which they run. That’s okay for single deployments, but you may need more than one “service”. For example, say you want to store your data in a database. That’s fine, you can just pay extra for a hosted database service (like RDS or Google Cloud SQL). But what if you also need a frontend Node system with backend Django? That will need two app hosting instances to run, one for each. The costs of these extras can add up. And as we’ve mentioned, you’re slowly becoming entrenched in their infrastructure and will find it more difficult if you have to move providers.
If you’re a startup looking for bang-for-buck, a low- or medium-spec VM will be capable of running your application, web server and database on a single machine. You can worry about scaling once you have users. At that point, you can look at using a hosted database servers or multiple VMs, or starting to use your provider’s load balancing service.
App hosting scales more easily
There’s no question that scaling your application using an app hosting service is easy. For example, with EB you can use the
eb scale command to start extra instances. You can even configure it to scale automatically based on certain thresholds.
When running directly on VMs, you’ll have to do this yourself. Set up your own load balancer and add/remove machines as necessary. Once again though, you do have more control over this than with auto scaling.
App hosting services
- Easier to setup and deploy to, provided you know what you're doing
- Deployment and setup skills are not necessarily transferable between vendors
- Harder to persist data or run services
- Only designed to run one app
- Much easier to scale
Direct VM deployment
- Not as easy to set up, but skills can be transferred between vendors
- Need to be managed: DIY security updates and reboots
- Like a real computer! Write to disk and the files stay there
- Save costs by running multiple services on one VM
- DIY scaling, but in keeping with the theme, you have more control
The Middle Route: Containerisation
So, to reiterate the summaries, AHSs are services that run all your apps directly on their computers, while VMs are services that run a computer-in-a-box for you on their computers, from which you can run the apps yourself. Containerisation represents a third option, one that stemmed from a question like this: “Hey, there are dozens of people running basically the same OS virtually on our computers, many times over. What if they were all running on one copy of the OS?”
Ideally, containerisation gives you the best of both worlds. The kernel of a single OS is shared between many, many containers, using services like Docker and Kubernetes. Your containers can be customised as you like, you can even run lots of services inside a single container (but don’t do that, it’s wrong!). That being said, you’re still giving up some control, as the end users (that’s you) probably won’t have control over that core kernel. And keep in mind, there’s no magic; it’s still all running on someone else’s computer. And you do have to jump through some hoops since there is, again, no persistent storage.
Which approach should you use?
There’s no one-size-fits-all solution, obviously. But here at Tera Shift we’ve worked with lots of different types of hosting. We’ve moved sites to, from and between many of these different hosting platforms. If you’re not happy with how your deployment and hosting is serving now, or looking at options for deploying a new application, we’re happy to help.