fix Makefile
Kim committed
Oct 21, 2025 at 11:56 UTC
68843fa4bed43a4782eac32a19d6478e548a26a1
6 files changed
+359
-264
Dockerfile
new
+22
@@ -0,0 +1,22 @@
1
+# Multi-stage build for relayserver
2
+FROM golang:1 AS builder
3
+
4
+WORKDIR /src
5
+
6
+COPY go.mod go.sum ./
7
+RUN --mount=type=cache,target=/go/pkg/mod \
8
+ go mod download
9
+
10
+COPY . .
11
+RUN --mount=type=cache,target=/go/pkg/mod \
12
+ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
13
+ go build -trimpath -ldflags "-s -w" -o /out/relayserver ./cmd/server
14
+
15
+# Minimal runtime image
16
+FROM gcr.io/distroless/static-debian12:nonroot
17
+
18
+COPY --from=builder /out/relayserver /usr/bin/relayserver
19
+
20
+EXPOSE 8080 8082 4001/tcp 4001/udp
21
+
22
+ENTRYPOINT ["/usr/bin/relayserver"]
Makefile
new
+51
@@ -0,0 +1,51 @@
1
+SHELL := /bin/sh
2
+.PHONY: help server-up server-down server-build client-run client-build fmt tidy
3
+
4
+# Detect docker compose command (override with `make DC="docker-compose"` if needed)
5
+DC ?= docker compose
6
+
7
+# ---------- Server (docker) ----------
8
+server-up:
9
+ $(DC) up -d --build
10
+
11
+server-down:
12
+ $(DC) down
13
+
14
+server-build:
15
+ $(DC) build
16
+
17
+# ---------- Client (local go) ----------
18
+# Default flags (override via `make VAR=value`)
19
+SERVER_URL ?= http://localhost:8080
20
+BACKEND_HTTP ?= :8081
21
+# Optional repeated flags: BOOTSTRAPS="/dnsaddr/example/p2p/12D3... /ip4/1.2.3.4/tcp/4001/p2p/12D3..."
22
+BOOTSTRAPS ?=
23
+CLIENT_BOOTSTRAPS_FLAGS := $(foreach b,$(BOOTSTRAPS),--bootstrap $(b))
24
+
25
+CLIENT_FLAGS := \
26
+ --server-url $(SERVER_URL) \
27
+ --backend-http $(BACKEND_HTTP) \
28
+ $(CLIENT_BOOTSTRAPS_FLAGS)
29
+
30
+client-run:
31
+ go run ./cmd/example_client $(CLIENT_FLAGS)
32
+
33
+client-build:
34
+ go build -trimpath -o bin/relaydns-client ./cmd/example_client
35
+
36
+# ---------- Dev helpers ----------
37
+fmt:
38
+ go fmt ./...
39
+
40
+tidy:
41
+ go mod tidy
42
+
43
+help:
44
+ @echo "Server:"
45
+ @echo " make server-up # build and start relayserver (docker compose)"
46
+ @echo " make server-down # stop and remove containers"
47
+ @echo "\nClient:"
48
+ @echo " make client-run # run example_client locally with minimal flags"
49
+ @echo " make client-build # build example_client to ./bin/relaydns-client"
50
+ @echo "\nFlags (override with make VAR=value):"
51
+ @echo " SERVER_URL BACKEND_HTTP BOOTSTRAPS"
README.md
+136
-94
@@ -1,94 +1,136 @@
1
-# RelayDNS
2
-> A lightweight, DNS-driven peer-to-peer proxy layer built on libp2p.
3
-
4
-`relaydns` provides a minimal DNS-entry proxy that routes traffic between arbitrary nodes over **libp2p**.
5
-It lets you expose and discover TCP services (like SSH, API endpoints, etc.) even behind NAT,
6
-without depending on centralized reverse-proxy services.
7
-
8
-## Features
9
-
10
-- 🛰 **Peer-to-peer routing** over libp2p (supports hole punching, relay, pubsub)
11
-- 🧩 **DNS-driven entrypoint** (server acts as a lightweight coordinator)
12
-- 🔄 **Automatic peer advertisement** via GossipSub
13
-- 🔌 **Pluggable client SDK** — embed the relaydns client directly into your Go applications
14
-- 🪶 **Lightweight** and dependency-minimal (Cobra CLI + Go libp2p only)
15
-
16
-## Architecture Overview
17
-
18
-```
19
-┌──────────────┐ pubsub (GossipSub) ┌──────────────┐
20
-│ relaydns │ <--------------------------> │ client(s) │
21
-│ server │ │ (imported in │
22
-│ (director) │ │ your app) │
23
-└──────────────┘ └──────────────┘
24
- │ │
25
- │ TCP stream (e.g. SSH, HTTP, custom) │
26
- ▼ ▼
27
- Your users Your local service
28
-```
29
-
30
-## Getting Started
31
-
32
-### 1️⃣ Run the RelayDNS Server
33
-
34
-The **server** acts as a public entrypoint that accepts incoming TCP connections
35
-and forwards them over libp2p to available clients.
36
-
37
-```bash
38
-go build -o relaydns ./cmd/relaydns
39
-
40
-./relaydns \
41
- --listen-tcp :22 \
42
- --listen-http :8080 \
43
- --protocol /relaydns/ssh/1.0 \
44
- --topic relaydns.backends
45
-```
46
-
47
-### 2️⃣ Embed the RelayDNS Client in Your App
48
-
49
-The client is a small Go library that you can embed in any Go program.
50
-It automatically advertises itself and tunnels incoming streams to your local TCP service.
51
-
52
-Install the module:
53
-```bash
54
-go get github.com/gosuda/relaydns
55
-```
56
-
57
-Example usage:
58
-```go
59
-package main
60
-
61
-import (
62
- "context"
63
- "log"
64
- "time"
65
-
66
- "github.com/libp2p/go-libp2p"
67
- "github.com/gosuda/relaydns/relaydns"
68
-)
69
-
70
-func main() {
71
- ctx := context.Background()
72
- h, err := libp2p.New(
73
- libp2p.EnableHolePunching(),
74
- libp2p.EnableNATService(),
75
- )
76
- if err != nil {
77
- log.Fatal(err)
78
- }
79
-
80
- client, err := relaydns.NewClient(ctx, h, relaydns.ClientConfig{
81
- Protocol: "/relaydns/ssh/1.0",
82
- Topic: "relaydns.backends",
83
- AdvertiseEvery: 5 * time.Second,
84
- TargetTCP: "127.0.0.1:22", // your local SSH or app port
85
- Name: "seoul-node",
86
- })
87
- if err != nil {
88
- log.Fatal(err)
89
- }
90
- defer client.Close()
91
-
92
- select {} // keep running
93
-}
94
-```
\ No newline at end of file
1
+# RelayDNS
2
+> A lightweight, DNS-driven peer-to-peer proxy layer built on libp2p.
3
+
4
+`relaydns` provides a minimal DNS-entry proxy that routes traffic between arbitrary nodes over **libp2p**.
5
+It lets you expose and discover TCP services (like SSH, API endpoints, etc.) even behind NAT,
6
+without depending on centralized reverse-proxy services.
7
+
8
+## Features
9
+
10
+- 🛰 **Peer-to-peer routing** over libp2p (supports hole punching, relay, pubsub)
11
+- 🧩 **DNS-driven entrypoint** (server acts as a lightweight coordinator)
12
+- 🔄 **Automatic peer advertisement** via GossipSub
13
+- 🔌 **Pluggable client SDK** — embed the relaydns client directly into your Go applications
14
+- 🪶 **Lightweight** and dependency-minimal (Cobra CLI + Go libp2p only)
15
+
16
+## Architecture Overview
17
+
18
+```
19
+┌──────────────┐ pubsub (GossipSub) ┌──────────────┐
20
+│ relaydns │ <--------------------------> │ client(s) │
21
+│ server │ │ (imported in │
22
+│ (director) │ │ your app) │
23
+└──────────────┘ └──────────────┘
24
+ │ │
25
+ │ TCP stream (e.g. SSH, HTTP, custom) │
26
+ ▼ ▼
27
+ Your users Your local service
28
+```
29
+
30
+## Getting Started
31
+
32
+### 1️⃣ Run the Server (Docker Compose)
33
+
34
+The server accepts incoming TCP connections and forwards them over libp2p to available clients.
35
+
36
+Option A — using Makefile:
37
+```bash
38
+make server-up # build + start
39
+make server-down # stop
40
+```
41
+
42
+Option B — raw docker compose:
43
+```bash
44
+docker compose up --build -d
45
+docker compose logs -f relayserver
46
+```
47
+
48
+Published ports:
49
+- Admin HTTP: `8080`
50
+- HTTP ingress (tcp-level): `8082`
51
+- libp2p TCP/QUIC: `4001/tcp`, `4001/udp`
52
+
53
+To add bootstraps, edit `docker-compose.yml` and append repeated `--bootstrap` flags under `relayserver.command`.
54
+
55
+### 2️⃣ Run the Example Client (Local Go)
56
+
57
+The example client runs a local HTTP backend and advertises it via libp2p.
58
+
59
+Option A — using Makefile (recommended):
60
+```bash
61
+make client-run \
62
+ BACKEND_HTTP=:8081 \
63
+ SERVER_URL=http://localhost:8080 \
64
+ BOOTSTRAPS="/dnsaddr/your.bootstrap/p2p/12D3Koo..."
65
+```
66
+
67
+Option B — go run directly:
68
+```bash
69
+go run ./cmd/example_client \
70
+ --backend-http :8081 \
71
+ --server-url http://localhost:8080 \
72
+ --bootstrap /dnsaddr/your.bootstrap/p2p/12D3Koo... \
73
+
74
+```
75
+
76
+The client exposes a tiny local HTTP server at `--backend-http` and tunnels traffic from the server to this address via libp2p streams.
77
+
78
+### 3️⃣ Embed the Client SDK in Your App
79
+
80
+Install the module:
81
+```bash
82
+go get github.com/gosuda/relaydns
83
+```
84
+
85
+Minimal snippet:
86
+```go
87
+package main
88
+
89
+import (
90
+ "context"
91
+ "time"
92
+ "github.com/gosuda/relaydns/relaydns"
93
+ "github.com/libp2p/go-libp2p"
94
+)
95
+
96
+func main() {
97
+ ctx := context.Background()
98
+ h, _ := libp2p.New(libp2p.EnableHolePunching(), libp2p.EnableNATService())
99
+ client, _ := relaydns.NewClient(ctx, h, relaydns.ClientConfig{
100
+ Protocol: "/relaydns/http/1.0",
101
+ Topic: "relaydns.backends",
102
+ AdvertiseEvery: 5 * time.Second,
103
+ TargetTCP: "127.0.0.1:8081",
104
+ Name: "demo-http",
105
+ })
106
+ defer client.Close()
107
+ select {}
108
+}
109
+```
110
+
111
+## Configuration Reference
112
+
113
+Server flags (see `docker-compose.yml`):
114
+- `--admin-http` Admin API listen address (default `:8080`)
115
+- `--ingress-http` HTTP ingress listen address (default `:8082`)
116
+- `--bootstrap` Repeatable multiaddr with `/p2p/`
117
+
118
+Example client flags (see `make client-run`):
119
+- `--server-url` Admin base URL to fetch `/health` (default `http://localhost:8080`)
120
+- `--bootstrap` Repeatable multiaddr with `/p2p/`
121
+- `--backend-http` Local backend HTTP listen address (default `:8081`)
122
+
123
+## Logging
124
+
125
+This project uses `zerolog` for structured logging. Binaries initialize a human-friendly console logger by default.
126
+
127
+## Development
128
+
129
+Useful commands:
130
+```bash
131
+make server-up # build and start the server via docker compose
132
+make server-down # stop the compose stack
133
+
134
+make client-run # run the example client locally
135
+make client-build # build the example client to ./bin/relaydns-client
136
+```
cmd/example_client/main.go
+39
-59
@@ -1,19 +1,19 @@
1
package main
2
3
-import (
4
- "context"
5
- "fmt"
6
- "net/http"
7
- "os"
8
- "os/signal"
9
- "syscall"
10
- "text/template"
11
- "time"
12
-
13
- "github.com/gosuda/relaydns/relaydns"
14
- "github.com/rs/zerolog/log"
15
- "github.com/spf13/cobra"
16
-)
3
+import (
4
+ "context"
5
+ "fmt"
6
+ "net/http"
7
+ "os"
8
+ "os/signal"
9
+ "syscall"
10
+ "text/template"
11
+ "time"
12
+
13
+ "github.com/gosuda/relaydns/relaydns"
14
+ "github.com/rs/zerolog/log"
15
+ "github.com/spf13/cobra"
16
+)
17
18
var rootCmd = &cobra.Command{
19
Use: "relaydns-client",
@@ -21,36 +21,18 @@ var rootCmd = &cobra.Command{
21
RunE: runClient,
22
}
23
24
-var (
25
- flagServerURL string
26
- flagBootstraps []string
27
- flagRelay bool
28
- flagBackendHTTP string
29
- flagProtocol string
30
- flagTopic string
31
- flagAdvertiseEvery time.Duration
32
- flagName string
33
- flagDNS string
34
- flagPreferQUIC bool
35
- flagPreferLocal bool
36
- flagHTTPTimeout time.Duration
37
-)
24
+var (
25
+ flagServerURL string
26
+ flagBootstraps []string
27
+ flagBackendHTTP string
28
+)
29
39
-func init() {
40
- flags := rootCmd.PersistentFlags()
41
- flags.StringVar(&flagServerURL, "server-url", "http://localhost:8080", "relayserver admin base URL (e.g. http://127.0.0.1:9090) to auto-fetch multiaddrs from /health")
42
- flags.StringSliceVar(&flagBootstraps, "bootstrap", nil, "multiaddrs with /p2p/ (supports /dnsaddr/ that resolves to /p2p/)")
43
- flags.BoolVar(&flagRelay, "relay", true, "enable libp2p relay/hole-punch support")
44
- flags.StringVar(&flagBackendHTTP, "backend-http", ":8081", "local backend HTTP listen address")
45
- flags.StringVar(&flagProtocol, "protocol", "/relaydns/http/1.0", "libp2p protocol id for streams (must match server)")
46
- flags.StringVar(&flagTopic, "topic", "relaydns.backends", "pubsub topic for backend adverts")
47
- flags.DurationVar(&flagAdvertiseEvery, "advertise-every", 3*time.Second, "interval for backend adverts")
48
- flags.StringVar(&flagName, "name", "demo-http", "backend display name")
49
- flags.StringVar(&flagDNS, "dns", "demo-http.example", "backend DNS metadata (optional)")
50
- flags.BoolVar(&flagPreferQUIC, "prefer-quic", true, "prefer QUIC multiaddrs when available")
51
- flags.BoolVar(&flagPreferLocal, "prefer-local", true, "prefer loopback/local multiaddrs when available")
52
- flags.DurationVar(&flagHTTPTimeout, "http-timeout", 3*time.Second, "timeout for server /health fetch")
53
-}
30
+func init() {
31
+ flags := rootCmd.PersistentFlags()
32
+ flags.StringVar(&flagServerURL, "server-url", "http://localhost:8080", "relayserver admin base URL to auto-fetch multiaddrs from /health")
33
+ flags.StringSliceVar(&flagBootstraps, "bootstrap", nil, "multiaddrs with /p2p/ (supports /dnsaddr/ that resolves to /p2p/)")
34
+ flags.StringVar(&flagBackendHTTP, "backend-http", ":8081", "local backend HTTP listen address")
35
+}
36
37
func main() {
38
if err := rootCmd.Execute(); err != nil {
@@ -89,26 +71,24 @@ func runClient(cmd *cobra.Command, args []string) error {
71
}
72
}()
73
92
- // 2) libp2p host
93
- h, err := relaydns.MakeHost(ctx, 0, flagRelay)
74
+ // 2) libp2p host
75
+ h, err := relaydns.MakeHost(ctx, 0, true)
76
if err != nil {
77
return fmt.Errorf("make host: %w", err)
78
}
79
98
- client, err := relaydns.NewClient(ctx, h, relaydns.ClientConfig{
99
- Protocol: flagProtocol,
100
- Topic: flagTopic,
101
- AdvertiseEvery: flagAdvertiseEvery,
102
- Name: flagName,
103
- DNS: flagDNS,
104
- TargetTCP: addrToTarget(flagBackendHTTP),
105
-
106
- ServerURL: flagServerURL,
107
- Bootstraps: flagBootstraps,
108
- HTTPTimeout: flagHTTPTimeout,
109
- PreferQUIC: flagPreferQUIC,
110
- PreferLocal: flagPreferLocal,
111
- })
80
+ client, err := relaydns.NewClient(ctx, h, relaydns.ClientConfig{
81
+ Protocol: "/relaydns/http/1.0",
82
+ Topic: "relaydns.backends",
83
+ AdvertiseEvery: 3 * time.Second,
84
+ TargetTCP: addrToTarget(flagBackendHTTP),
85
+
86
+ ServerURL: flagServerURL,
87
+ Bootstraps: flagBootstraps,
88
+ HTTPTimeout: 3 * time.Second,
89
+ PreferQUIC: true,
90
+ PreferLocal: true,
91
+ })
92
if err != nil {
93
return fmt.Errorf("new client: %w", err)
94
}
cmd/server/main.go
+89
-111
@@ -1,111 +1,89 @@
1
-package main
2
-
3
-import (
4
- "context"
5
- "os"
6
- "os/signal"
7
- "syscall"
8
- "time"
9
-
10
- "github.com/gosuda/relaydns/relaydns"
11
- "github.com/rs/zerolog/log"
12
- "github.com/spf13/cobra"
13
-)
14
-
15
-var rootCmd = &cobra.Command{
16
- Use: "relayserver",
17
- Short: "A lightweight, DNS-driven peer-to-peer proxy layer built on libp2p",
18
- RunE: runServer,
19
-}
20
-
21
-var (
22
- flagBootstraps []string
23
- flagRelay bool
24
-
25
- ingressTCP string // e.g. :22 (raw TCP ingress, SSH)
26
- ingressHTTP string // e.g. :8082 (HTTP ingress, Browser)
27
- adminHTTP string // e.g. :8080 (admin API)
28
- outBoundPort int // e.g. :4001 (outbound connections)
29
- protocol string // e.g. /relaydns/http/1.0
30
- topic string // e.g. relaydns.backends
31
-)
32
-
33
-func init() {
34
- flags := rootCmd.PersistentFlags()
35
- flags.StringSliceVar(&flagBootstraps, "bootstrap", nil, "multiaddrs with /p2p/ (supports /dnsaddr/ that resolves to /p2p/)")
36
- flags.BoolVar(&flagRelay, "relay", true, "enable libp2p relay support")
37
-
38
- flags.StringVar(&ingressTCP, "ingress-tcp", ":22", "L4 TCP ingress (e.g. :22 for SSH/raw TCP)")
39
- flags.StringVar(&ingressHTTP, "ingress-http", ":8082", "HTTP ingress (browser-friendly TCP port for HTTP backends)")
40
- flags.StringVar(&adminHTTP, "admin-http", ":8080", "Admin HTTP API (status/control)")
41
- flags.IntVar(&outBoundPort, "outbound-port", 4001, "Outbound connections")
42
-
43
- flags.StringVar(&protocol, "protocol", "/relaydns/http/1.0", "libp2p protocol id for streams (must match clients)")
44
- flags.StringVar(&topic, "topic", "relaydns.backends", "pubsub topic for backend adverts")
45
-}
46
-
47
-func main() {
48
- if err := rootCmd.Execute(); err != nil {
49
- log.Fatal().Err(err).Msg("execute root command")
50
- }
51
-}
52
-
53
-func runServer(cmd *cobra.Command, args []string) error {
54
- ctx, cancel := context.WithCancel(context.Background())
55
- defer cancel()
56
-
57
- h, err := relaydns.MakeHost(ctx, outBoundPort, flagRelay)
58
- if err != nil {
59
- return err
60
- }
61
- relaydns.ConnectBootstraps(ctx, h, flagBootstraps)
62
-
63
- d, err := relaydns.NewDirector(ctx, h, protocol, topic)
64
- if err != nil {
65
- return err
66
- }
67
-
68
- // 1) admin API
69
- go func() {
70
- if adminHTTP == "" {
71
- return
72
- }
73
- log.Info().Msgf("[server] admin http: %s", adminHTTP)
74
- if err := d.ServeHTTP(adminHTTP); err != nil {
75
- log.Error().Err(err).Msg("[server] admin http error")
76
- cancel()
77
- }
78
- }()
79
-
80
- // 2) L4 TCP ingress (SSH/raw TCP)
81
- go func() {
82
- if ingressTCP == "" {
83
- return
84
- }
85
- log.Info().Msgf("[server] tcp ingress: %s", ingressTCP)
86
- if err := d.ServeTCP(ingressTCP); err != nil {
87
- log.Error().Err(err).Msg("[server] tcp ingress error")
88
- cancel()
89
- }
90
- }()
91
-
92
- // 3) HTTP ingress (browser/HTTP traffic)
93
- go func() {
94
- if ingressHTTP == "" {
95
- return
96
- }
97
- log.Info().Msgf("[server] http ingress (tcp-level): %s", ingressHTTP)
98
- if err := d.ServeTCP(ingressHTTP); err != nil {
99
- log.Error().Err(err).Msg("[server] http ingress error")
100
- cancel()
101
- }
102
- }()
103
-
104
- // graceful shutdown
105
- sig := make(chan os.Signal, 1)
106
- signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
107
- <-sig
108
- cancel()
109
- time.Sleep(300 * time.Millisecond)
110
- return nil
111
-}
1
+package main
2
+
3
+import (
4
+ "context"
5
+ "os"
6
+ "os/signal"
7
+ "syscall"
8
+ "time"
9
+
10
+ "github.com/gosuda/relaydns/relaydns"
11
+ "github.com/rs/zerolog/log"
12
+ "github.com/spf13/cobra"
13
+)
14
+
15
+var rootCmd = &cobra.Command{
16
+ Use: "relayserver",
17
+ Short: "A lightweight, DNS-driven peer-to-peer proxy layer built on libp2p",
18
+ RunE: runServer,
19
+}
20
+
21
+var (
22
+ flagBootstraps []string
23
+
24
+ ingressHTTP string // e.g. :8082 (HTTP ingress, Browser)
25
+ adminHTTP string // e.g. :8080 (admin API)
26
+)
27
+
28
+func init() {
29
+ flags := rootCmd.PersistentFlags()
30
+ flags.StringSliceVar(&flagBootstraps, "bootstrap", nil, "multiaddrs with /p2p/ (supports /dnsaddr/ that resolves to /p2p/)")
31
+
32
+ flags.StringVar(&ingressHTTP, "ingress-http", ":8082", "HTTP ingress (browser-friendly TCP port for HTTP backends)")
33
+ flags.StringVar(&adminHTTP, "admin-http", ":8080", "Admin HTTP API (status/control)")
34
+}
35
+
36
+func main() {
37
+ if err := rootCmd.Execute(); err != nil {
38
+ log.Fatal().Err(err).Msg("execute root command")
39
+ }
40
+}
41
+
42
+func runServer(cmd *cobra.Command, args []string) error {
43
+ ctx, cancel := context.WithCancel(context.Background())
44
+ defer cancel()
45
+
46
+ const outBoundPort = 4001
47
+ h, err := relaydns.MakeHost(ctx, outBoundPort, true)
48
+ if err != nil {
49
+ return err
50
+ }
51
+ relaydns.ConnectBootstraps(ctx, h, flagBootstraps)
52
+
53
+ d, err := relaydns.NewDirector(ctx, h, "/relaydns/http/1.0", "relaydns.backends")
54
+ if err != nil {
55
+ return err
56
+ }
57
+
58
+ // 1) admin API
59
+ go func() {
60
+ if adminHTTP == "" {
61
+ return
62
+ }
63
+ log.Info().Msgf("[server] admin http: %s", adminHTTP)
64
+ if err := d.ServeHTTP(adminHTTP); err != nil {
65
+ log.Error().Err(err).Msg("[server] admin http error")
66
+ cancel()
67
+ }
68
+ }()
69
+
70
+ // 2) HTTP ingress (browser/HTTP traffic)
71
+ go func() {
72
+ if ingressHTTP == "" {
73
+ return
74
+ }
75
+ log.Info().Msgf("[server] http ingress (tcp-level): %s", ingressHTTP)
76
+ if err := d.ServeTCP(ingressHTTP); err != nil {
77
+ log.Error().Err(err).Msg("[server] http ingress error")
78
+ cancel()
79
+ }
80
+ }()
81
+
82
+ // graceful shutdown
83
+ sig := make(chan os.Signal, 1)
84
+ signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
85
+ <-sig
86
+ cancel()
87
+ time.Sleep(300 * time.Millisecond)
88
+ return nil
89
+}
docker-compose.yml
new
+22
@@ -0,0 +1,22 @@
1
+version: "3.9"
2
+
3
+services:
4
+ relayserver:
5
+ build:
6
+ context: .
7
+ dockerfile: Dockerfile
8
+ image: relaydns/server:local
9
+ command:
10
+ - "--admin-http"
11
+ - ":8080"
12
+ - "--ingress-http"
13
+ - ":8082"
14
+ # To add bootstraps, add more lines like below (repeatable):
15
+ # - "--bootstrap"
16
+ # - "/dnsaddr/bootstrap.example/p2p/12D3Koo..."
17
+ ports:
18
+ - "8080:8080" # Admin HTTP
19
+ - "8082:8082" # HTTP ingress (tcp-level)
20
+ - "4001:4001/tcp" # libp2p tcp
21
+ - "4001:4001/udp" # libp2p quic/udp
22
+ restart: unless-stopped