Limboy

Rebuilt this site for the next decade using Astro

This site previously used Zola as its blog engine (you can read here for more details), along with:

This architecture had been running for about 3 years. Mostly satisfied. Zola build fast, its functionality was basically adequate, with Deno, I could write API for frontend page. Using Alpine.js and Tailwind CSS, I could create frontend pages quickly.

However, it wasn’t perfect, mainly for these reasons:

After some investigation, I decided on Astro as my new site engine.

However, making this transition wasn’t easy. On one hand, I was familiar with the current tools and workflow. Though it was missing some features, but it was tolerable. On the other hand, it would take time to become familiar with new tools, build a new workflow, and transfer the content.

After a period of deliberation, I decided to make the switch.

Design

The new site is separated into 3 parts: essays, comments and stream. Essays are articles I write on specific topics, stream is mainly for life activities, like books, photos and thoughts. Kind of facebook homepage, but just for myself.

Essays are written in MDX and generated by Astro. Stream contents are stored in PocketBase and rendered dynamically via Astro’s SSR. These contents are created using PocketBase’s built-in GUI. Comments are also stored in PocketBase, using PocketBase’s API.

Development

Astro’s Developer Experience is really good. It may take some time to get familiar with its directory structure, design philosophy and API. But once you get through this stage, you gain power. Thanks to the well-written docs and GitHub issues, whenever I encountered a problem, there was usually a solution.

It took me 5 days (working full-time) to design, develop, and transfer content. It wasn’t easy, but as the foundation for the next decade, it was worth the effort.

Deployment

This site is served on a VPS, so I chose Node as the adapter. In theory, it’s simple to deploy: just run pnpm build and node ./dist/server/entry.mjs, then make Nginx point the domain to the port. But reality taught me a lesson. When I ran pnpm build, it took nearly 8 minutes and failed, due to running out of memory.

My first thought was that it allocated too much memory when optimizing images, so I set limitInputPixels: 10000 (100x100) in astro.config.mjs to tell Sharp not to process large images. It didn’t work.

Then I found someone mentioning a command option --experimental-static-build that might fix this scenario, but still, it didn’t work.

When I only left 1 post for Astro to build, it worked, though it still took about 5 minutes.

I was kinda desperate then, even considering rolling back to Zola, which at least wouldn’t cause these issues. This thought lingered for a while before I decided to overcome the problem.

since it could build on my machine, why not just skip the build process on the server and use my machine’s build result? So I put the dist directory in git, and on the server side, I just ran node ./dist/server/entry.mjs. Guess what? it worked! Though it was a bit quirky.

Just as I thought the mission was complete, something else happened. I wanted to write some cache files to the local disk. So I created a .env file, set the cache path, then built and pushed to the server. Server crashed. After digging into the logs, it turned out the cache path was still my machine’s path instead of server’s path defined in the .env file.

The .env file is read at compile time, not runtime. I could remedy it by replacing all the env content before running, but it would be ugly and could lead to potential bugs.

Just when I was at my wit’s end, Bun saved me. Bun is known for its speed and efficiency, and Astro supports Bun, so I decided to give it a try. I ran bun install and bunx --bun astro build. Literally just these two commands, and it worked!

There were still some minor scenarios to handle (e.g. import.meta.env is different when using Bun), but the deployment section basically came to an end. Bun is not only fast but also resource-efficient. In the future, I will prefer Bun over Node.

Conclusion

Astro as a meta-framework fully meets my requirements. PocketBase, combining data storage and CMS in a single file, is really convenient. I hope this new system can help me create more and better content in the future.