Merge pull request #4677 from coffeegoddd/db/idle-timeout

init: make proxied-server idle timeout configurable
This commit is contained in:
Dustin Brown
2026-07-08 13:51:03 -07:00
committed by GitHub
13 changed files with 143 additions and 72 deletions
+31 -20
View File
@@ -114,6 +114,7 @@ Non-interactive mode (--non-interactive or BD_NON_INTERACTIVE=1):
serverLogPath, _ := cmd.Flags().GetString("proxied-server-log-path")
serverRootPath, _ := cmd.Flags().GetString("proxied-server-root-path")
serverProxyPort, _ := cmd.Flags().GetInt("proxied-server-port")
serverProxyIdleTimeout, _ := cmd.Flags().GetDuration("proxied-server-idle-timeout")
externalHost, _ := cmd.Flags().GetString("proxied-server-external-host")
externalPort, _ := cmd.Flags().GetInt("proxied-server-external-port")
externalSocketPath, _ := cmd.Flags().GetString("proxied-server-external-socket-path")
@@ -189,6 +190,14 @@ Non-interactive mode (--non-interactive or BD_NON_INTERACTIVE=1):
return fmt.Errorf("--proxied-server-port must be between 1 and 65535, got %d", serverProxyPort)
}
}
if serverProxyIdleTimeout != 0 {
if !initProxiedServer {
return fmt.Errorf("--proxied-server-idle-timeout requires --proxied-server")
}
if serverProxyIdleTimeout < 0 {
return fmt.Errorf("--proxied-server-idle-timeout must be a non-negative duration, got %s", serverProxyIdleTimeout)
}
}
externalProvided := externalHost != "" || externalPort != 0 || externalSocketPath != "" ||
externalUser != "" ||
@@ -293,26 +302,27 @@ Non-interactive mode (--non-interactive or BD_NON_INTERACTIVE=1):
if initProxiedServer {
if err := runInitProxiedServer(cmd, rootCtx, initProxiedServerInput{
prefix: prefix,
database: database,
roleFlag: roleFlag,
initRemote: initRemote,
initRemoteChanged: initRemoteChanged,
destroyToken: destroyToken,
serverConfigPath: serverConfigPath,
serverLogPath: serverLogPath,
serverRootPath: serverRootPath,
serverProxyPort: serverProxyPort,
externalConfig: externalConfig,
quiet: quiet,
stealth: stealth,
skipHooks: skipHooks,
skipAgents: skipAgents,
reinitLocal: reinitLocal,
contributor: contributor,
team: team,
fromJSONL: fromJSONL,
nonInteractive: nonInteractive,
prefix: prefix,
database: database,
roleFlag: roleFlag,
initRemote: initRemote,
initRemoteChanged: initRemoteChanged,
destroyToken: destroyToken,
serverConfigPath: serverConfigPath,
serverLogPath: serverLogPath,
serverRootPath: serverRootPath,
serverProxyPort: serverProxyPort,
serverProxyIdleTimeout: serverProxyIdleTimeout,
externalConfig: externalConfig,
quiet: quiet,
stealth: stealth,
skipHooks: skipHooks,
skipAgents: skipAgents,
reinitLocal: reinitLocal,
contributor: contributor,
team: team,
fromJSONL: fromJSONL,
nonInteractive: nonInteractive,
}); err != nil {
return err
}
@@ -1778,6 +1788,7 @@ func init() {
initCmd.Flags().String("proxied-server-log-path", "", "[EXPERIMENTAL] Absolute path to the proxied dolt sql-server log file (proxied-server mode only). Default: <beadsDir>/proxieddb/server.log. Relative paths are rejected.")
initCmd.Flags().String("proxied-server-root-path", "", "[EXPERIMENTAL] Absolute directory holding the proxied dolt sql-server's lockfiles, pidfiles, and child .dolt repository (proxied-server mode only). Default: <beadsDir>/proxieddb. May not exist yet — bd will create it. Relative paths are rejected.")
initCmd.Flags().Int("proxied-server-port", 0, "[EXPERIMENTAL] Fixed TCP port for the proxy's loopback listener (proxied-server mode only). Default 0 = an OS-assigned free port. Startup fails if the port is already in use.")
initCmd.Flags().Duration("proxied-server-idle-timeout", 0, "[EXPERIMENTAL] Idle duration after which the proxy shuts down its loopback listener and backend (proxied-server mode only). Default 0 = built-in default (30s).")
initCmd.Flags().String("proxied-server-external-host", "", "[EXPERIMENTAL] Hostname or IP of an externally-managed dolt sql-server the proxy should front (proxied-server mode only). Mutually exclusive with --proxied-server-external-socket-path.")
initCmd.Flags().Int("proxied-server-external-port", 0, "[EXPERIMENTAL] TCP port of the externally-managed dolt sql-server (proxied-server mode only). Required when --proxied-server-external-host is set.")
initCmd.Flags().String("proxied-server-external-socket-path", "", "[EXPERIMENTAL] Absolute unix socket path of the externally-managed dolt sql-server (proxied-server mode only). Mutually exclusive with --proxied-server-external-host. Relative paths are rejected.")
+30 -28
View File
@@ -22,26 +22,27 @@ import (
)
type initProxiedServerInput struct {
prefix string
database string
roleFlag string
initRemote string
initRemoteChanged bool
destroyToken string
serverConfigPath string
serverLogPath string
serverRootPath string
serverProxyPort int
externalConfig *configfile.ExternalDoltConfig
quiet bool
stealth bool
skipHooks bool
skipAgents bool
reinitLocal bool
contributor bool
team bool
fromJSONL bool
nonInteractive bool
prefix string
database string
roleFlag string
initRemote string
initRemoteChanged bool
destroyToken string
serverConfigPath string
serverLogPath string
serverRootPath string
serverProxyPort int
serverProxyIdleTimeout time.Duration
externalConfig *configfile.ExternalDoltConfig
quiet bool
stealth bool
skipHooks bool
skipAgents bool
reinitLocal bool
contributor bool
team bool
fromJSONL bool
nonInteractive bool
}
func runInitProxiedServer(cmd *cobra.Command, ctx context.Context, in initProxiedServerInput) error {
@@ -120,7 +121,7 @@ func runInitProxiedServer(cmd *cobra.Command, ctx context.Context, in initProxie
}
configYAMLBody := renderInitConfigYAML("", false)
clientInfo, err := buildProxiedServerClientInfo(in.serverRootPath, in.serverConfigPath, in.serverLogPath, in.serverProxyPort, in.externalConfig)
clientInfo, err := buildProxiedServerClientInfo(in.serverRootPath, in.serverConfigPath, in.serverLogPath, in.serverProxyPort, in.serverProxyIdleTimeout, in.externalConfig)
if err != nil {
return err
}
@@ -256,8 +257,8 @@ func composeProxiedServerMetadataJSON(in proxiedMetadataInputs) ([]byte, error)
return json.MarshalIndent(cfg, "", " ")
}
func buildProxiedServerClientInfo(rootPath, configPath, logPath string, port int, external *configfile.ExternalDoltConfig) (*configfile.ProxiedServerClientInfo, error) {
if rootPath == "" && configPath == "" && logPath == "" && external == nil {
func buildProxiedServerClientInfo(rootPath, configPath, logPath string, port int, idleTimeout time.Duration, external *configfile.ExternalDoltConfig) (*configfile.ProxiedServerClientInfo, error) {
if rootPath == "" && configPath == "" && logPath == "" && port == 0 && idleTimeout == 0 && external == nil {
return nil, nil
}
clean := func(p string) (string, error) {
@@ -287,11 +288,12 @@ func buildProxiedServerClientInfo(rootPath, configPath, logPath string, port int
}
}
return &configfile.ProxiedServerClientInfo{
RootPath: rootAbs,
ConfigPath: configAbs,
LogPath: logAbs,
Port: port,
External: external,
RootPath: rootAbs,
ConfigPath: configAbs,
LogPath: logAbs,
Port: port,
IdleTimeout: idleTimeout,
External: external,
}, nil
}
+44 -14
View File
@@ -2,6 +2,7 @@ package main
import (
"testing"
"time"
"github.com/steveyegge/beads/internal/configfile"
"github.com/stretchr/testify/assert"
@@ -10,13 +11,42 @@ import (
func TestBuildProxiedServerClientInfo(t *testing.T) {
t.Run("all empty returns nil", func(t *testing.T) {
info, err := buildProxiedServerClientInfo("", "", "", 0, nil)
info, err := buildProxiedServerClientInfo("", "", "", 0, 0, nil)
require.NoError(t, err)
assert.Nil(t, info)
})
t.Run("port alone is persisted", func(t *testing.T) {
info, err := buildProxiedServerClientInfo("", "", "", 3306, 0, nil)
require.NoError(t, err)
require.NotNil(t, info)
assert.Equal(t, 3306, info.Port)
assert.Zero(t, info.IdleTimeout)
})
t.Run("idle timeout alone is persisted", func(t *testing.T) {
info, err := buildProxiedServerClientInfo("", "", "", 0, 5*time.Minute, nil)
require.NoError(t, err)
require.NotNil(t, info)
assert.Equal(t, 5*time.Minute, info.IdleTimeout)
assert.Zero(t, info.Port)
})
t.Run("port and idle timeout survive a round-trip via SaveProxiedServerClientInfo", func(t *testing.T) {
dir := t.TempDir()
info, err := buildProxiedServerClientInfo("", "", "", 3306, 5*time.Minute, nil)
require.NoError(t, err)
require.NotNil(t, info)
require.NoError(t, configfile.SaveProxiedServerClientInfo(dir, info))
loaded, err := configfile.LoadProxiedServerClientInfo(dir)
require.NoError(t, err)
require.NotNil(t, loaded)
assert.Equal(t, 3306, loaded.Port)
assert.Equal(t, 5*time.Minute, loaded.IdleTimeout)
})
t.Run("absolute paths pass through cleaned", func(t *testing.T) {
info, err := buildProxiedServerClientInfo("/var/lib/beads/proxieddb", "/etc/dolt/server.yaml", "/var/log/server.log", 0, nil)
info, err := buildProxiedServerClientInfo("/var/lib/beads/proxieddb", "/etc/dolt/server.yaml", "/var/log/server.log", 0, 0, nil)
require.NoError(t, err)
require.NotNil(t, info)
assert.Equal(t, "/var/lib/beads/proxieddb", info.RootPath)
@@ -26,14 +56,14 @@ func TestBuildProxiedServerClientInfo(t *testing.T) {
})
t.Run("filepath.Clean normalizes redundant separators and . segments", func(t *testing.T) {
info, err := buildProxiedServerClientInfo("/var/lib//beads/./proxieddb", "", "", 0, nil)
info, err := buildProxiedServerClientInfo("/var/lib//beads/./proxieddb", "", "", 0, 0, nil)
require.NoError(t, err)
require.NotNil(t, info)
assert.Equal(t, "/var/lib/beads/proxieddb", info.RootPath)
})
t.Run("mixed absolute + empty", func(t *testing.T) {
info, err := buildProxiedServerClientInfo("/var/lib/beads/proxieddb", "", "/var/log/server.log", 0, nil)
info, err := buildProxiedServerClientInfo("/var/lib/beads/proxieddb", "", "/var/log/server.log", 0, 0, nil)
require.NoError(t, err)
require.NotNil(t, info)
assert.Equal(t, "/var/lib/beads/proxieddb", info.RootPath)
@@ -42,26 +72,26 @@ func TestBuildProxiedServerClientInfo(t *testing.T) {
})
t.Run("relative root path is rejected", func(t *testing.T) {
_, err := buildProxiedServerClientInfo("alt-root", "", "", 0, nil)
_, err := buildProxiedServerClientInfo("alt-root", "", "", 0, 0, nil)
require.Error(t, err)
assert.Contains(t, err.Error(), "not absolute")
})
t.Run("relative config path is rejected", func(t *testing.T) {
_, err := buildProxiedServerClientInfo("", "configs/server.yaml", "", 0, nil)
_, err := buildProxiedServerClientInfo("", "configs/server.yaml", "", 0, 0, nil)
require.Error(t, err)
assert.Contains(t, err.Error(), "not absolute")
})
t.Run("relative log path is rejected", func(t *testing.T) {
_, err := buildProxiedServerClientInfo("", "", "logs/server.log", 0, nil)
_, err := buildProxiedServerClientInfo("", "", "logs/server.log", 0, 0, nil)
require.Error(t, err)
assert.Contains(t, err.Error(), "not absolute")
})
t.Run("absolute paths survive a round-trip through the sidecar resolver", func(t *testing.T) {
const beadsDir = "/proj/.beads"
info, err := buildProxiedServerClientInfo("/var/lib/beads/proxieddb", "", "", 0, nil)
info, err := buildProxiedServerClientInfo("/var/lib/beads/proxieddb", "", "", 0, 0, nil)
require.NoError(t, err)
require.NotNil(t, info)
assert.Equal(t, info.RootPath, (&configfile.ProxiedServerClientInfo{RootPath: info.RootPath}).ResolvedRootPath(beadsDir))
@@ -69,7 +99,7 @@ func TestBuildProxiedServerClientInfo(t *testing.T) {
t.Run("external config alone populates External section", func(t *testing.T) {
ext := &configfile.ExternalDoltConfig{Host: "db.internal", Port: 3306}
info, err := buildProxiedServerClientInfo("", "", "", 0, ext)
info, err := buildProxiedServerClientInfo("", "", "", 0, 0, ext)
require.NoError(t, err)
require.NotNil(t, info)
assert.Empty(t, info.RootPath)
@@ -88,7 +118,7 @@ func TestBuildProxiedServerClientInfo(t *testing.T) {
TLSCert: "/etc/beads/client.pem",
TLSKey: "/etc/beads/client.key",
}
info, err := buildProxiedServerClientInfo("", "", "", 0, ext)
info, err := buildProxiedServerClientInfo("", "", "", 0, 0, ext)
require.NoError(t, err)
require.NotNil(t, info.External)
assert.True(t, info.External.TLSRequired)
@@ -98,7 +128,7 @@ func TestBuildProxiedServerClientInfo(t *testing.T) {
t.Run("external unix socket config flows through", func(t *testing.T) {
ext := &configfile.ExternalDoltConfig{Socket: "/var/run/dolt.sock"}
info, err := buildProxiedServerClientInfo("", "", "", 0, ext)
info, err := buildProxiedServerClientInfo("", "", "", 0, 0, ext)
require.NoError(t, err)
require.NotNil(t, info.External)
assert.Equal(t, "/var/run/dolt.sock", info.External.Socket)
@@ -107,13 +137,13 @@ func TestBuildProxiedServerClientInfo(t *testing.T) {
})
t.Run("invalid external config is rejected", func(t *testing.T) {
_, err := buildProxiedServerClientInfo("", "", "", 0, &configfile.ExternalDoltConfig{})
_, err := buildProxiedServerClientInfo("", "", "", 0, 0, &configfile.ExternalDoltConfig{})
require.Error(t, err)
assert.Contains(t, err.Error(), "ExternalDoltConfig")
})
t.Run("invalid external config with tls cert without key is rejected", func(t *testing.T) {
_, err := buildProxiedServerClientInfo("", "", "", 0, &configfile.ExternalDoltConfig{
_, err := buildProxiedServerClientInfo("", "", "", 0, 0, &configfile.ExternalDoltConfig{
Host: "db",
Port: 3306,
TLSCert: "/etc/beads/client.pem",
@@ -125,7 +155,7 @@ func TestBuildProxiedServerClientInfo(t *testing.T) {
t.Run("external survives round-trip via SaveProxiedServerClientInfo", func(t *testing.T) {
dir := t.TempDir()
ext := &configfile.ExternalDoltConfig{Host: "db.internal", Port: 3306, TLSRequired: true}
info, err := buildProxiedServerClientInfo("", "", "", 0, ext)
info, err := buildProxiedServerClientInfo("", "", "", 0, 0, ext)
require.NoError(t, err)
require.NotNil(t, info)
require.NoError(t, configfile.SaveProxiedServerClientInfo(dir, info))
+9 -2
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"os/exec"
"time"
"github.com/steveyegge/beads/internal/config"
"github.com/steveyegge/beads/internal/configfile"
@@ -25,14 +26,16 @@ func newProxiedServerUOWProvider(ctx context.Context, beadsDir string) (uow.Unit
info, _ := configfile.LoadProxiedServerClientInfo(beadsDir)
var proxyPort int
var proxyIdleTimeout time.Duration
if info != nil {
proxyPort = info.Port
proxyIdleTimeout = info.IdleTimeout
}
if info != nil && info.External != nil {
return newExternalProxiedServerUOWProvider(ctx, beadsDir, database, info.External, proxyPort)
return newExternalProxiedServerUOWProvider(ctx, beadsDir, database, info.External, proxyPort, proxyIdleTimeout)
}
return newManagedProxiedServerUOWProvider(ctx, beadsDir, database, proxyPort)
return newManagedProxiedServerUOWProvider(ctx, beadsDir, database, proxyPort, proxyIdleTimeout)
}
func newExternalProxiedServerUOWProvider(
@@ -40,6 +43,7 @@ func newExternalProxiedServerUOWProvider(
beadsDir, database string,
external *configfile.ExternalDoltConfig,
proxyPort int,
proxyIdleTimeout time.Duration,
) (uow.UnitOfWorkProvider, error) {
rootPath, err := resolveProxiedServerRootPath(beadsDir)
if err != nil {
@@ -72,6 +76,7 @@ func newExternalProxiedServerUOWProvider(
external.ResolvedUser(),
os.Getenv(configfile.ExternalDoltPasswordEnvVar),
proxyPort,
proxyIdleTimeout,
)
}
@@ -79,6 +84,7 @@ func newManagedProxiedServerUOWProvider(
ctx context.Context,
beadsDir, database string,
proxyPort int,
proxyIdleTimeout time.Duration,
) (uow.UnitOfWorkProvider, error) {
doltBin, err := exec.LookPath("dolt")
if err != nil {
@@ -119,5 +125,6 @@ func newManagedProxiedServerUOWProvider(
"", // proxy is loopback-only, no auth
doltBin,
proxyPort,
proxyIdleTimeout,
)
}
+1 -1
View File
@@ -28,7 +28,7 @@ func TestNewExternalProxiedServerUOWProvider_CreatesRootDir(t *testing.T) {
beadsDir := t.TempDir()
external := &configfile.ExternalDoltConfig{Host: "db.invalid"}
_, err := newExternalProxiedServerUOWProvider(context.Background(), beadsDir, "beads_test", external, 0)
_, err := newExternalProxiedServerUOWProvider(context.Background(), beadsDir, "beads_test", external, 0, 0)
require.Error(t, err, "invalid external config must surface a validation error")
wantRoot := proxiedServerRoot(beadsDir)
+1
View File
@@ -3549,6 +3549,7 @@ bd init [flags]
--proxied-server-external-tls-cert-path string [EXPERIMENTAL] Absolute path to a client TLS certificate (for mTLS to the externally-managed dolt sql-server). Must be paired with --proxied-server-external-tls-key-path. Relative paths are rejected.
--proxied-server-external-tls-key-path string [EXPERIMENTAL] Absolute path to the client TLS private key (for mTLS to the externally-managed dolt sql-server). Must be paired with --proxied-server-external-tls-cert-path. Relative paths are rejected.
--proxied-server-external-user string [EXPERIMENTAL] MySQL user for the externally-managed dolt sql-server (proxied-server mode only). Defaults to "root" when empty. Password is read at runtime from $BEADS_PROXIED_SERVER_EXTERNAL_PASSWORD and is never persisted to disk.
--proxied-server-idle-timeout duration [EXPERIMENTAL] Idle duration after which the proxy shuts down its loopback listener and backend (proxied-server mode only). Default 0 = built-in default (30s).
--proxied-server-log-path string [EXPERIMENTAL] Absolute path to the proxied dolt sql-server log file (proxied-server mode only). Default: <beadsDir>/proxieddb/server.log. Relative paths are rejected.
--proxied-server-port int [EXPERIMENTAL] Fixed TCP port for the proxy's loopback listener (proxied-server mode only). Default 0 = an OS-assigned free port. Startup fails if the port is already in use.
--proxied-server-root-path string [EXPERIMENTAL] Absolute directory holding the proxied dolt sql-server's lockfiles, pidfiles, and child .dolt repository (proxied-server mode only). Default: <beadsDir>/proxieddb. May not exist yet — bd will create it. Relative paths are rejected.
@@ -5,16 +5,18 @@ import (
"fmt"
"os"
"path/filepath"
"time"
)
const ProxiedServerClientInfoFileName = "proxied_server_client_info.json"
type ProxiedServerClientInfo struct {
RootPath string `json:"root_path,omitempty"`
ConfigPath string `json:"config_path,omitempty"`
LogPath string `json:"log_path,omitempty"`
Port int `json:"port,omitempty"`
External *ExternalDoltConfig `json:"external,omitempty"`
RootPath string `json:"root_path,omitempty"`
ConfigPath string `json:"config_path,omitempty"`
LogPath string `json:"log_path,omitempty"`
Port int `json:"port,omitempty"`
IdleTimeout time.Duration `json:"idle_timeout,omitempty"`
External *ExternalDoltConfig `json:"external,omitempty"`
}
func ProxiedServerClientInfoPath(beadsDir string) string {
+6 -1
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"time"
_ "github.com/go-sql-driver/mysql"
@@ -23,7 +24,11 @@ func NewDoltServerUOWProvider(
rootPassword string,
doltBinExec string,
proxyPort int,
idleTimeout time.Duration,
) (UnitOfWorkProvider, error) {
if idleTimeout <= 0 {
idleTimeout = defaultProxyIdleTimeout
}
if database == "" {
return nil, fmt.Errorf("uow: database name must not be empty (caller should default to %q)", "beads")
}
@@ -56,7 +61,7 @@ func NewDoltServerUOWProvider(
LogFilePath: serverLogFilePath,
DoltBinPath: absDoltBinExec,
Database: database,
IdleTimeout: defaultProxyIdleTimeout,
IdleTimeout: idleTimeout,
Port: proxyPort,
})
if err != nil {
@@ -62,6 +62,7 @@ func TestNewDoltServerUOWProvider_ValidationErrors(t *testing.T) {
"", "", tc.backend,
tc.rootUser, "", tc.doltBin,
0,
0,
)
assert.Nil(t, p)
require.Error(t, err)
@@ -105,6 +106,7 @@ func TestNewDoltServerUOWProvider_HappyPath(t *testing.T) {
"",
bin,
0,
0,
)
require.NoError(t, err)
@@ -160,6 +162,7 @@ func TestNewDoltServerUOWProvider_ConcurrentInstantiation(t *testing.T) {
"",
bin,
0,
0,
)
results[i] = result{provider: p, err: err}
}()
@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"time"
_ "github.com/go-sql-driver/mysql"
@@ -22,7 +23,11 @@ func NewExternalDoltServerUOWProvider(
rootUser string,
rootPassword string,
proxyPort int,
idleTimeout time.Duration,
) (UnitOfWorkProvider, error) {
if idleTimeout <= 0 {
idleTimeout = defaultProxyIdleTimeout
}
if database == "" {
return nil, fmt.Errorf("uow: database name must not be empty (caller should default to %q)", "beads")
}
@@ -46,7 +51,7 @@ func NewExternalDoltServerUOWProvider(
Backend: proxy.BackendExternal,
LogFilePath: serverLogFilePath,
External: external,
IdleTimeout: defaultProxyIdleTimeout,
IdleTimeout: idleTimeout,
Port: proxyPort,
})
if err != nil {
@@ -46,6 +46,7 @@ func TestNewExternalDoltServerUOWProvider_ValidationErrors(t *testing.T) {
tc.rootUser,
"",
0,
0,
)
assert.Nil(t, p)
require.Error(t, err)
@@ -87,6 +88,7 @@ func TestNewExternalDoltServerUOWProvider_EndToEnd(t *testing.T) {
"root",
"",
0,
0,
)
require.NoError(t, err)
require.NotNil(t, provider)
@@ -161,6 +163,7 @@ func TestNewExternalDoltServerUOWProvider_ConcurrentInstantiation(t *testing.T)
"root",
"",
0,
0,
)
results[i] = result{provider: p, err: err}
}()
@@ -50,6 +50,7 @@ func newTestUOWProvider(t *testing.T) UnitOfWorkProvider {
"",
bin,
0,
0,
)
require.NoError(t, err)
require.NotNil(t, provider)
+1
View File
@@ -76,6 +76,7 @@ bd init [flags]
--proxied-server-external-tls-cert-path string [EXPERIMENTAL] Absolute path to a client TLS certificate (for mTLS to the externally-managed dolt sql-server). Must be paired with --proxied-server-external-tls-key-path. Relative paths are rejected.
--proxied-server-external-tls-key-path string [EXPERIMENTAL] Absolute path to the client TLS private key (for mTLS to the externally-managed dolt sql-server). Must be paired with --proxied-server-external-tls-cert-path. Relative paths are rejected.
--proxied-server-external-user string [EXPERIMENTAL] MySQL user for the externally-managed dolt sql-server (proxied-server mode only). Defaults to "root" when empty. Password is read at runtime from $BEADS_PROXIED_SERVER_EXTERNAL_PASSWORD and is never persisted to disk.
--proxied-server-idle-timeout duration [EXPERIMENTAL] Idle duration after which the proxy shuts down its loopback listener and backend (proxied-server mode only). Default 0 = built-in default (30s).
--proxied-server-log-path string [EXPERIMENTAL] Absolute path to the proxied dolt sql-server log file (proxied-server mode only). Default: <beadsDir>/proxieddb/server.log. Relative paths are rejected.
--proxied-server-port int [EXPERIMENTAL] Fixed TCP port for the proxy's loopback listener (proxied-server mode only). Default 0 = an OS-assigned free port. Startup fails if the port is already in use.
--proxied-server-root-path string [EXPERIMENTAL] Absolute directory holding the proxied dolt sql-server's lockfiles, pidfiles, and child .dolt repository (proxied-server mode only). Default: <beadsDir>/proxieddb. May not exist yet — bd will create it. Relative paths are rejected.