proxy

package
v0.5.2 Latest Latest
Warning

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

Go to latest
Published: Aug 13, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package proxy gives every bay its own browser origin.

This is a correctness feature, not cosmetics. Browsers scope cookies, localStorage, IndexedDB and service worker registrations by host and deliberately ignore the port, so two bays served from localhost:3000 and localhost:3001 share one storage partition. Log into one and you are logged into the other; log out of one and the other's session evaporates. The resulting bugs only reproduce when two bays are running, which is exactly when a developer is least able to reason about them.

Distinct hostnames eliminate the whole class.

Two implementation notes explain the shape of this package.

The proxy runs as a container rather than in the daemon because macOS has no setcap and no unprivileged-port sysctl, and pf rules need root and do not survive a reboot. Publishing :80 from a container makes Docker's already-root helper perform the privileged bind, so devbay itself never needs sudo.

The proxy joins each bay's network rather than reaching services through the host, because published ports are bound to loopback and a container cannot reach the host's loopback. Publishing on 0.0.0.0 to make that work would put every bay, and every credential it holds, on the local network.

Index

Constants

View Source
const (
	// Image is the proxy image. Caddy is used rather than a hand-written
	// reverse proxy because WebSocket upgrades, HTTP/2, and a local
	// certificate authority are all requirements here and all solved problems
	// there.
	Image = "caddy:2-alpine"

	// ContainerName is shared by every bay; there is one proxy per machine.
	ContainerName = "devbay-proxy"

	// AdminPort is Caddy's config API inside the container.
	AdminPort = 2019

	// LabelManaged marks the proxy container.
	LabelManaged = "dev.devbay.proxy"
)
View Source
const BindEnv = "DEVBAY_PROXY_BIND"

BindEnv names the variable that overrides what the proxy binds to.

Variables

This section is empty.

Functions

This section is empty.

Types

type Proxy

type Proxy struct {

	// HTTPPort is the host port :80 is published on. It falls back to 8080
	// when 80 cannot be bound, which keeps devbay usable rather than refusing
	// to start.
	HTTPPort int

	Log func(format string, args ...any)
	// contains filtered or unexported fields
}

Proxy manages the shared reverse proxy container.

func New

func New(cli *client.Client, logf func(string, ...any)) *Proxy

New prepares a proxy handle. It does not start anything.

func (*Proxy) Attach

func (p *Proxy) Attach(ctx context.Context, networkName string) error

Attach joins the proxy to a bay's network so it can reach services by name.

func (*Proxy) ClearRoutes

func (p *Proxy) ClearRoutes(ctx context.Context, project, bay string) error

ClearRoutes removes a bay's routes.

func (*Proxy) Detach

func (p *Proxy) Detach(ctx context.Context, networkName string) error

Detach leaves a bay's network. Teardown must call this before removing the network, or Docker refuses because the endpoint is still active.

func (*Proxy) Ensure

func (p *Proxy) Ensure(ctx context.Context, httpPort, adminPort int) error

Ensure starts the proxy if it is not already running.

httpPort is the host port to serve on; 0 means try 80 and fall back to 8080. adminPort is where Caddy's config API is published, on loopback only.

func (*Proxy) Routes

func (p *Proxy) Routes() []Route

Routes returns the current routing table, sorted by host.

func (*Proxy) SetRoutes

func (p *Proxy) SetRoutes(ctx context.Context, project, bay string, routes []Route) error

SetRoutes replaces every route belonging to one bay.

Replacing rather than merging means a service removed from a manifest stops being routable, instead of lingering as a hostname that resolves to a container that no longer exists.

func (*Proxy) Stop

func (p *Proxy) Stop(ctx context.Context) error

Stop removes the proxy container.

type Route

type Route struct {
	// Host is the full hostname, e.g. add-oauth.acme.localhost.
	Host string
	// Upstream is the container-network address, e.g. web:3000. The proxy
	// resolves it over the bay network it is attached to.
	Upstream string
	// Bay and Project identify the owner, so routes can be replaced per bay.
	Project string
	Bay     string
}

Route sends one hostname to one container port.

Jump to

Keyboard shortcuts

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