Skip to content

Bauhaus is an opinionated set of foundational modules to optimize DevOps experience with Clojure-based services.

Notifications You must be signed in to change notification settings

gorillalabs/bauhaus

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

17 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Bauhaus

Bauhaus is an opinionated set of foundational modules to optimize DevOps experience with Clojure-based services.

Overall design

Bauhaus is a set of modules that are designed to be used together. The modules are designed to be used with Integrant, but can be used without it.

It is the distillation of the experience of running Clojure services in production in several different organizations.

Why "Bauhaus"?

Named after the influential design movement, Bauhaus emphasizes functional design, modular composition, and practical utility. Just as Bauhaus architecture focused on essential functionality without unnecessary ornamentation, this framework provides essential infrastructure without bloat.

"Form follows function" - applied to Clojure application architecture.

Repository Structure

This is a monorepo containing multiple modules and example applications:

bauhaus/
β”œβ”€β”€ modules/                    # Reusable Bauhaus modules
β”‚   β”œβ”€β”€ setup/                 # Application setup utilities
β”‚   β”‚   β”œβ”€β”€ logging/           # Logging infrastructure
β”‚   β”‚   β”œβ”€β”€ shutdown/          # Graceful shutdown hooks
β”‚   β”‚   └── cli/               # Command-line interface
β”‚   β”œβ”€β”€ dev-tooling/           # Development utilities
β”‚   β”‚   β”œβ”€β”€ config/            # Configuration management
β”‚   β”‚   └── build/             # Build and deployment
β”‚   └── clojure-contrib/       # Clojure utility extensions
β”‚       └── collection/        # Collection utilities
β”œβ”€β”€ applications/              # Example applications
β”‚   β”œβ”€β”€ example/              # Basic Bauhaus application
β”‚   └── example-http-service/ # HTTP service example
└── docs/                     # Documentation

Usage

There is an example application showing usage in applications/example and an example http service showing more elaborate usage in application/example-http-service.

See Documentation: Intro for a more detailed introduction utilizing the two example applications.

Monorepo Development (Recommended)

At least for starting, going with the monorepo approach is the way to go. It becomes more complicated if you do not have 10s of applications, but 100s or 1000s of deployment artefacts, but for moving fast within a scoped context, a monorepo approach is favourable.

Clone the entire repository (or your own fork) for development:

git clone https://github.com/gorillalabs/bauhaus.git

Creating New Projects

Option 1: Quick Start by Copying an Example

# Copy the basic example
cp -r applications/example applications/my-new-project
cd applications/my-new-project

# Update project namespace in src/example/ β†’ src/my-project/
# Update deps.edn and configuration as needed

Option 2: Start Fresh

  1. Create project structure:
mkdir -p applications/my-project && cd applications/my-project
mkdir -p {src,resources,dev,dev-resources,test}
  1. Create deps.edn:
{:paths ["src" "resources"]
 
 :deps {org.clojure/clojure {:mvn/version "1.12.0"}
        integrant/integrant {:mvn/version "0.13.1"}
        aero/aero {:mvn/version "1.1.6"}
        
        ;; Add Bauhaus modules as needed
        org.gorillalabs.bauhaus/setup-logging 
        {:git/url "https://github.com/gorillalabs/bauhaus.git"
         :git/sha "LATEST_SHA"
         :deps/root "modules/setup/logging"}}
         
 :aliases
 {:dev {:extra-paths ["dev" "dev-resources"]
        :extra-deps {integrant/repl {:mvn/version "0.4.0"}
                     org.gorillalabs.bauhaus/dev-config 
                     {:git/url "https://github.com/gorillalabs/bauhaus.git"
                      :git/sha "LATEST_SHA"
                      :deps/root "modules/dev-tooling/config"}}}
                      
  :build {:deps {org.gorillalabs.bauhaus/build 
                 {:git/url "https://github.com/gorillalabs/bauhaus.git"
                  :git/sha "LATEST_SHA"  
                  :deps/root "modules/dev-tooling/build"}}
          :paths ["build"]
          :ns-default build}}}
  1. Set up development workflow:
;; dev/user.clj
(ns user
  (:require [integrant.repl :as ig-repl]
            [gorillalabs.bauhaus.dev-tooling.config :as dev-config]))

(ig-repl/set-prep! (constantly (dev-config/ig-config "dev-resources/dev-config.edn")))

(def go ig-repl/go)
(def halt ig-repl/halt)  
(def reset ig-repl/reset)
  1. Create your system configuration:
;; src/my_project/system.clj
(ns my-project.system
  (:require [integrant.core :as ig]))

(defn system-config [config]
  {:my-project/core {:message (:message config)}})

(defmethod ig/init-key :my-project/core [_ config]
  (println "Starting with:" (:message config))
  config)

(defmethod ig/halt-key! :my-project/core [_ component]
  (println "Stopping"))

Build System Integration

To use Bauhaus build tools in your project:

  1. Add build configuration:
;; build/build.clj
(ns build
  (:require [gorillalabs.bauhaus.build.version :as version]))

(defn uber [opts]
  (let [version-string (version/application-build-string)]
    (println "Building version:" version-string)
    ;; Your build logic here
    ))
  1. Use git tags for versioning:
git tag v1.0.0  # Bauhaus build tools will use this
clj -T:build uber

Integration Patterns

Recommended module combinations:

  • Basic CLI app: setup/logging + setup/cli + setup/shutdown
  • Web service: + http-server
  • Development: + dev-tooling/config + dev-tooling/build

Individual Module Dependencies

You can, of course, reference specific modules even if you do not use all of Bauhaus or the monorepo structure:

{:deps {;; Core dependencies
        org.clojure/clojure {:mvn/version "1.12.0"}
        integrant/integrant {:mvn/version "0.13.1"}
        
        ;; Bauhaus modules (pick what you need)
        org.gorillalabs.bauhaus/setup-logging 
        {:git/url "https://github.com/gorillalabs/bauhaus.git"
         :git/sha "COMMIT_SHA"  ; Pin to specific commit
         :deps/root "modules/setup/logging"}
         
        org.gorillalabs.bauhaus/setup-shutdown
        {:git/url "https://github.com/gorillalabs/bauhaus.git"
         :git/sha "COMMIT_SHA"
         :deps/root "modules/setup/shutdown"}}}

πŸ’‘ Tip: Check latest commits for the most recent SHA

Modules

Setup

Foundation for application infrastructure

Module Path Description
Logging modules/setup/logging Setup proper logging infrastructure, fighting the JVM logging chaos.
Shutdown modules/setup/shutdown Provide ordered shutdown hooks as proposed in Killing me softly: Graceful shutdowns in Clojure
CLI modules/setup/cli Setup a CLI for your application.

Dev-Tooling

Enhanced developer experience

Module Path Description
Config modules/dev-tooling/config Handle development config and ease Integrant REPL integration.
Build modules/dev-tooling/build Support building your app with version management.

Clojure Contrib

Enhanced standard library

Module Path Description
Collection modules/clojure-contrib/collection Collection utilities including deep-merge and more.

Learning Path

πŸš€ New to Bauhaus? Start here:

  1. πŸ“– Read the Philosophy: Design Choices - Understand the "why"
  2. ⚑ Quick Win: Run the Basic Example in 2 minutes
    cd applications/example
    clj -M:dev
    # In REPL: (go)
  3. 🌐 Real Application: Explore the HTTP Service Example
  4. πŸ”§ Build Your Own: Follow Creating New Projects
  5. πŸ“š Deep Dive: Comprehensive Introduction

🎯 By Use Case:

  • Building CLI tools: Start with setup/logging + setup/cli
  • Web applications: Try example-http-service first
  • Learning Integrant: Both examples show different patterns
  • Production deployment: Check build tooling and shutdown hooks

Development Environment

Nix Development Environment

This project includes a Nix flake to provide a reproducible development environment.

Prerequisites

You must have Nix installed with flake support enabled. You can find installation instructions on the official NixOS website.

Activating the Environment

Navigate to the project's root directory and run the following command:

nix develop

This will download all the required dependencies and drop you into a nushell with the following tools available:

  • jdk23
  • clojure
  • git

Upon activation, it will confirm the Java and Clojure versions available in the shell.

Contributing

We welcome contributions! Please:

  1. Check existing issues before creating new ones
  2. Fork the repository for your own modules, applications and/or pull requests.
  3. Follow the established patterns in existing modules
  4. Add tests for new functionality
  5. Update documentation as needed

Troubleshooting

Common Issues

"Module not found" errors:

  • Verify the :git/sha points to a valid commit
  • Check that :deps/root path matches the actual module location
  • Ensure module dependencies are compatible

REPL development issues:

  • Run (reset) if code changes aren't reflecting
  • Check that dev-resources/dev-config.edn exists
  • Verify Integrant system configuration is valid

Build problems:

  • Check that build namespace is properly configured in :build alias

Getting Help:

  • Check individual module READMEs for specific guidance
  • Review the Introduction Guide for detailed examples
  • Look at working examples in applications/ directory

Migration from Other Frameworks

From Mount

  • Replace Mount states with Integrant components
  • Use Bauhaus setup modules for logging and shutdown
  • Leverage enhanced REPL workflow

From Component

  • Integrant provides similar lifecycle management
  • Bauhaus adds production-ready operational modules
  • Configuration management is enhanced with Aero

From Plain Clojure

  • Gradual adoption - start with one or two modules
  • Enhanced REPL development experience
  • Production operational capabilities

About

Bauhaus is an opinionated set of foundational modules to optimize DevOps experience with Clojure-based services.

Resources

Stars

Watchers

Forks

Packages

No packages published