Self-hosted Next.js with Kamal 2 and Cloud VMs: 100x Builder Playbook
Ship your products in days. Say goodbye to Server-phobia!
Hello! Thanks for your time reading this book.
It is late 2024 and obviously we have a lot of challenges across the world: The inflation has not stopped. The money is harder to borrow. Tech companies have tighter budgets.
But one thing is unchanged: People expect more value from whatever things or services they purchase.
As a tech worker and creator, I believe we need to adapt to these challenges and build more with less effort.
Instead of only shipping fast, we need to really build, iterate with mature tech stack, with lower computing cost, i.e. bare metal or cloud VMs.
Developing software applications is not as expensive and slow as before, with the growth of Large Language Models.
Meanwhile, more and more new tech stacks are created to facilitate the development.
However, we have been educated for something like "DevOps is expensive and risky", "You should be serverless".
I was convinced once before. I tried a lot of different serverless stacks from Google App Engine but haven't got one suitable for my business. In recent years, we have a lot of other options like Vercel. With all respect to their efforts of great dev experience, I still believe serverless is not a sustainable way to build things.
Earlier last month, DHH at 37signals/basecamp released Kamal 2, based on Kamal (MSRK) released last year. It has a huge new feature, which allows you to deploy multiple different web applications on a single Linux machine. This was actually possible with Kamal 1 but requires many hacks.
For one-person or few-people teams, this is a useful change. Because you can even save more in early-stage projects.
At the same time, Sahil Lavingia, the CEO of Gumroad had several streaming of live coding with Cursor and Next.js with in-production examples, which is super productive, as long as you have basic knowledge with TypeScript (or JavaScript), CSS, and a little bit command line.
Currently, one of the perfect stack for growing projects for small teams, which can be delivered quickly, is Next.js, delivered in Docker, using Kamal 2.
Before we start, I want to introduce myself. I was born in the 1990s and started to code and use the internet quite early, in 1999, when my father started to apply for a master’s degree. At that time, we didn’t own any computers at home. My father and I went to the internet cafe to get information.
After graduating from school, I went to Microsoft, worked on several different projects, including Outlook iOS, Android, Mac, Web, and OneDrive/Sharepoint Web. I have seen many million-line code projects (obviously both Outlook and OneDrive). And a fun fast is you can find all source maps for the client code at photos.onedrive.com. These projects are cash cows for the company. But I don’t think they’re on the right path for software development. In short, the execution is too slow and you cannot see tech is contributing to the success, at least as of today. These projects have good code, relatively modern design. But I feel it is wrong, especially with the evolution of AI. So I left Microsoft to start my own business.
This tutorial (also a community) is the very first part of thoughts and sharing of a real-world tech stack which is more pragmatic than 99% of the others. It not only aims to ship things fast, but with low cost (both in terms of time consumed and runtime cloud expenses). Because as Jeff Bezos said, “your margin is my opportunity”. If your competitors are in Vercel, or Azure/AWS, you’ll have many more opportunities while using this stack (Next.js + Kamal 2). I’m confident it can work even before our IPOs : )
Thanks for reading this initial part. Hope you’ll enjoy it.
Now, let’s focus on tech.
Technical requirements
This book is mainly on technical stuff. These’re some requirements:
- Hardware: A computer which can run Ruby, Docker, Node.js, usually Windows/Mac/Linux are all perfect for this.
- Knowledge:
- Minimal or no knowledge of Ruby
- Node.js (required for build products with Next.js)
- Next.js or other Node.js frameworks like Express.js
- Basic Linux/Docker
Please make sure you have Docker (or Docker Desktop) installed on your local machine. If not, it is also acceptable to use a remote docker environment on a Linux machine as a “builder” (we’ll get into this concept in the Kamal 2 part).
If you found this book might not be suitable for you, don’t worry, as long as you don’t finish over 30% of this book, you can request for a refund within 7 days for purchase.
If you want to keep this book accessible, but still have some suggestions or difficulties, please comment below this page and we’ll help you.
Quick Start: Minimal Next.js in Production, within 15 minutes
We don’t want to hold you for too long before hitting production. So for the very first project, let’s start a minimal Next.js project, and deploy it to production instantly. Usually in many books, the last section is about deployment to production. In that way we cannot ship fast.
I believe the best pace for development is shipping to production instantly after you make sure the code is finished and have low chance of regression.
Assuming you have all dev environments ready and a cloud server (like a virtual machine on DigitalOcean, OVH, Hetzner, .etc), we can 100% make it deploy within 15 minutes. For the second time, you may only need 5 minutes to make it work. Once you get used to it, you won’t lose any momentum of building products!
So let’s deploy first!
Start a Next.js Project
You can start a Next.js project using this command: npx create-next-app@latest next-kamal-playbook-minimal-demo
If you’re not familiar with this process, you could read the official doc for Next.js, https://nextjs.org/docs/getting-started/installation
The output would be like
➜ next-playground npx create-next-app@latest next-kamal-playbook-minimal-demo
Need to install the following packages:
[email protected]
Ok to proceed? (y) y
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use \`src/\` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/\*)? … No / Yes
✔ What import alias would you like configured? … @/\*
You could choose customizing the default import alias or not. It does not matter much for the current state and we can always change it later.
Next step is to make sure the minimal demo is running. You can change into the next-kamal-playbook-minimal-demo
directory (on Linux/Mac/Windows, you can also run cd next-kamal-playbook-minimal-demo
in the terminal), then run npm run dev
.
When open http://localhost:3000
, you can see the initial screen of Next.js. That means this project is running.
We don’t want to change any Next.js code in this part. Instead, we’ll add a Dockerfile
to the root of this project. You could use VSCode/Cursor or Vim to add this file with these contents: