recipes for docker-compose, svelte-kit, golang, pocketbase, python, ...
At SpinSpire, every year we take dozens of projects to production. But in order to get there, we have to build dozens of projects per month, only some of which gets released. In this process, we master several tech stacks. After going through this process many times we've made some common observations:
- The diversity of tech stacks is large, so no one person can master them all.
- On each stack we make the usual mistakes and then learn from them.
- This institutional knowledge needs to be codified and saved somewhere, ready to be retrieved and leveraged at a moment's notice.
- A library of foundational components and their bug fixes gets accumulated over time.
- We benefit so much from open source software (it's in our tagline - Open Source High performance Web & Mobile!), so we want to give our learning back to the community.
With those considerations in mind, I would like to introduce SpinSpire Recipes -- A git monorepo designed to kickstart any project with a working foundation of tech stacks involed. The stacks are pre-configured and even have a small library of components.
Docker & Docker Compose
We use Docker and Docker Compose to help provide a highly predictable, controlled, isolated, and hence secure runtime environment for all our apps.
docker-compose.yml file is provided for every container in the stack.
- uses small but battle tested ready-to-use Docker images and avoids building custom images from
Dockerfile(although sometimes that is exactly what you need for better control; but this method gets you started faster)
docker-compose.override.ymlfile that includes
labelsconfig to use
traefikreverse proxy HTTP requests
commandoverride to run in "live dev" mode so that code gets recompiled and reloaded on change.
entrypoint.shscripts for various containers to initialize (e.g. compile) a container at the time of startup.
svelte.config.jspreconfigured to use
adapter-staticin SPA mode (
+layout.tsturns off SSR, trailing slashes are on by default
- a prebuilt
+error.sveltepage ready to be customized
- Uses water.css for default styling and provides SASS &
app.scssfor custom styling
pnpmfor faster dependency management
- includes example
vitesttests for unit testing and
playwrighttests for end-to-end testing
- Has a library of components for alerts, modal dialogs, file upload, navbar, animated busy-indication spinners, and PocketBase client functionality.
- Example pages and routes for showing CRUD operations on a PocketBase backend.
PokcetBase & Golang (pb)
PocketBase is a self-hosted BaaS (backend as a service) which is very lightweight but provides a ton of features like a database (sqlite) fronted by a REST API, file uploads, email/3rd party single-sign-on, server push on data change, etc. Although a binary is provided, the best part is that it can be used as a Golang framework and extended without limits.
main.gothat leverages all the power of PocketBase as a framework (as opposed to binary program)
moddsetup for live development. Watches the code and on every file change to:
- re-run unit tests
- restart server
hooksimplementation to watch any table in the application and run external programs, webhooks, or send emails on insert/update/delete.
auditlogtable and corresponding hooks to keep a record of which user made what change to which table. This is turned off by default, but can be turned on by setting an environment variable.
- Go type to TypeScript type generation with
- PocketBase record to TypeScript type generation with
- Serve static frontend using
Python / FastAPI (py)
- Mount Python routes to a configurable prefix (e.g.
- More features to be added soon.
Metabase is a power BI (Business Intelligence) and data visualization platform.
- at this point, all we have is a metabase container that could then be used to visualize data from any available database.
How to use
- First of all, read the project README file to understand the technical details.
- Then use the excellent tool
degitfor copying entire repo or a part of it.
- It's a monorepo containing probably more than what you need. You can use the entire repo, or some part of it:
- entire repo:
npx degit spinspire/receipes myprj
- some part of it:
npx degit spinspire/receipes/sk myprj/sk
npx degit spinspire/receipes/pb myprj/pb
npx degit spinspire/receipes/mb myprj/mb
npx degit spinspire/receipes/py myprj/py
- entire repo:
- Then copy
.envand edit it to match your environment.
- Delete the folders for the stacks you don't need (e.g.
- Delete their configuration from
docker-compose.ymlfile and adjust
- Finally run
docker-compose up -dand watch the logs (
docker-compose logs -f) for a healthy compile and startup.
Browse the code and further delete what you don't need. And only after that, start building on top of it. Of course, reach out to me if any questions.
How it works
- docker-compose downloads and runs containers for NodeJS, Golang, and other technologies used in this.
labelsincluded, but not container definition) runs an HTTPS server exposing your project to the public internet and (reverse) proxies the incoming HTTPS requests as plain HTTP requests to your HTTP listeners (
py/etc). In the absence of
traefik, your servers receive HTTP requests directly from the browsers (e.g. in development)
[traefik https:443] --> [pb:8090] (prefix /apy) --> [py:8000] (prefix /mb ) --> [mb:3000]
- If you are doing active development in SvelteKit then make sure the
npm run devcommand entry is uncommented in
docker-compose.override.yml. The client are sent first to
sk's dev server (0.0.0.0:5173) which does HMR (hot module reloading) upon every change in the SvelteKit code. And due to the
vite.config.tsthis dev server can also proxy the
/_requests to PocketBase backend server. This technique completely sidesteps all CORS issues.
[traefik https:443] --> [sk:5173] --> (prefix /_ || prefix /api) --> [pb:8090]
- If you are ALSO using PocketBase as a framework and active Golang development, then make sure
moddcommand entry uncommented.
- If you want to see how this will all work in production, then comment out the
commandentries for both
docker-compose.override.ymlfile and use the one in the main
commandentries build both SvleteKit and Golang/PocketBase projects in fully compiled, release mode and thus should run faster. There is no vite/SvelteKit dev server and no
moddwatching for changes either. PocketBase then serves the bundled SvelteKit output from
[traefik https:443] --> [pb:8090] + (dynamic /api + static /sk/build)
- If you are using other stacks such as
mb, then we mount them at
/mbpaths within your domain by configuring
traefikto forward those path prefixs to their respective containers.
Coming soon ...
We will keep building up this repo, for our own sake as well as the community's. We will add many library functions and components. Also, other stacks:
Also, watch this space for a YouTube screencast tutorial video on how to take most benefit out of it.