substrate

package module
v0.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 11, 2025 License: MIT Imports: 26 Imported by: 0

README

Substrate Caddy Module

Overview

Substrate is a custom Caddy v2 module that enables dynamic backend execution based on HTTP requests. It automatically manages the lifecycle of backend processes and proxies traffic to them, creating a seamless integration between Caddy and your custom backend code.

The module watches for a special substrate executable file in your site's directory. When this file is present, Substrate launches it as a backend process and proxies relevant requests to it. When the file is removed or modified, Substrate automatically stops or restarts the process.

Installation

To use this module, build Caddy with the Substrate module included:

xcaddy build --with github.com/fserb/substrate

Configuration

Substrate provides both global configuration options and a handler for HTTP requests.

Global Configuration

Configure global Substrate settings in the Caddyfile:

{
    substrate {
        env KEY VALUE           # Set environment variables for substrate processes
        status_log stdout|stderr|null|file FILENAME  # Configure status logging
    }
}
  • env: Set environment variables for all substrate processes (can be repeated)
  • status_log: Configure where status logs are written
    • stdout: Output to standard output (default)
    • stderr: Output to standard error
    • null: Discard output
    • file FILENAME: Write output to the specified file
Handler Configuration

Add the substrate directive to site blocks:

example.com {
    root * /path/to/site
    substrate [/prefix]
    file_server
}
  • The optional /prefix parameter specifies a URL path prefix for substrate requests
  • If no prefix is specified, substrate will handle requests at the root path

How It Works

  1. Substrate watches for a file named substrate in your site's root directory

  2. When the file is found, Substrate:

    • Executes it as a backend process
    • Passes a port number as the first argument
    • Waits for the process to start listening on that port
    • Proxies relevant requests to the backend
  3. The backend process receives:

    • The port number as its first command-line argument
    • Standard environment variables plus any configured in the global settings
    • If running as root, the process runs with the permissions of the file owner
  4. Request handling:

    • Requests matching the configured prefix are proxied to the backend
    • The backend can return status code 515 to indicate that Caddy should handle the request instead
    • Headers X-Forwarded-Path and X-Forwarded-BaseURL are added to proxied requests
  5. Process management:

    • If the process exits, it's automatically restarted with exponential backoff
    • When the substrate file is removed, the process is stopped
    • When the substrate file is modified, the process is restarted

Status Logging

Substrate provides detailed status logs to help with debugging:

  • [A] messages: Administrative actions (starting/stopping processes)
  • [S] messages: Standard output from the substrate process
  • [E] messages: Standard error from the substrate process

Examples

See the example directory for complete working examples.

Documentation

Index

Constants

View Source
const (
	LRUCacheSize = 256
)

Variables

This section is empty.

Functions

func GetFreePort added in v0.2.1

func GetFreePort() (int, error)

GetFreePort finds an available TCP port by binding to port 0 and retrieving the assigned port number.

Types

type App

type App struct {
	Env       map[string]string `json:"env,omitempty"`
	StatusLog outputTarget      `json:"status_log,omitempty"`
	// contains filtered or unexported fields
}

App is the main substrate application that manages the substrate server and provides configuration for substrate processes.

func (App) CaddyModule

func (h App) CaddyModule() caddy.ModuleInfo

func (*App) GetWatcher added in v0.2.0

func (h *App) GetWatcher(root string) *Watcher

GetWatcher retrieves an existing watcher for the given root directory or creates a new one if it doesn't exist.

func (*App) Provision

func (h *App) Provision(ctx caddy.Context) error

Provision sets up the app.

func (*App) Start

func (h *App) Start() error

func (*App) Stop

func (h *App) Stop() error

Stop gracefully shuts down the substrate app.

type HostReverseProxy

type HostReverseProxy interface {
	caddyhttp.MiddlewareHandler
	caddy.Provisioner
	SetHost(string)
}

type ReverseProxy

type ReverseProxy struct{ *reverseproxy.Handler }

func (*ReverseProxy) SetHost

func (s *ReverseProxy) SetHost(host string)

type SubstrateHandler

type SubstrateHandler struct {
	Prefix string `json:"prefix,omitempty"`
	// contains filtered or unexported fields
}

SubstrateHandler handles requests by proxying to a substrate process. It manages the lifecycle of substrate processes and routes HTTP requests to the appropriate backend based on path matching.

func (SubstrateHandler) CaddyModule

func (s SubstrateHandler) CaddyModule() caddy.ModuleInfo

func (*SubstrateHandler) Provision

func (s *SubstrateHandler) Provision(ctx caddy.Context) error

Provision sets up the handler.

func (*SubstrateHandler) ServeHTTP

type Watcher added in v0.2.0

type Watcher struct {
	// Root is the directory to watch for a substrate file
	Root string
	Port int
	// contains filtered or unexported fields
}

Watcher watches for a substrate file in a root directory and manages the lifecycle of substrate processes.

func (*Watcher) Close added in v0.2.0

func (w *Watcher) Close()

func (*Watcher) WriteStatusLog added in v0.2.1

func (w *Watcher) WriteStatusLog(msgType, message string)

WriteStatusLog writes a message to the status log The output destination is determined by the app's StatusLog configuration.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL