This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Build Go binary
|
||||
FROM golang:1.25-alpine AS builder
|
||||
FROM golang:1.22-alpine AS builder
|
||||
WORKDIR /src
|
||||
RUN apk add --no-cache ca-certificates tzdata
|
||||
COPY go.mod ./
|
||||
@@ -13,7 +13,7 @@ RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/ntfywui ./cmd/ntfy
|
||||
FROM binwiederhier/ntfy:latest AS ntfy
|
||||
|
||||
# Runtime
|
||||
FROM alpine:3.23
|
||||
FROM alpine:3.20
|
||||
RUN apk add --no-cache ca-certificates tzdata \
|
||||
&& addgroup -S ntfywui && adduser -S -G ntfywui -h /home/ntfywui ntfywui
|
||||
WORKDIR /app
|
||||
|
||||
@@ -62,25 +62,25 @@ func main() {
|
||||
logger := log.New(os.Stdout, "", log.LstdFlags)
|
||||
|
||||
s := app.NewServer(app.Config{
|
||||
BasePath: strings.TrimRight(*basePath, "/"),
|
||||
DataDir: *dataDir,
|
||||
Secret: secKey,
|
||||
CookieSecure: *cookieSecure,
|
||||
BasePath: strings.TrimRight(*basePath, "/"),
|
||||
DataDir: *dataDir,
|
||||
Secret: secKey,
|
||||
CookieSecure: *cookieSecure,
|
||||
TrustedProxies: trusted,
|
||||
NtfyBin: *ntfyBin,
|
||||
NtfyConfig: *ntfyConfig,
|
||||
NtfyTimeout: *reqTimeout,
|
||||
Logger: logger,
|
||||
NtfyBin: *ntfyBin,
|
||||
NtfyConfig: *ntfyConfig,
|
||||
NtfyTimeout: *reqTimeout,
|
||||
Logger: logger,
|
||||
})
|
||||
|
||||
httpSrv := &http.Server{
|
||||
Addr: *listenAddr,
|
||||
Handler: s.Handler(),
|
||||
ReadTimeout: 15 * time.Second,
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
WriteTimeout: 30 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
ReadTimeout: 15 * time.Second,
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
WriteTimeout: 30 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -45,41 +46,67 @@ func (c *Client) Run(ctx context.Context, args []string, env map[string]string,
|
||||
if c.Bin == "" {
|
||||
return "", "", 0, errors.New("ntfy binary not set")
|
||||
}
|
||||
|
||||
// Many (newer) ntfy versions support `--config/-c` for server-side commands
|
||||
// (serve/user/access/token). Some older builds do not. We try with --config
|
||||
// first (if configured) and fall back to running without it if the binary
|
||||
// rejects the flag.
|
||||
withConfig := args
|
||||
if c.Config != "" {
|
||||
args = append([]string{"--config", c.Config}, args...)
|
||||
withConfig = append([]string{"--config", c.Config}, args...)
|
||||
}
|
||||
|
||||
tctx := ctx
|
||||
var cancel context.CancelFunc
|
||||
if c.Timeout > 0 {
|
||||
tctx, cancel = context.WithTimeout(ctx, c.Timeout)
|
||||
defer cancel()
|
||||
}
|
||||
cmd := exec.CommandContext(tctx, c.Bin, args...)
|
||||
if stdin != "" {
|
||||
cmd.Stdin = strings.NewReader(stdin)
|
||||
// helper to execute once
|
||||
runOnce := func(a []string) (string, string, int, error) {
|
||||
cmd := exec.CommandContext(tctx, c.Bin, a...)
|
||||
if stdin != "" {
|
||||
cmd.Stdin = strings.NewReader(stdin)
|
||||
}
|
||||
var outb, errb bytes.Buffer
|
||||
cmd.Stdout = &outb
|
||||
cmd.Stderr = &errb
|
||||
if env != nil {
|
||||
// inherit env + add/override provided vars
|
||||
cmd.Env = append([]string{}, os.Environ()...)
|
||||
for k, v := range env {
|
||||
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
}
|
||||
err := cmd.Run()
|
||||
exit := 0
|
||||
if err != nil {
|
||||
var ee *exec.ExitError
|
||||
if errors.As(err, &ee) {
|
||||
exit = ee.ExitCode()
|
||||
} else if errors.Is(err, context.DeadlineExceeded) {
|
||||
return outb.String(), errb.String(), -1, fmt.Errorf("ntfy timeout")
|
||||
} else {
|
||||
return outb.String(), errb.String(), -1, err
|
||||
}
|
||||
}
|
||||
return outb.String(), errb.String(), exit, nil
|
||||
}
|
||||
var outb, errb bytes.Buffer
|
||||
cmd.Stdout = &outb
|
||||
cmd.Stderr = &errb
|
||||
if env != nil {
|
||||
// inherit env automatically
|
||||
for k, v := range env {
|
||||
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v))
|
||||
|
||||
// first attempt (maybe with --config)
|
||||
out, errOut, exit, err := runOnce(withConfig)
|
||||
if c.Config == "" {
|
||||
return out, errOut, exit, err
|
||||
}
|
||||
// fallback for older ntfy binaries that don't know --config
|
||||
if exit != 0 {
|
||||
errTrim := strings.TrimSpace(errOut)
|
||||
if strings.Contains(errTrim, "flag provided but not defined: -config") ||
|
||||
strings.Contains(errTrim, "unknown flag") && strings.Contains(errTrim, "config") {
|
||||
return runOnce(args)
|
||||
}
|
||||
}
|
||||
err := cmd.Run()
|
||||
exit := 0
|
||||
if err != nil {
|
||||
var ee *exec.ExitError
|
||||
if errors.As(err, &ee) {
|
||||
exit = ee.ExitCode()
|
||||
} else if errors.Is(err, context.DeadlineExceeded) {
|
||||
return outb.String(), errb.String(), -1, fmt.Errorf("ntfy timeout")
|
||||
} else {
|
||||
return outb.String(), errb.String(), -1, err
|
||||
}
|
||||
}
|
||||
return outb.String(), errb.String(), exit, nil
|
||||
return out, errOut, exit, err
|
||||
}
|
||||
|
||||
func (c *Client) ListUsers(ctx context.Context) ([]User, error) {
|
||||
|
||||
Reference in New Issue
Block a user