baker

package module
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Aug 20, 2024 License: Apache-2.0 Imports: 18 Imported by: 0

README

██████╗░░█████╗░██╗░░██╗███████╗██████╗░
██╔══██╗██╔══██╗██║░██╔╝██╔════╝██╔══██╗
██████╦╝███████║█████═╝░█████╗░░██████╔╝
██╔══██╗██╔══██║██╔═██╗░██╔══╝░░██╔══██╗
██████╦╝██║░░██║██║░╚██╗███████╗██║░░██║
╚═════╝░╚═╝░░╚═╝╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝

Introduction

Baker is a dynamic HTTP reverse proxy with a focus on extensibility and flexibility. It is designed to adapt to a variety of orchestration engines and provides dynamic configuration capabilities, eliminating the need to restart the reverse proxy when changing configurations.

Features

  • Docker driver integration for Docker event listening.
  • Exposed driver interface for easy integration with other orchestration engines.
  • Dynamic configuration capabilities.
  • Custom trie data structure for fast path pattern matching.
  • Can be used as a library, as it implements the HTTP Handler interface.
  • High extensibility due to exposed interfaces for most components.
  • Middleware-like feature for modifying incoming and outgoing traffic.
  • Default load balancing.
  • Automatic SSL certificate updates and creation using Let's Encrypt.
  • Configurable rate limiter per domain and path.
  • Prometheus metrics are available at BAKER_METRICS_ADDRS/metrics

Usage

First, we need to run Baker inside docker. The following docker-compose.yml

version: "3.5"

services:
  baker:
    image: ellato/baker:latest

    environment:
      # enables ACME system
      - BAKER_ACME=NO
      # folder location which holds all certification
      - BAKER_ACME_PATH=/acme/cert
      - BAKER_LOG_LEVEL=DEBUG
      - BAKER_BUFFER_SIZE=100
      - BAKER_PING_DURATION=2s
      - BAKER_METRICS_ADDR=:8089

    ports:
      - "80:80"
      - "443:443"

    # make sure to use the right network
    networks:
      - baker

    volumes:
      # make sure it can access to main docker.sock
      - /var/run/docker.sock:/var/run/docker.sock
      - ./acme/cert:/acme/cert

networks:
  baker:
    name: baker_net
    driver: bridge

Then for each service, the following docker-compose can be used. The only requirements are labels and networks. Make sure both baker and service have the same network interface

version: "3.5"

services:
  service1:
    image: service:latest

    labels:
      - "baker.enable=true"
      - "baker.network=baker_net"
      - "baker.service.port=8000"
      - "baker.service.ping=/config"

    networks:
      - baker

networks:
  baker:
    external:
      name: baker_net

The service should expose a REST endpoint that returns a configuration. This endpoint acts as a health check and provides real-time configuration.

[
  {
    "domain": "example.com",
    "path": "/sample1",
    "ready": true
  },
  {
    "domain": "example.com",
    "path": "/sample2",
    "ready": false
  },
  {
    "domain": "example1.com",
    "path": "/sample1*",
    "ready": true,
    "rules": [
      {
        "type": "ReplacePath",
        "args": {
          "search": "/sample1",
          "replace": "",
          "times": 1
        }
      }
    ]
  }
]

Middleware

Baker comes with several built-in middleware:

ReplacePath

Remove a specific path from an incoming request. Service will be receiving the modified path. to use this middleware, simply add the following rule to the rules section of the configuration

{
  "type": "ReplacePath",
  "args": {
    "search": "/sample1",
    "replace": "",
    "times": 1
  }
}
AppendPath

Add a path at the beginning and end of the path to use this middleware, simply add the following rule to the rules section of the configuration

{
  "type": "AppendPath",
  "args": {
    "begin": "/begin",
    "end": "/end"
  }
}
RateLimiter

Add a rate limiter for a specific domain and path to use this middleware, simply add the following rule to the riles sections of the configuration

{
  "type": "RateLimiter",
  "args": {
    "request_limit": 100,
    "window_duration": "60s"
  }
}

the above configuration means, in one minute, 100 requests should be routed per individual IP address, if that is exceeded, a 429 HTTP status will be sent back to the client.

License

Baker is licensed under the Apache v2.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewEntryList added in v0.0.4

func NewEntryList() *entryList

func WithAddCallback

func WithAddCallback(callback func(*Container)) func(*ActionRunner)

func WithBufferSize

func WithBufferSize(size int) serverOptFunc

func WithGetCallback

func WithGetCallback(callback func(string, string) (*Container, *Endpoint)) func(*ActionRunner)

func WithPingDuration

func WithPingDuration(d time.Duration) serverOptFunc

func WithPingerCallback

func WithPingerCallback(callback func()) func(*ActionRunner)

func WithRemoveCallback

func WithRemoveCallback(callback func(*Container)) func(*ActionRunner)

func WithRules

func WithRules(rules ...rule.RegisterFunc) serverOptFunc

func WithUpdateCallback

func WithUpdateCallback(callback func(*Container, *Endpoint)) func(*ActionRunner)

Types

type ActionCallback

type ActionCallback func(*ActionRunner)

type ActionRunner

type ActionRunner struct {
	// contains filtered or unexported fields
}

func NewActionRunner

func NewActionRunner(bufferSize int, cbs ...ActionCallback) *ActionRunner

func (*ActionRunner) Add

func (ar *ActionRunner) Add(container *Container)

func (*ActionRunner) Close

func (ar *ActionRunner) Close()

func (*ActionRunner) Get

func (ar *ActionRunner) Get(ctx context.Context, endpoint *Endpoint) (*Container, *Endpoint)

func (*ActionRunner) Pinger

func (ar *ActionRunner) Pinger()

func (*ActionRunner) Remove

func (ar *ActionRunner) Remove(container *Container)

func (*ActionRunner) Update

func (ar *ActionRunner) Update(container *Container, endpoint *Endpoint)

type Config

type Config struct {
	Endpoints []Endpoint `json:"endpoints"`
}

type Container

type Container struct {
	Id         string
	ConfigPath string
	Addr       netip.AddrPort
}

type Driver

type Driver interface {
	Add(*Container)
	Remove(*Container)
}

type Endpoint

type Endpoint struct {
	Domain string `json:"domain"`
	Path   string `json:"path"`
	Rules  []Rule `json:"rules"`
}

type Event

type Event struct {
	Type      EventType
	Container *Container
	Endpoint  *Endpoint
	Result    chan struct {
		Container *Container
		Endpoint  *Endpoint
	}
}

type EventType

type EventType int

type Rule

type Rule struct {
	Type string          `json:"type"`
	Args json.RawMessage `json:"args"`
}

type Server

type Server struct {
	// contains filtered or unexported fields
}

func NewServer

func NewServer(opts ...serverOpt) *Server

func (*Server) Close

func (s *Server) Close()

func (*Server) RegisterDriver

func (s *Server) RegisterDriver(fn func(Driver))

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

type Service

type Service struct {
	Containers []*Container
	Endpoint   *Endpoint
}

Directories

Path Synopsis
cmd
internal

Jump to

Keyboard shortcuts

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