• Zed Ng
  • Posts
  • From Cloud Hostages to Self-Hosting Freedom: How I Secured My Next.js App on VPS with Dokku

From Cloud Hostages to Self-Hosting Freedom: How I Secured My Next.js App on VPS with Dokku

Hardening my Linux server, taking full control and securing my Dokku apps from vulnerabilities

Why migrate to self-hosting on VPS

For years, my Next.js app has been hosted on Vercel with its convenient push-to-deploy feature. I've also used PlanetScale for DB, but recently both PlanetScale and Vercel have changed their price plan recently, I was forced to choose between paying or migrating. I'm tired of being held hostage by these cloud providers, whose future strategies are still uncertain. To break free from this cycle, I've decided to move my data to a VPS, giving me full control and freedom from third-party constraints. This will save me time and allow me to focus on developing my product.

I initially thought setting up a Heroku like platform on VPS would be complex, but it turned out to be surprisingly straightforward. The biggest surprise was how much I saved on running costs - significantly lower than what I spent on cloud services. Instead of worrying about deployment complexity, I found myself focused on securing my Linux setup to prevent attacks and compromises. Thanks to Dokku, deploying apps is just as easy as Vercel's push-to-deploy, with the added benefit of flexibility across various technical stacks. Through this process, I gained valuable new skills, making it a meaningful experience for me.

My Requirements

Before setting up my own VPS, I outlined my requirements as follows:

  1. Security: I need a secure environment to prevent my server from being easily hacked.

  2. Usability: I want my server to be as easy to use as Heroku or Vercel, with push-to-deploy functionality, so I don't spend too much time on maintenance.

  3. Cost: My SaaS projects always start from a small scale, I want my apps to be able to run on cheap VPS.

  4. Flexibility: Although most of my apps are based on Next.js, I still wish my server to support multiple technology stacks, including Umami and n8n docker image.

  5. Scalability: As my business grows, I want my server to be easily scaled or migrated as quick as possible.

Harden and secure linux host

A hardened and secure linux is important, especially for SaaS projects where data breaches can be devastating. However, over investing in security can lead to high maintenance costs and usability issues. My goal is to strike a balance between simplicity, effectiveness, and cost reduction. As such, I have chosen some simple yet effective methods to harden my VPS:

  1. Use long-term support distros such as RHEL or Ubuntu server, with regular security patches. Remove unnecessary services , reduce access permissions to system files.

  2. Secure SSH by enforcing key-based login, disabling password login, restricting login IPs, and limiting login attempts.

  3. Enable SELinux.

  4. Implement intrusion detection and prevention systems such as fail2ban.

  5. Set up a firewall with minimum exposed ports.

  6. Install rootkit and backdoor scanners.

Dokku - Heroku compatible PAAS

Dokku is an open-source PAAS alternative to Heroku, helps you build and manage the lifecycle of applications from building to scaling. You can install Dokku on any inexpensive cloud providers or VPS. Dokku has the following features:

  1. Heroku/vercel like push-to-deploy experience, with support for various technology stacks such as Node.js, Ruby, Python, Java, PHP, Go, and more.

  2. Plugins, such as let's encrypt, postgresql etc. Allow you to easily extend its functionality.

  3. Deploy app by Docker images. This allows you to deploy applications by prebuilt Umami or n8n binary image.

  4. Convenient backup and restore. You can create a scheduled task to easily back up your application and data to a remote machine or even directly to Amazon S3, and also conveniently restore it.

Now I can effortlessly deploy my Next.js application to a low price $5 VPS as I previous did on Vercel!

Other Considerations

While Vercel touts edge performance, reality shows that factors like accessing other cloud databases can create significant bottlenecks. In my case, latency between Vercel and Planet Scale affects user experience, especially with Next.js's server-side rendering. Self-hosting has a natural advantage here, as my database and Next.js are directly on the same server.

I've chosen Cloudflare for my DNS and caching needs due to its free services and affordable pricing. With Cloudflare, I can enjoy free DNS resolution, SSL certificates and CDN caching, which accelerates static resources. Additionally, their WAF and tunnel provide an extra layer of security by hiding my app server completely, making it harder for hackers to target me.

Another concern with cloud services is reliability and scalability. For my SaaS project, a single server is sufficient, as I typically run multiple small projects rather than one large one. Dokku's application density makes it well-suited for this approach. If a project grows rapidly, I can easily migrate it to a delicated dokku server with k3s cluster. However, I prefer the simplicity of single-server over the complexity of Dokku k3s.

Many people worry about the reliability of VPS, but in fact, self-hosted servers are not that fragile and can run stably for months or even years. In case of server failure, I need to recover data quickly. A fact that many people overlook is that many cloud services' free or entry-tier plans cannot even guarantee 99.9% availability, which means 8 hours of downtime per year, with Dokku's backup plugin and service monitoring alerts, I have enough time to recover the service.

Final stack of self-hosted VPS

Conclusion

Although configuring each sub-module is relatively easy, integrating them to work together is a challenge. Many software packages have default configurations that open up unnecessary permissions and configurations, which might lead to security concerns.

Finally, I want to say that self-hosting might not suitable for everyone. If your project has a large user base or requires extremely high availability or unpredictable user growth, professional cloud services might be better choices. However, for micro SaaS or side projects, self-hosting is a perfect option for its low-price, flexibility and security.

Looking back on my experience, I'm thrilled that I made this decision. I can now rest assured that I have complete control over my hosting setup, without worrying about being locked into a specific service. I'll share more about each topic later, please feel free to subscribe to this newsletter.