Cloud service that I use to run my weekend project: haiku.pro.
I am not affiliated with Render. I am using it because it is exactly what I need in my weekend project.
Table of Contents
- Why I built my weekend project: haiku.pro
- Product requirements
- High-level design / architecture
- Looking for cloud service alternatives
- Why I chose Render
- auth0 for my login service
- haiku.pro’s setup in Render
- Domain name configuration
- Infrastructure as code
- Horizontal scaling
- A few other nice features worth highlighting
- High level design with Cloud Services
This article will not dive into the implementation details of the web application. However, we will go through the high level design with emphasis on the usage of Render to run the web application. I might consider diving into the implementation details of some of the components involved in my future posts. Stay tuned ;)
Why I built my weekend project: haiku.pro
Before we get started, let’s understand the “why”.
- I like to read and write Haikus. I am attracted to the simplicity in reading them and the constraint in writing them. During the Covid period, I’ve started thinking of building a simple web application to write and share Haikus. In other words, this weekend project is yet another Twitter clone but for writing haikus.
- Anything that I will learn from this project can be applied to any future projects that I will build. If done right, parts of what I build for haiku.pro can be reused for any future personal projects especially if they are of similar architecture. As you can see in previous blog posts: I am a fan of reusing boilerplate code with templates and I like to share reference architectures so developers can learn from it.
haiku.pro users should be able to:
- Create an account and login with username and password.
- Write and post haikus.
- Follow other users. They should be able to see posted haikus of users they follow on the authenticated home page.
- Like posted haikus.
- Share a direct link to a haiku.
High-level design / architecture
The system design is a simple — a tiered web application with: authentication, static file server, a web frontend, a backend service and a database.
Looking for cloud service alternatives
Given the above design, I started to look for cloud service providers that I can use. Although I have been using Amazon Web Services at work and for some of my personal projects, I was looking for simpler alternatives where I could achieve the following with minimal work needed. I’ve always had this problem where I build a web application locally but somehow got stuck setting it up or deploying it to a cloud provider and I ended up not continuing.
Here are the requirements from a Cloud Provider that I was looking for:
- Setup a build and deployment pipeline with GitHub integration.
- Custom domain and DNS configuration.
- Setup services using a multi-tiered architecture.
- User authentication.We don’t want to handle user data and authentication, leave it to services that specialise in it.
- CDN and static file hosting.
I’m aiming for less infrastructure maintenance so I can focus on building the product.
Why I chose Render
Render is a unified platform to build and run all your apps and websites with free SSL, a global CDN, private networks and auto deploys from Git.
After scanning their documentation, I realised that they have everything that I need (see list above) except for user authentication.
Their documentation is also easy to follow. I noticed there are few number of steps in their tutorials, usually around or less than 5~ steps. Which makes it a breeze to go through.
auth0 for my login service
I have tried both AWS Cognito and auth0 before. But auth0 stuck with me because of how I quickly managed get it to work. Their docs feel overwhelming but they make up for it through their dashboard UX and easy to follow Quickstart. I will not go into the details of my setup in auth0 in this post, hopefully that will be for another post.
haiku.pro’s setup in Render
“Services” in Render can either be a: Web Service, Private Service, Background worker or Cron Job.
I am using Web Service and Private Service for haiku.pro. Setting this up in Render’s dashboard is straightforward. I haven’t tried creating a Background Worker or a Cron Job but I am planning to use them in the future.
Creating a service allows you to connect to your GitHub account and choose the repository of the service that you’d like to run. After connecting to GitHub, it will show you the autofilled service Settings. You can modify it according to your needs. It can also detect your Dockerfile and adjust the default settings accordingly.
You can then choose your plan which ranges from $7 to $175 per month. Plans below are for services that need compute resources. However, if your service is hosting a static site then it is free of charge. I am currently hosting my static personal website ardy.me in Render for free.
Advanced settings for auto-deploy for every push to your repo, health check, secrets, environment variables and so on.
After successfully creating your service, it will be:
- Publicly available from <your-service-name>.onrender.com if it’s a Web Service.
- Privately available from <your-service-name>:<port-number> if it’s a Private Service. It will be accessible from within your other services or from the Shell tab in Render.
The service dashboard has these useful functionalities like logging, mounting a disk for storage, adding environment variables and shell interface for debugging your service. There is also an option to create Environment Groups, which are basically a group of environment variables that can be shared across services.
Pull Requests tab allows you to preview your changes for your pull requests, it will create a new service instance so you can test your service. Sharing is for giving access to your team and Metrics tab shows you the CPU and memory usage.
In my project haiku.pro, I’m using a Web Service for my Web Frontend and Static Files, and a Private Service for my Web API Backend.
Render currently supports a fully managed Postgres Database Server. From their docs:
Your database comes with encryption at rest, automated backups, and expandable SSD storage.
Creating a new Database is even simpler than creating a new service with pricing plans similar to their services.
The guide here sums up how simple it is to set it up a database in Render.
Domain name configuration
Infrastructure as code
Render has its own YAML spec for Infrastructure as Code (IaC). I find this very useful as I don’t have to login to the dashboard and make changes using the web interface. I can have a YAML file that specifies the services I want to run with each of their own configuration.
Another nice feature that I like about using their YAML spec is that it allows me to pass around environment variables. For example, I can specify in my YAML that it should pass the database credentials as environment variables to my Private Service from my Database. That way, I don’t have to worry about copying and pasting my database credentials to the an environment variable in the Render dashboard. More about Render’s IaC here.
You can also add instances to your Service in render, which is automatically managed by Render’s load balancer. This part is not yet well-documented in Render’s doc but it’s definitely a handy feature.
A few other nice features worth highlighting
- No downtime deploys. Uses the health check URL that you specify for a service to ensure that the service is healthy before it is deployed.
- Deploy hooks. Render provides a private hook URL that you can use to trigger a deploy.
- Slack Notifications. Useful when you work with a team or if you want to implement alerting via Slack.
High level design with Cloud Services
There you go, I’m just getting started with Render. I’m quite happy with the results so far.
Hope you’ll have fun deploying your web application!
Check out my other post about software architecture:
Architecting a Scalable Software as a Service
Here are some of the best practices in architecting your Software-as-a-Service (SaaS) web application.