Up and Running with CloudSeed (F# / SvelteKit boilerplate)
Date: 2022-11-31 | cloudseed | fsharp | sveltekit | docker | containers
I build a lot of projects - from tiny businesses to creative technology. I've found that a lot of my time spent on a porject (sometimes upwards of 50%) often goes towards setting up the core project infrastructure / hosting.
So I put together a project boilerplate using the best technologies / techniques I've found to speed up the process - move fast, with stable infrastructure. In this post, we'll walk through the CloudSeed F# / SvelteKit boilerplate and how to start developing with it.
CloudSeed is a project boilerplate built with F# / SvelteKit.
CloudSeed's mission is to be the paved road for 95% of projects.
- Simple - Easy to reason about and extend
- Reliable - Use boring, battle-tested technologies and techniques
- Powerful - To extend, modify, scale etc
CloudSeed System Architecture
CloudSeed's values are reflected in the architecture and technology choices used to build it.
It features a lean, modular 3 component architecture which fits 95% of projects out of the box. The modular design allows for easy composition of components to spin up full environments and configure for your usecase.
- Backend - Robust business logic engine built with F# / .NET. .NET is highly scalable with a large ecosystem of libraries and developers, F# is C# but better.
- Frontend - A lean (almost anemic) frontend built for simplicity / replacement with SvelteKit. CloudSeed aims to be an API first boilerplate so it should be easy to replace this frontend with the framework of your choice.
- Persistence - A containerized Postgres instance for "true" e2e testing. Swap out with your DB of choice with minimal impact on the rest of the stack.
Each of these components are fully containerized with Docker, composed locally with docker-compose, and configured with env files. This makes it easy to run anywhere - whether it's local dev or hosting on a public cloud.
Next we'll walk through some specifics of each component.
CloudSeed - Backend
We consider the backend to be the core of the app. Typically this will be built as an API server that the rest of your system can connect to.
F# is a relatively small language in terms of adoption but brings with it the power of the .NET ecosystem effectively giving it access to everything C# has and the financial backing of Microsoft. Where I think it beats out C# is its excellent type system, functional-first paradigms, and extreme lack of paradigms. I find that this leads to better code faster.
For libraries, we're relying on the simplest, most trusted libs out there. No magic, just logic.
- Language / Runtime: F# / .NET
- Web Server: Giraffe on ASP.NET
- Data Layer:
- ORM: Dapper
- Migrations: DBUp
- Testing: XUnit (with FsUnit)
For a better idea of what a backend written in F# looks like, check out Build a simple F# web API with Giraffe
CloudSeed - Frontend
We consider the frontend to be an implementation detail of the system. We need a frontend interface to be usable by our end users but most of the heavy lifting should be done serverside in our app. This becomes more apparent when we consider that systems of scale will often support many different kinds of interfaces (web, mobile web, mobile app, pwa) all with a same / the similar API.
As such, we've provided a simple, lean frontend with the basic things you'll probably want in 95% of projects so you can scale fast but you could also scrap it entirely and still get most of the benefits by just using the Backend.
We chose SvelteKit for this frontend as it's the simplest frontend app experience we've found (and devs seem to agree - read: Svelte is better than React). It inclludes things like serving on Node for performance / flexibility, Tailwind for styling, and a simple markdown processor for content serving.
- Language / Runtime: SvelteKit with Typescript
- Styling: Tailwind
- Other features:
- Markdown (Svelte w MDsvex)
CloudSeed - Persistence
When you move to host your apps somewhere, you likely won't have much need for a containerized db. But the first step for basically every app (and feature) is to develop e2e locally first. That's why we include a fully containerized DB running Postgres - so that you can dev with a complete stack and ship faster.
Not everyone wants to use Postgres which is fine - you can easily swap it out for a containerized version of the DB you want (MySQL, Redis, MongoDB, etc) and configure it with docker-compose.
The latest instructions for getting started with CloudSeed will always be available in the official CloudSeed documentation. But we'll pull out a simplified version here for ergonomics.
In order to successfully run CloudSeed, there are a few requirements:
- Docker - to run the individual service containers
- Docker Compose - Which we use to compose the containers for local dev
Once those are installed, we can get the CloudSeed codebase and spin it up locally.
- Get CloudSeed: Clone the CloudSeed repo (linked from CloudSeed Documentation)
- Run CloudSeed:
- From CLI:
docker-compose down --remove-orphans && docker-compose build && docker-compose up
- This spins down and cleans up any existing CloudSeed instance, builds new contianers, and spins them up
- If using VS code you can run this task which handles the CLI command for you:
- Run Task:
- Run Task:
- From CLI:
If all goes smoothly, you should now be able to access each service at:
- Health endpoint:
- Health endpoint:
With that, you should have a good understanding of what CloudSeed is and how to use it.