Skip to content

Latest commit

 

History

History
237 lines (167 loc) · 10.4 KB

README.md

File metadata and controls

237 lines (167 loc) · 10.4 KB

Macadam

About

Macadam is a full-stack, software-as-a-service (SaaS) "boilerplate" application. It is meant to serve as a complete, exemplary, starting point for building new SaaS-type projects.

Project goals

  • Provide a complete, production-ready toolset to get a SaaS product started as quickly as possible, all parts included, using best practices.
  • Fully self-hostable in a Kubernetes environment.

Many "starter projects" and "boilerplates" are incomplete or contrived examples that will still require a huge amount of effort to get a production-ready MVP shipped. But most SaaS projects have a common set of features that will be needed for a maintainable, production-ready deployment, i.e.: authentication, logging, tracing, error reporting, analytics, unit testing, database interactivity, user-facing client(s), an API server, infrastructure, etc. Providing this base is the primary goal of the project.

This is not meant to be highly configurable with a many options available to the developer from the outset. Some tooling can be easily swapped out, while other pieces may require significant work. But ultimately it is, by design, very opiniated.

Getting started

Prerequisites

The only prerequisite to getting a fully-usable environment up and running is a Docker environment with Docker Compose capabilities.

Starting a development environment

  1. Clone the repo (i.e. git clone https://github.com/joekrill/macadam.git)
  2. docker compose up

The resulting web application will be accessible by visiting https://localtest.me in your browser.

Any mail sent during development will ba accessible using a local maildev instance by visiting https://mail.localtest.me.

TLS

The auto-generated certificates will not be trusted by default and you will need to manually trust them. Alternatively, you can add the underlying Caddy certificate authority as a trusted root on your local machine.

# On MacOS
docker cp $(docker-compose ps -q caddy):/data/caddy/pki/authorities/local/root.crt /tmp/macadam_caddy.crt && sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/macadam_caddy.crt

# On Linux
docker cp $(docker-compose ps -q caddy):/data/caddy/pki/authorities/local/root.crt /usr/local/share/ca-certificates/macadam_caddy.crt && sudo update-ca-certificates

# Firefox on MacOS - `security.enterprise_roots.enabled` must be `true` in `about:config` (see https://support.mozilla.org/en-US/kb/setting-certificate-authorities-firefox for other OSes)
docker cp $(docker compose ps -q caddy):/data/caddy/pki/authorities/local/root.crt ~/Library/Application\ Support/Mozilla/Certificates/macadam_caddy.crt

Running additional services

Some services are not run by default in the development environment. These can be include by passing the appropriate profile to docker-compose. For example, to run a Storybook instance:

docker compose --profile storybook up

Multiple profiles can be passed:

docker compose --profile storybook --profile metrics up

Available profiles:

  • analytics runs a Plausible Analytics instance and it's depdenencies.
  • error-tracking runs a GlitchTip instance for collecting crash and error reports.
  • metrics runs Prometheus and Grafana instances.
  • storybook runs a Storybook instance for explorting the web application UI components.

Development URLs

Useful commands

Commands using exec assume that the accompanying service/container is up and running. In most cases exec can be replaced with run to start the command in a new container.

  • Connect to Redis via redis-cli:

    docker compose exec redis redis-cli
  • Create/update the plausible database seed file:

    docker-compose exec postgres pg_dump -U plausible plausible > services/postgres/imports/plausible.sql

Project Structure

Macadam is a monorepo that uses Yarn Package Manager and it's workspaces feature to organize code and provide tooling and scripts.

The basic folder structure highlighting the most important paths:

├── docs
├── packages
│   ├── api-server
│   ├── client-web
├── services
│   ├── caddy
│   ├── clickhouse
│   ├── glitchtip
│   ├── ...
├── package.json
├── docker-compose.yml
  • docs/ - project-level documentation
  • packages/ - the root folder that contains individual yarn workspaces
  • packages/api-server/ - source code for the API server
  • packages/client-web/ - source code for the frontend web client
  • services/ - configuration, scripts, and other files needed for running external services.
  • package.json - root-level package.json
  • docker-compose.yml - docker compose definition for the default development environment.

Core Services

Macadam is built as a series of (micro)services that can roughly be broken down into:

  • Web Client
  • API Server
  • Database
  • Authentication
  • Error Reporting
  • Analytics
  • Metrics
  • UI Component Explorer
  • Gateway Web Server
  • Mail Interceptor (development)

Web Client

The frontend web application (found at packages/client-web) is a Typescript application bootstrapped with Create React App.

API Server

The backend API servier (found at packages/api-server) is NodeJS application built using the Koa framework.

Database

PostgreSQL is used by the API server, Kratos, Plausible Analytics, and GlitchTip. Each application is it's own database

Authentication

Identity & User Management is implemented using Ory Kratos - a cloud native user management system.

Error Reporting

GlitchTip is used for error reporting collection and analysis. GlitchTip is a branch of, and (currently) compatible with, Sentry.io - and the reporting clients use the Sentry.io SDKS. Switching to Sentry would simply require changing the DSNs used.

Analytics

TODO: Plausible Analytics

Metrics

TODO: Prometheus/Grafana

UI Component Explorer

Gateway Web Server

In development, Caddy acts as the gateway web server and routes all incoming requests. services/caddy/Caddyfile tells Caddy how to do this.

Development Services

Mail Interceptor

In development, all mail is routed through Maildev, which allows viewing emails in the browser by visiting https://mail.localtest.me.

Maildev

pgweb

pgweb is a web-based client for PostgreSQL. This allows browsing and querying the database directly to aid in debugging and development. Visit https://pgweb.localtest.me to access the running pgweb instance.

Starting a new project

git clone https://github.com/joekrill/macadam my-new-project