add support for docker socket proxy

This commit is contained in:
Henry Dollman
2024-07-31 19:14:51 -04:00
parent e26e9fce03
commit e204bcf9ce
3 changed files with 55 additions and 21 deletions

View File

@@ -1,6 +1,7 @@
package main package main
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@@ -8,6 +9,7 @@ import (
"math" "math"
"net" "net"
"net/http" "net/http"
"net/url"
"os" "os"
"strings" "strings"
"sync" "sync"
@@ -51,20 +53,8 @@ var netIoStats = NetIoStats{
Name: "", Name: "",
} }
// client for docker engine api // dockerClient for docker engine api
var client = &http.Client{ var dockerClient = newDockerClient()
Timeout: time.Second,
Transport: &http.Transport{
Dial: func(proto, addr string) (net.Conn, error) {
return net.Dial("unix", "/var/run/docker.sock")
},
ForceAttemptHTTP2: false,
IdleConnTimeout: 90 * time.Second,
DisableCompression: true,
MaxIdleConnsPerHost: 50,
DisableKeepAlives: false,
},
}
func getSystemStats() (*SystemInfo, *SystemStats) { func getSystemStats() (*SystemInfo, *SystemStats) {
systemStats := &SystemStats{} systemStats := &SystemStats{}
@@ -159,7 +149,7 @@ func getSystemStats() (*SystemInfo, *SystemStats) {
} }
func getDockerStats() ([]*ContainerStats, error) { func getDockerStats() ([]*ContainerStats, error) {
resp, err := client.Get("http://localhost/containers/json") resp, err := dockerClient.Get("http://localhost/containers/json")
if err != nil { if err != nil {
return []*ContainerStats{}, err return []*ContainerStats{}, err
} }
@@ -167,7 +157,8 @@ func getDockerStats() ([]*ContainerStats, error) {
var containers []*Container var containers []*Container
if err := json.NewDecoder(resp.Body).Decode(&containers); err != nil { if err := json.NewDecoder(resp.Body).Decode(&containers); err != nil {
panic(err) log.Printf("Error decoding containers: %+v\n", err)
return []*ContainerStats{}, err
} }
containerStats := make([]*ContainerStats, 0, len(containers)) containerStats := make([]*ContainerStats, 0, len(containers))
@@ -219,7 +210,7 @@ func getContainerStats(ctr *Container) (*ContainerStats, error) {
// use semaphore to limit concurrency // use semaphore to limit concurrency
acquireSemaphore() acquireSemaphore()
defer releaseSemaphore() defer releaseSemaphore()
resp, err := client.Get("http://localhost/containers/" + ctr.IdShort + "/stats?stream=0&one-shot=1") resp, err := dockerClient.Get("http://localhost/containers/" + ctr.IdShort + "/stats?stream=0&one-shot=1")
if err != nil { if err != nil {
return &ContainerStats{}, err return &ContainerStats{}, err
} }
@@ -404,3 +395,44 @@ func initializeNetIoStats() {
netIoStats.Time = time.Now() netIoStats.Time = time.Now()
} }
} }
func newDockerClient() *http.Client {
dockerHost := "unix:///var/run/docker.sock"
if dockerHostEnv, exists := os.LookupEnv("DOCKER_HOST"); exists {
dockerHost = dockerHostEnv
}
parsedURL, err := url.Parse(dockerHost)
if err != nil {
log.Fatal("Error parsing DOCKER_HOST: " + err.Error())
}
transport := &http.Transport{
ForceAttemptHTTP2: false,
IdleConnTimeout: 90 * time.Second,
DisableCompression: true,
MaxIdleConnsPerHost: 50,
DisableKeepAlives: false,
}
switch parsedURL.Scheme {
case "unix":
transport.DialContext = func(ctx context.Context, proto, addr string) (net.Conn, error) {
return (&net.Dialer{}).DialContext(ctx, "unix", parsedURL.Path)
}
case "tcp", "http", "https":
log.Println("Using DOCKER_HOST: " + dockerHost)
transport.DialContext = func(ctx context.Context, proto, addr string) (net.Conn, error) {
return (&net.Dialer{}).DialContext(ctx, "tcp", parsedURL.Host)
}
default:
log.Fatal("Unsupported DOCKER_HOST: " + parsedURL.Scheme)
}
client := &http.Client{
Timeout: time.Second,
Transport: transport,
}
return client
}

View File

@@ -163,8 +163,7 @@ func main() {
// system creation defaults // system creation defaults
app.OnModelBeforeCreate("systems").Add(func(e *core.ModelEvent) error { app.OnModelBeforeCreate("systems").Add(func(e *core.ModelEvent) error {
record := e.Model.(*models.Record) record := e.Model.(*models.Record)
var info = SystemInfo{} record.Set("info", SystemInfo{})
record.Set("info", info)
record.Set("status", "pending") record.Set("status", "pending")
return nil return nil
}) })

View File

@@ -111,9 +111,12 @@ If using systemd, run `sudo systemctl restart beszel` and `sudo systemctl restar
| Name | Default | Description | | Name | Default | Description |
| ------------ | ------- | ---------------------------------------------------------- | | ------------ | ------- | ---------------------------------------------------------- |
| `FILESYSTEM` | unset | Filesystem / partition to use for disk I/O stats | | `FILESYSTEM` | unset | Filesystem / partition to use for disk I/O stats. |
| `KEY` | unset | Public SSH key to use for authentication. Provided in hub. | | `KEY` | unset | Public SSH key to use for authentication. Provided in hub. |
| `PORT` | 45876 | Port to listen on | | `PORT` | 45876 | Port to listen on. |
<!-- | `DOCKER_HOST` | unset | Overrides the docker host (docker.sock) if using a proxy.[^socket] |
[^socket]: Beszel only needs access to read container information. For [linuxserver/docker-socket-proxy](https://github.com/linuxserver/docker-socket-proxy) you would set `CONTAINERS=1`. -->
## OAuth / OIDC setup ## OAuth / OIDC setup