This tutorial will walk you through deploying an application on SquareScale in a matter of minutes. The tutorial itself is rich with a lot of details. If you want to have a quick overview, you should watch our quickstart videos.
For the purpose of this tutorial, let's imagine FractalX, a fictional startup, which is the world-leading supplier of live fractal computations. Fractals are a successful business, and customers are willing to pay to see beautiful fractals (based on the famous Mandelbrot set algorithm). Don't worry if you don't know about fractals, it's used only as an example to demonstrate the need for computing power.
FractalX could have designed its application as a monolith, with a simple design. It could have looked like:
Instead, they preferred to take advantage of a microservices architecture, popularised by the widespread use of containers like Docker. The main advantage of microservices is that they are easier to maintain: each service has only one feature and your whole application can scale easily if you benefit from a reliable infrastructure.
So far startups which wanted to be able to support any number of customers at any time, in particular at times of peak demand, required to hire highly-skilled ops. They would have to spend months to design the right architecture. Fortunately, with SquareScale now teams with only software developers can build their own dedicated, automated and scalable infrastructure and deploy their application into it with a click of a button. Let's see how with our fictional startup, FractalX.
Eventually, FractalX chose the following architecture for their Fractal application:
The software team has developed two services: the frontends and the workers. To communicate together, they will need a database (Postgres) and a queuing system (RabbitMQ). They also wanted to set up a load balancer to split the load between the different frontends (if needed).
Here is a more detailed description of the application design. (You can skip this part if you want).
More about each component:
A NodeJS Express back-end
- Serves frontend (one page) on root URL
- One API endpoint
/launchto start computing
- Split computing work into several iterations and puts them in the computing queue
- Consumes result ID queue, get result in DB and send them to frontend through Socket.IO
HTML + JS + Socket.IO frontend page
- A form to set compute params and launch computing
- Assembles results as soon as there're sent to the socket
2 RabbitMQ queues
- One for computing iterations
- One for results ID
One worker process (scalable) in NodeJS
- Consumes the computing queue
- Performs the computing
- Puts the result in DB
- Sends result ID through result queue
1 PostregSQL DB
First you'll need to create an account on SquareScale. Currently you must have a Github account to log in. In the future, SquareScale will support some other ways to sign in.
You must authorize SquareScale via Github by clicking on the green button below:
You need to enter your personal information if you want to use the service, as well as the payment details. A valid card number is required. Don't worry, you won't be charged if you don't use the service. If you do, you'll be charged by the second of use, the payment is processed every month. If you want to know more about the cost, you can use the cost estimator in your account menu or have a look at the pricing page. Running this whole tutorial and keeping the demo up for a few hours won't cost you more than a few cents.
For security reasons, your account is limited to US$500 worth of monthly infrastructure service for the first two months. If you need more from the beginning, you have to contact us or to pay the service with tokens (the feature should be available soon).
Once you've entered your information you are ready to create a new SquareScale project:
Choose a project name (a random name is provided by default):
Then, you must choose the infrastructure configuration:
For our demo, we will be using a High availability infrastructure to demonstrate how SquareScale allows you to scale nodes up/down in a very easy way. A single node infrastructure may be useful to perform some tests or in a development environment. For a preproduction infrastructure, It’s advised to have the exact same kind of configuration deployed in production. Keep in mind that if you choose a single node configuration, SquareScale cannot guarantee zero downtime during automatic system upgrades.
Our FractalX development team has chosen Postgres as a relational database management system (RDBMS) for the application. So for the demo, select Micro sized Postgres instance.
SquareScale is integrated with Slack. If you want to receive notifications about your project on a specific channel, you can optionally enter a Slack webhook. If you don't know how to do it, you can click on the provided link to get help:
After clicking on "Create project", you land on the main project page. The active tab is "Overview". What you see now is like magic! Your infrastructure is being created. In the "Overview tab" are shown the components of your infrastructure. The progress bar shows the status of the infrastructure creation. What happens here seems simple, but in the background, it's like having many sysadmins working in the dark to do the hard job of configuring your infrastructure, the scheduler, the automatic updating system, etc. With a click of a button... It usually takes around 10 minutes to create the complete infrastructure. If you had done all the work manually, it would have taken weeks to a skilled sysadmin to build the same thing! As you previously chose a high availability infrastructure, the default number of nodes of your cluster is 3. When the infrastructure creation is finished, you'll see "3 nodes" in green instead of the progress bar.
Below the progress bar, the components of your infrastructure are listed with their status. We see that we don't have a load balancer configured yet, and our Postgres database is still being built.
While SquareScale is doing the hard job for us, we can add some services to our infrastructure. As described before, the FractalX dev team has developed two services, one frontend and one worker.
The source code of the application used in this tutorial can be freely downloaded on Github at https://github.com/squarescale/sqsc-demo-app for the frontend, and at
https://github.com/squarescale/sqsc-demo-worker/ for the worker.
To add the service to your SquareScale project, you first need to fork it, as SquareScale requires to have write access to the repository.
On the SquareScale Github project page, click on "Fork" on the right:
Just wait a few seconds:
Now you have your own project with your own URL:
It's your URL that needs to be added below. Don't use the one displayed on the screenshots as you don't have write access to it.
So let's add these two services by clicking on the "Add service" button below:
There are two ways to add a service to your project: either from a Github repository or from a docker image. We'll see later how to use a Docker image. Let's start with the frontend. The development team hosts the code on a Github repository. To be deployed as a service on SquareScale, the repository must contain a Dockerfile. The application must forward logs to STDOUT and STDERR to be used by the SquareScale log system.
When you choose Github as a service source, SquareScale checks that your project contains a Dockerfile. Then, SquareScale downloads the source code and builds the docker image accordingly.
A container for this service will be launched on the running infrastructure from the image that has just been built, as soon as SquareScale has finished building the cluster.
You don't have to worry about which node will run your image. The scheduler deals with that automatically.
Back to the service configuration, we have to define the build type. If you are using Travis, SquareScale supports it as a build method. To integrate Travis, you first need to authorize the account in your SquareScale personal settings. For this tutorial, if you don't use Travis, choose the internal build system by selecting "Internal".
Afterwards, enter the Github URL of your repository. You can change the maximum amount of memory allocated to your service, and define advanced settings. For the demo, just keep it unchanged.
By now, every time you push any change on Github, SquareScale rebuilds the docker image, runs the CI (eg Travis), and after a successful result from the CI, it deploys the new version of the Docker image of your project with zero downtime. A good practice would be to create 2 similar infrastructures: one for preproduction and one for production. At the moment, you cannot choose a specific branch from your repository, but it's on the roadmap. When the feature is available, you'll be able to associate a specific Git branch with an infrastructure, so it would be easy to test and/or switch to a new version of your app.
Clicking on "Add service" launches the build of the service. The next screen allows you to define other parameters, such a the number of instances. The default is 3. It's obviously not always relevant to have more than one, especially when using a stateful service.
The frontend here is stateless, but for the demo, let's set the number of instances to 1, and then, click on "Update".
We have added the frontend service. If we go back to the overview tab, we can see that the frontend is being built (squarescale/sqsc-demo-app).
We also see that the infrastructure has just been built and we have a cluster with 3 nodes ready to host our services when built. Now, let's add the second service: the worker. We do the same as we did previously, this time with the Github URL for the worker.
Obviously you also need to fork the project as we did for the frontend. Use your own Github URL instead of the one displayed in the screenshots:
On the next screen, keep the number of instances to 3 for the demonstration (later, you can play with it and change the numbers on your own).
If we go back to the overview tab, we can see now our 2 services being built (sqsc-demo-app and sqsc-demo-worker).
Now let's add Rabbitmq, our Queuing service. It's done very easily by selecting "Docker image" as a service source, then, just type the name of the Docker image. SquareScale will retrieve it from the Docker's public registry and build it automatically.
On the next screen, don't forget to set the number of instances to 1. If you keep 3, the application will encounter unpredictable behaviours (actually we could have configured RabbitMQ as a cluster to launch 3 different queues, but the development team didn't for this example).
If you go back to the overview tab, you can see that your infrastructure and our 2 custom services are still being built (sqsc-demo-app and sqsc-demo-worker), the database and RabbitMQ are already available.
To communicate together, all the services run on the cluster can share global environment variables. SquareScale automatically sets some of these global variables, for instance for the database. Each service has also its own local variables. You can override any global environment variable in the settings by using the same name. Setting global variables is done via the "Environment" tab, while local variables are defined in the setup of each service.
To setup SquareScale for the purpose of this demo, the development team has defined in the documentation of the project that we need to setup the following global environment variables:
- RABBITMQ_HOST: rabbitmq.service.consul
- NODE_ENV: production
At the moment we are writing these lines, we don't support SquareScale files yet. In the SquareScale roadmap, we are going to support a configuration file in which all the parameters of a project we are describing in this tutorial can be set. So the only action to launch the project would be to load the configuration file with the web UI or with the command line. However, for the purpose of the tutorial, we want to describe every step to explain how SqureScale works.
After clicking on the "update" button, we still need one last step to have the application in production. Let's go back to the overview tab:
Now we can see that while the frontend service (sqsc-demo-app) is still being built, the worker service has been built and is being scheduled. One out of three instances were active when the screenshot was taken (the 2 missing were active immediately after).
On the top banner of the web application, you have the message "Configure public URL", and the load balancer is set to "Unconfigured". This means that no service has been connected to the load balancer. To perform this final step, you can either click on the setup button at the right of the load balancer field in the Oeverview
tab, or go to the "Load Balancer" tab.
This is where you select the service exposed to the web, and the port that the selected service listens to.
If you have selected more than one instance for the service, the load balancer will distribute the requests to all the services. For the demonstration, don't enable HTTPS (unless you have a valid certificate).
Once updated, the public URL is exposed. You can use this URL, or more likely set up your domaine name to redirect to this URL with a CNAME record for instance.
Now your app is ready for the world! You may just have to wait a few seconds. Here is what it looks like:
In the frontend application, clicking on the launch button will push some fractal computing requests on the queue. By doing so, you will see the build of the fractal picture step by step. The workers are listening to the queue. When there is some computation to make, they pop a small piece of computation of the queue until it's empty. The more instances of the worker service you have, the faster (even though it's not always the case: at some point, performances start to drop. It depends on applications and the way they make good use of the resources).
On the right of the fractal picture you see live the number of workers computing the picture and the number of tasks computed per worker instance.
On the bottom, the results of every computation are stored, with the number of workers that were used to perform each computation. The goal of this demonstration is to observe the effect of the number of workers, and other parameters on the speed of the application.
We can see that we have launched 2 computations within one-minute, both with 3 workers. The compute time is around 4 seconds (4148 and 4308 ms).
Now, go back to the overview tab of the SquareScale application, click on the setup of the worker service (sqsc-demo-worker),
then increase the number of instances from 3 to 5 and validate:
Back on the "Overview" tab, you can see that the number of worker instances has instantly changed to 5:
Let's see the impact of this change on the application performances by launching a new computation:
The fractal picture is built faster on the screen with the five workers. The compute time falls down to 2628 ms instead of 4 seconds.
To highlight the different types of scale (density, horizontal and vertical scale), let's approach the limits. Just to remind you, the infrastructure is set to 3 nodes so far. Do not confuse the number of service instances with the number of nodes in your cluster (we'll dive into details about cluster size later in this tutorial).
Now, increase the number of instances from 5 to 12 and validate:
On the overview page, you have a warning message in the worker field: "Missing resources to schedule service: memory exhausted on 3 nodes (try to reduce service requirements, or increase cluster size)"
SquareScale warns you that your cluster cannot run more than 7 instances out of the 12 you have requested. The good news is that your application is always running with zero downtime, but only with the number of instances that can be run on your cluster size.
Let's launch a new computation:
You can observe the fractal picture being displayed faster than before. The session results at the bottom show that with 7 workers, the compute time is 2095ms instead of 2591ms with 5 workers.
We need to optimise our settings. Go back to the overview tab, and go to the setup parameters of the worker service. In the "requirements and limits" section, the memory field is set to 256 MB, which is the default value.
Let's decrease this value to 128MB:
Don't forget to click on "Update":
It takes a little while to apply the changes. Now, each worker can use up to 128MB instead of 256MB. The scheduler will then reschedule all the services according to the maximum resources available on the cluster. Now, we still have a warning message, but the maximum number of instances that can be run on the cluster is 10 out of 12 requested, instead of 7.
Let's assess the impact on the application performances:
The display of the picture is again faster that before, and the compute time is 1645ms for 10 workers instead of 2096ms for 7 workers.
The type of scale we were playing with until now is density. It consists in changing the number of instances of the services while keeping underlying infrastructure unchanged. But we have reached the limit.
It's time to play with horizontal scale! That type of scale consists in increasing the number of nodes of your cluster. Currently, our cluster has 3 nodes, as shown on the top of the overview tab:
To modify the number of nodes, go to the "Infrastructure" tab:
Change the cluster size from 3 to 5 and click on the "update" button:
Back on the overview tab, you can see that the infrastructure is being updated. This operation usually takes around 2 minutes. In the background, SquareScale performs complex ops tasks to provision, configure and schedule the new nodes, with a click of a button... It's important to note that while this is being performed, you still have zero downtime, your application is fully operational.
Precisely 1 min and 51 sec later with our screenshot, our cluster has 5 nodes. Here we still have 10 worker instances out of 12. The scheduler is about to reschedule the services.
After a few seconds, the magic happened: the 12 instances are running.
It's time to review the final result with the application:
The fractal picture is displayed quite rapidly. The session results show that 12 workers computed the fractal, for a compute time of 1241ms! When we began the demo, it lasted more than 4 seconds with 3 workers.
To summarise the way you have to scale your application, remember that you have 3 kinds of scale:
- Density: Changing the number of instances of the services
- Horizontal scale: Changing the number of nodes in your cluster
- Vertical scale: Modifying the computing power of the nodes in your cluster. We didn't mention it in this tutorial because at the time of writing, SquareScale doesn't support hot node switching yet. This feature should be available very soon.
Once you have finished this tutorial, you should delete the project to stop being charged. First, you must unprovision the infrastructure in the danger zone section of the "infrastructure" tab:
The overview tab shows the infrastructure being destroyed.
Once destroyed, delete the project:
You are done!