Skip to content

Commit b11c108

Browse files
committed
Add: Unix Sockets
1 parent a511e39 commit b11c108

File tree

3 files changed

+74
-10
lines changed

3 files changed

+74
-10
lines changed

docs/configuration.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,20 +276,30 @@ server:
276276
When set to `true`, Glance will use the `X-Forwarded-For` header to determine the original IP address of the request, so make sure that your reverse proxy is correctly configured to send that header.
277277

278278
## Server
279-
Server configuration is done through a top level `server` property. Example:
279+
Server configuration is done through a top level `server` property. You can configure the server to listen on either TCP or Unix socket.
280280

281+
TCP example:
281282
```yaml
282283
server:
284+
host: localhost
283285
port: 8080
284286
assets-path: /home/user/glance-assets
285287
```
286288

289+
Unix socket example:
290+
```yaml
291+
server:
292+
socket-path: /tmp/glance.sock
293+
assets-path: /home/user/glance-assets
294+
```
295+
287296
### Properties
288297

289298
| Name | Type | Required | Default |
290299
| ---- | ---- | -------- | ------- |
291300
| host | string | no | |
292301
| port | number | no | 8080 |
302+
| socket-path | string | no | |
293303
| proxied | boolean | no | false |
294304
| base-url | string | no | |
295305
| assets-path | string | no | |
@@ -300,6 +310,17 @@ The address which the server will listen on. Setting it to `localhost` means tha
300310
#### `port`
301311
A number between 1 and 65,535, so long as that port isn't already used by anything else.
302312

313+
#### `socket-path`
314+
Path to a Unix socket file to listen on instead of TCP host:port. When specified, the server will listen on a Unix socket rather than a TCP port. Cannot be used together with `host`. The socket file will be created if it doesn't exist, and any existing file at the path will be removed before creating the socket.
315+
316+
Example:
317+
```yaml
318+
server:
319+
socket-path: /tmp/glance.sock
320+
```
321+
322+
This is useful for running behind reverse proxies that support Unix sockets, or in containerized environments where you want to share the socket via a volume mount.
323+
303324
#### `proxied`
304325
Set to `true` if you're using a reverse proxy in front of Glance. This will make Glance use the `X-Forwarded-*` headers to determine the original request details.
305326

internal/glance/config.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type config struct {
3131
Server struct {
3232
Host string `yaml:"host"`
3333
Port uint16 `yaml:"port"`
34+
SocketPath string `yaml:"socket-path"`
3435
Proxied bool `yaml:"proxied"`
3536
AssetsPath string `yaml:"assets-path"`
3637
BaseURL string `yaml:"base-url"`
@@ -483,6 +484,18 @@ func isConfigStateValid(config *config) error {
483484
}
484485
}
485486

487+
// Validate server listening configuration
488+
hasSocketPath := config.Server.SocketPath != ""
489+
hasExplicitHostPort := config.Server.Host != ""
490+
491+
if hasSocketPath && hasExplicitHostPort {
492+
return fmt.Errorf("cannot specify both socket-path and host when using socket-path")
493+
}
494+
495+
if !hasSocketPath && !hasExplicitHostPort && config.Server.Port == 0 {
496+
return fmt.Errorf("must specify either socket-path or host:port for server")
497+
}
498+
486499
for i := range config.Pages {
487500
page := &config.Pages[i]
488501

internal/glance/glance.go

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import (
66
"encoding/base64"
77
"fmt"
88
"log"
9+
"net"
910
"net/http"
11+
"os"
1012
"path/filepath"
1113
"slices"
1214
"strconv"
@@ -489,19 +491,47 @@ func (a *application) server() (func() error, func() error) {
489491
}
490492

491493
server := http.Server{
492-
Addr: fmt.Sprintf("%s:%d", a.Config.Server.Host, a.Config.Server.Port),
493494
Handler: mux,
494495
}
495496

496497
start := func() error {
497-
log.Printf("Starting server on %s:%d (base-url: \"%s\", assets-path: \"%s\")\n",
498-
a.Config.Server.Host,
499-
a.Config.Server.Port,
500-
a.Config.Server.BaseURL,
501-
absAssetsPath,
502-
)
503-
504-
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
498+
var listener net.Listener
499+
var err error
500+
501+
if a.Config.Server.SocketPath != "" {
502+
// Unix socket mode
503+
// Remove existing socket file if it exists
504+
if err := os.RemoveAll(a.Config.Server.SocketPath); err != nil {
505+
return fmt.Errorf("failed to remove existing socket file: %w", err)
506+
}
507+
508+
listener, err = net.Listen("unix", a.Config.Server.SocketPath)
509+
if err != nil {
510+
return fmt.Errorf("failed to listen on unix socket: %w", err)
511+
}
512+
513+
log.Printf("Starting server on unix socket %s (base-url: \"%s\", assets-path: \"%s\")\n",
514+
a.Config.Server.SocketPath,
515+
a.Config.Server.BaseURL,
516+
absAssetsPath,
517+
)
518+
} else {
519+
// TCP mode
520+
addr := fmt.Sprintf("%s:%d", a.Config.Server.Host, a.Config.Server.Port)
521+
listener, err = net.Listen("tcp", addr)
522+
if err != nil {
523+
return fmt.Errorf("failed to listen on tcp address: %w", err)
524+
}
525+
526+
log.Printf("Starting server on %s:%d (base-url: \"%s\", assets-path: \"%s\")\n",
527+
a.Config.Server.Host,
528+
a.Config.Server.Port,
529+
a.Config.Server.BaseURL,
530+
absAssetsPath,
531+
)
532+
}
533+
534+
if err := server.Serve(listener); err != nil && err != http.ErrServerClosed {
505535
return err
506536
}
507537

0 commit comments

Comments
 (0)