# 100% FREE Deployment for your  full-stack web application

So you are done building your next unicorn startup and ready to deploy your awesome web application. Congratulations 🎉. You're in the right place. By the end of this article, we will get you up and running with a domain name, a custom professional email (e.g., welcome@my-super-awesome-app.tk) for sending emails, storage for your image uploads, deployment for your frontend & backend, and a database for sure. Let's get started.

We will not go through the process of building the web application. We already have a web application ready for deployment. I created this app, especially for this demo. So feel free to use it to follow up throughout the tutorial.

Frontend: [My Super Awesome App](https://github.com/kerolloz/my-super-awesome-app).  
Backend: [My Super Awesome API](https://github.com/kerolloz/my-super-awesome-api).

## An overview of the web app we're deploying

It's a simple web blog where users can:

- Signup using their name, email, and password.
  - Upon signup, the user receives a verification email, clicks the email confirmation link, and verifies their account.
- Login with their email and password after verification.
- Post articles (with optional image uploads).
- Get the list of posted articles.

### Tech stack

The frontend is built using *Svelte*. I used *Tailwind* for styling. I made a simple RESTful API for the backend with *Node.js* using *Express.js*. As for the database, I am using your-all-the-time-favorite database *MongoDB*. I am using the coolest stack ever 😎, the MESN (MongoDB, Express.js, Svelte, Node.js) stack.

Please note that using the MESN stack is unnecessary. The services we use for deployment do not require the usage of a specific stack. You can use almost any programming language, stack, or framework.

## The Free Services

We're using several services that provide a free tier.

- *Freenom* for the domain name.
- *Imgbb* for image uploads.
- *MongoDB Atlas* for the database.
- *Twilio's SendGrid* for sending emails using our custom domain name.
- *Render* for backend deployment.
- *Cloudflare* for the following:
  - DNS Configuration.
  - Frontend deployment.


### Domain Name

We will use 2 services to complete the domain name setup. The first service is Freenom, and it's where we get our free domain name from. The second service is Cloudflare. We will use the DNS management service provided by Cloudflare to manage the DNS configuration of our domain.

Let's get our domain name first from *Freenom* and then add it to *Cloudflare*. Freenom gives you a free domain for a maximum of 12 months. You can choose a domain that ends in any of these 5 TLDs: `.tk`, `.cf`, `.ml`, `.ga`, and `.gq`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1661096905141/sUoQJEQZz.png align="center")

> Freenom is the world's first and only free domain provider. Our mission is to bring people online and help countries develop their digital economies.

- Go to https://freenom.com and check the availability of your desired domain name, then click `Get it now!`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1661166303012/-XOXRIA2V.png align="center")
- Click `Checkout` and choose the `12 Month @ FREE` period. Click `Continue`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1661171087140/QlusXmuLd.png align="center")

- Enter your email address and click `Verify My Email Address`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668956509467/4eEwfRsdz.png align="center")

- Go to your inbox and click the link to confirm your email address.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668956787424/s-azEIddT.png align="center")

- Clicking the verification link will lead you to the following page. Enter your details, check the `I have read and agree to the Terms & Conditions` checkbox, and click `Complete Order`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668958018752/vpASbEjBB.png align="center")
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1661274095529/4hKIqz4k1.png align="center")

- From `Services`, select `My Domains`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1666620602578/DTBGtmTjj.png align="center")
- Choose your domain and click `Manage Domain`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1666536424603/UYKltn55i.png align="center")
- From `Management Tools`, choose `Nameservers`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1666620670970/Hf-P0FzN5.png align="center")
- Choose `Use custom nameservers`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668599174632/vDV0K2S-d.png align="center")

We need to get these custom nameservers from *Cloudflare*.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1666627934942/WVe_rq53N.png align="center")

> Cloudflare, Inc. is an American content delivery network and DDoS mitigation company, founded in 2010. It primarily acts as a reverse proxy between a website's visitor and the Cloudflare customer's hosting provider.

- Head to https://dash.cloudflare.com/sign-up and create your account. Make sure to verify your email address.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1666628181752/CdEbeh9g9.png align="center")

- Choose the `Websites` tab and click `Add Site`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1666628484040/M5_KoQtfK.png align="center")

- Enter the domain name you got from *Freenom*. Click `Add site`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668599496018/yxgAhf6Pq.png align="center")

- Choose the Free plan and click `Continue`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668600402601/EEOYFq9Ib.png align="center")

- Cloudflare will check if there are any DNS records associated with your domain and add them automatically. Nothing appears here since we do not have any yet. Click `Continue`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668600560528/idGx7bANZ.png align="center")

- We will add the DNS records later, so click `Confirm`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668600646372/V0ErpNZ4K.png align="center")

- Copy Cloudflare's nameservers and add them to Freenom.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668600824482/J1nLNVo3g.png align="center")

- Click `Change Nameservers`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668600896086/OOP2OlxGc.png align="center")

- After changing our nameservers on Freenom, go back to Cloudflare and click `Done, check nameservers`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668601054062/vMVRlReNK.png align="center")

- Feel free to go through the *Quick Start Guide*. I will choose `Finish later` for now.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668601215934/nKjSuoU3oA.png align="center")

- The nameserver changes can take a few hours. It's usually a matter of a few minutes, but it depends. Click `Check nameservers` to see if the nameserver updates have been processed and refresh the page.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668601493657/_Gl0kc4ZE.png align="center")

- If you get the following message, we're good to go.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668601574946/qDwiA5Bez.png align="center")

### Image Uploads

![imgbb logo](https://simgbb.com/images/logo.png align="center")

>Imgbb is a free image hosting and sharing service where you can get free storage for your pictures. The greatest thing about *imgbb* is its simple API.

- Go to [imgbb](https://imgbb.com/signup) and create your free account.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1661064344558/FGx55a6Yk.png align="center")
- You will receive a verification link in your email. Clicking the verification link will log you in automatically.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1661064474447/nTkx1IHYr.png align="center")
- After logging in, all we need to do is head to [api.imgbb.com](https://api.imgbb.com/) and click `Get API Key`
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1661064629595/yXaiYaZz9.png align="center")
- Copy the API key and save it. We will use it later when we get to backend deployment.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1661064807168/rBCRr9U4q.png align="center")

You can look at my [code](https://github.com/kerolloz/my-super-awesome-api/blob/master/src/services/ImageUploader.ts#L12-L20) to see how I upload images to *imgbb*. There's an [NPM package](https://www.npmjs.com/package/imgbb-uploader) for that.

### Database

We will be using the well-known NoSQL database MongoDB. MongoDB Atlas offers a free tier. The free tier has 512MB of storage which is enough for our demo.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1666526223964/Y6RtrZ4_B.png align="center")

>MongoDB Atlas is a fully-managed cloud database that handles all the complexity of deploying, managing, and healing your deployments on the cloud service provider of your choice (AWS, Azure, and GCP). MongoDB Atlas is the best way to deploy, run, and scale MongoDB in the cloud.

- Go to https://www.mongodb.com/cloud/atlas/register and create your Atlas account.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668958716985/QDF8pyTJy.png align="center")

- Check your inbox and click the verification link to complete your registration.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668958883615/NTjzvn0DW.png align="center")

- After successfully verifying your email, click `Continue`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668959033544/AcV3qbVZv.png align="center")

- Complete the required info here and click `Finish`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1666528603631/r4QGWiU6X.png align="center")

- Choose the FREE `Shared` option and click `Create`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668959508699/8yHVsQG7k2.png align="center")


- Click `Create Cluster`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1666528821170/mWW7jDgdE.png align="center")

- Choose the `Username and Password` authentication option and follow the instructions to create a database user using a username and password. Make sure to keep your credentials safe because we will need them later. Click `Create User`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1666528978435/2dqQSyqKC.png align="center")

- Go to the `Network Access` tab and click `Add IP Address`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1666529205933/Iyl01-O8m.png align="center")

- Choose `ALLOW ACCESS FROM ANYWHERE` and click `Confirm`. Please wait for it to finish deploying the changes to your cluster.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668959993795/P6ZZzFqAs.png align="center")

- Go to the `Database` tab and click `Connect`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1666530021212/lhTO4yWZp.png align="center")

- Choose `MongoDB Drivers`. 
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668960236102/cVZdXS0PR.png align="center")

- Copy the connection string and keep it safe. We will use it later during the backend deployment. **Do not forget to replace the `<password>` part with your password**.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668960522691/MKGCVLvAh.png align="center")


I use Mongoose to [connect to MongoDB Atlas](https://github.com/kerolloz/my-super-awesome-api/blob/master/src/database.ts#L7).

### Sending Emails

We need 2 services to set up sending emails from our app (for email verification purposes). We need a Sendgrid account and a Cloudflare account which we already have. So we need to create a SendGrid account first.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668618974674/OEvdTseyQ.png align="center")

> SendGrid (also known as Twilio SendGrid) is a customer communication platform for transactional and marketing email.

- Go to [signup.sendgrid.com](https://signup.sendgrid.com/). Fill in your data and click `Create Account`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668619466113/XVqs01Pwv.png align="center")

- Complete the required inputs and click `Get Started!`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668619621271/wNt67dF4B.png align="center")

- Confirm your account email address. Check your inbox for the confirmation email.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668619988695/LA8_OMA3F.png align="center")

- After signup, you will have the following setup guide. Click `Authenticate a domain instead`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668620143670/8ZBJ1IE-t.png align="center")

- Choose *Cloudflare* as the DNS host. Click `Next`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668620575421/6gcc2arbS.png align="center")

- Type your domain and click `Next`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668620654596/j50BgnstN.png align="center")

- We need to copy these DNS records to Cloudflare.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668684329057/3UjEVNe3Z.png align="center")

- On Cloudflare, go to the DNS tab on the left-side pane or click the DNS Settings link on the right-side pane.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668620893309/88sjroDUe.png align="center")

- Click `Add record`. Choose the `CNAME` type, copy and paste the name and target values from SendGrid to Cloudflare, and hit the `Save` button. **Make sure you toggle off the orange cloud button to tell Cloudflare not to proxy it; treat it as "DNS only".**
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668684743159/cyfibjtVr.png align="center")

- Your DNS records should look like this after copying the values from SendGrid to Cloudflare.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668685088479/n80GbPRER.png align="center")

- Back to SendGrid, check the `I've added these records` checkbox, and click `Verify`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668685261143/CjlvN10kr.png align="center")

- The following message should appear.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668685345162/tcsvFKY84.png align="center")

- Now, we need to get our API key from SendGrid. Go to https://app.sendgrid.com/settings/api_keys. Click `Create API Key`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668685793658/KI-wztJoR.png align="center")

- Enter your API Key Name, then hit `Create & View`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668685860989/RSM4aAcXY.png align="center")

- Copy your API key and save it for later. Click `Done`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668686178661/E8HuYlKkP.png align="center")

This is [how I use SendGrid](https://github.com/kerolloz/my-super-awesome-api/blob/master/src/mailer/base.mailer.ts#L18) to send emails.

### Backend

Now we're ready to deploy our backend code. We've got what we need:

- ImgBB API key for image uploads ✅
- MongoDB Atlas connection string for the database ✅
- SendGrid API key for sending emails ✅

We will use *Render* to deploy our backend API. I used to deploy my apps to *Heroku* but, unfortunately, free Heroku is not an option anymore.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668690518144/GmTW4udPQ.png align="center")

>Render is a unified cloud to build and run all your apps and websites with free TLS certificates, a global CDN, DDoS protection, private networks, and auto deploys from Git.

- Go to https://dashboard.render.com/register and create an account.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668767640090/B7OwmWSii.png align="center")

- Check your inbox for the verification email.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668767754558/SbOc4nHSq.png align="center")

- You will be logged in after clicking the link in your email. Click `New Web Service`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668767922074/VIhIKwE9A.png align="center")

- You can choose a public git repository or connect to GitHub or GitLab and choose one of your repositories.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668768071628/1geV2mMFn.png align="center")

- I chose a repository from my GitHub account.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668860884027/sVbYuTF5w.png align="center")

- Add a unique name for your web service. You can edit the other configs, but in my case, I will leave it as is.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668768567726/UKPHnsuKo.png align="center")

- Scroll down to the bottom and click `Advanced` to set the environment variables required for our API to run properly.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668768692519/dA8N5E_vb.png align="center")

- There are two ways to accomplish the same goal (adding env vars). You can click `Add Environment Variable` and add them one by one, or click `Add Secret File` (a *.env* file in my case because I have it [loaded automatically](https://github.com/kerolloz/my-super-awesome-api/blob/master/package.json#L7) on API startup).
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668860717835/rXCA_NHgE.png align="center")

- I will choose `Add Secret File`. Add filename and file contents, then click `Save`. ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668860761551/m1jm0hlvm.png align="center")

- Click `Create Web Service`. 
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668861619999/SvEdfmlFr.png align="center")

- You might want to read about [free plan limits on Render](https://render.com/docs/free) while it's deploying our API.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668771216315/1Yf9jc52T.png align="center")

- It's LIVE! Our API is up and running now. Only one more thing to do. Go to the `Settings` tab.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668774266260/7qhtaViaW.png align="center")

- Scroll down to *Custom Domains* and click `Add Custom Domain`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668774316918/ZfwVZUL9e.png align="center")

- I want https://api.my-super-awesome-app.tk to be the custom domain for the API. Click `Save`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668774409874/1ZkOGYydD.png align="center")

- Follow the instructions and add the CNAME record to Cloudflare as we did earlier with SendGrid. For further info, see https://render.com/docs/configure-cloudflare-dns.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668774550635/urv2__IiE.png align="center")

- On Cloudflare, go to DNS settings and add the CNAME record. Click `Save`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668774704883/CTQDUtgIQ.png align="center")

- Now go back to Render and click `Verify`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668774774451/9dp9ZxgZ3.png align="center")

- You should see that it is `Verified` now.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668774786850/LtEoBzNpA.png align="center")

### Frontend

To the final step 🥁. We will deploy the frontend part of My Super Awesome App. As we mentioned at the beginning of the article, we will use [Cloudflare Pages](https://pages.cloudflare.com/) to deploy our frontend. Cloudflare Pages is part of your Cloudflare account, so there are no more registrations.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668775537673/r4eaxZigL.png align="center")

> Cloudflare Pages is a JAMstack platform for frontend developers to collaborate and deploy websites. Build fast sites. Deploy frontend applications in record time.

- Head to https://dash.cloudflare.com/?account=pages. Click `Create a project`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668775853415/MfnFjio3y.png align="center")

- You have various options to deploy your frontend, but the super awesome frontend is available on GitHub so I will go with that.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668775778909/vvOi3bF9n.png align="center")

- Choose your frontend repository. Click `Begin Setup`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668776469385/c0n4i8krN.png align="center")

- Change build settings to fit your case. In this case, I set the framework to `Svelte` and the output directory to `dist`. I also added 2 env vars to set the base API URI to which the frontend will send requests and the NodeJS version to be used during the build process. Click `Save and Deploy`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668777508808/mO3EDJSTt.png align="center")

- After a successful build, you should see the following. Click `Continue to project`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668777731343/GOJHJlphU.png align="center")

- The last step here is to link our frontend to our domain. Click `Set up custom domain`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668778034934/Y_mwzTKKw.png align="center")
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668778090757/lI-skcHyP.png align="center")

- Add your custom domain name and click `Continue`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668778130796/jL8U1eajz.png align="center")

- Click `Activate domain`.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668778162275/Kd-nqOBgP.png align="center")

- Woohoo! 🥳 Our frontend is now connected to our custom domain https://my-super-awesome-app.tk.
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1668778415308/fv3FIYamW.png align="center")

Go to https://my-super-awesome-app.tk and see the app come to life ✨. Congratulations on deploying your full-stack app for FREE. I hope you enjoyed this tutorial. I can't wait to hear your feedback and feel free to reach out to me if you get stuck on any step.

P.S. If you reached the end of this article, you are a Super Awesome Human Being ❤️.
