Releases: yusing/godoxy
v0.8.0
GoDoxy v0.8 changes:
Breaking changes
-
Removed
redirect_to_https
inconfig.yml
, superseded byredirectHTTP
as an entrypoint middleware -
New notification config format, support webhook notification, support multiple notification providers
old
providers: notification: gotify: url: ... token: ...
new
providers: notification: - name: gotify provider: gotify url: ... token: ... - name: discord provider: webhook url: https://discord.com/api/webhooks/... template: discord
Webhook notification fields:
Field Description Required Allowed values name name of the provider Yes provider Yes webhook
url webhook URL Yes Full URL template webhook template No empty, discord
token webhook token No payload webhook payload No (if template
is used)valid json method webhook request method No GET POST PUT
mime_type mime type No color_mode color mode No hex
dec
Available payload variables:
Variable Description Format $title message title json string $message message in markdown format json string $fields extra fields in json format json object $color embed color by color_mode
0xff0000
(hex) or16711680
(dec)
Non-breaking changes
-
services health notification now in markdown format like
Uptime Kuma
for both webhook and Gotify -
docker services now use docker container health status if possible, fallback to GoDoxy health check on failure / no docker health check, e.g.
# docker compose services: app: ... container_name: app healthcheck: test: ["CMD-SHELL", "curl --fail http://localhost:8080 || exit 1"] interval: 5s
Health check result will be equivalent to
docker inspect --format='{{json .State.Health}}' app
-
proxy.<alias>.path_patterns
fully support http.ServeMux patterns[METHOD ][HOST]/[PATH]
(See https://pkg.go.dev/net/http#hdr-Patterns-ServeMux) -
caching ACME private key in order to reuse ACME account, to prevent from ACME rate limit
-
WebUI config editor now validates for middleware compose files
-
New: fully support string as inline YAML for docker labels
services: app: ... labels: # add '|' after colon ':' to treat it as string proxy.app: | scheme: http host: 10.0.0.254 port: 80 path_patterns: - GET / - POST /auth healthcheck: disabled: false path: / interval: 5s proxy.app1.healthcheck: | path: /ping use_get: true proxy.app1.load_balance: | link: app mode: ip_hash
-
New: support entrypoint middlewares (applied to all routes, before route middlewares)
entrypoint: middlewares: - use: CIDRWhitelist allow: - "127.0.0.1" - "10.0.0.0/8" - "192.168.0.0/16" status: 403 message: "Forbidden"
-
New: support exact host matching, i.e.
# include file app1.domain.tld: host: 10.0.0.1 # docker compose services: app1: ... proxy.aliases: app1.domain.tld
will only match exactly
app1.domain.tld
match_domains
in config will be ignored for this route -
New: support host matching without a subdomain, i.e.
app1: host: 10.0.0.1
will now also match
app1.tld
-
New: support
x-properties
(will be ignored, like in docker compose), useful with YAML anchor e.g.x-proxy: &proxy # this will be ignored in GoDoxy scheme: https healthcheck: disable: true middlewares: hideXForwarded: modifyRequest: setHeaders: Host: $req_host api.openai.com: <<: *proxy # extends from x-proxy host: api.openai.com api.groq.com: <<: *proxy # extends from x-proxy host: api.groq.com
-
new middleware name aliases:
modifyRequest
=request
modifyResponse
=response
-
New: support
$
variables inrequest
andresponse
middlewares (like nginx config)$req_method
: request http method$req_scheme
: request URL scheme (http/https)$req_host
: request host without port$req_port
: request port$req_addr
: request host with port (if present)$req_path
: request URL path$req_query
: raw query string$req_url
: full request URL$req_uri
: request URI (encoded path?query)$req_content_type
: request Content-Type header$req_content_length
: length of request body (if present)$remote_addr
: client's remote address (may changed by middlewares likeRealIP
andCloudflareRealIP
)$remote_host
: client's remote ip parse from$remote_addr
$remote_port
: client's remote port parse from$remote_addr
(may be empty)$resp_content_type
: response Content-Type header$resp_content_length
: length response body$status_code
: response status code$upstream_name
: upstream server name (alias)$upstream_scheme
: upstream server scheme$upstream_host
: upstream server host$upstream_port
: upstream server port$upstream_addr
: upstream server address with port (if present)$upstream_url
: full upstream server URL$header(name)
: get request header by name$resp_header(name)
: get response header by name$arg(name)
: get URL query parameter by name
-
New: Access Logging (entrypoint and per route), i.e.
mount logs directory before setting this
# config.yml entrypoint: access_log: format: json # common, combined, json path: /app/logs/access.json.log filters: cidr: negative: true # no log for local requests values: - 127.0.0.1/32 - 172.0.0.0/8 - 192.168.0.0/16 - 10.0.0.0/16 fields: headers: default: drop # drop app headers in log config: # keep only these X-Real-Ip: keep CF-Connecting-Ip: keep X-Forwarded-For: keep # include file # same as above but under route config app: access_log: format: json # common, combined, json ... # docker labels labels: proxy.app.access_log: | format: json path: /app/logs/access.json.log filters: cidr: negative: true values: - 127.0.0.1/32 - 172.0.0.0/8 - 192.168.0.0/16 - 10.0.0.0/16
To integrate with goaccess, currently need to use caddy as a file web server. Below should work with
combined
log format.# compose.yml services: app: image: reg.6uo.me/yusing/goproxy ... volumes: ... - ./logs:/app/logs caddy: image: caddy restart: always labels: proxy.goaccess.port: 80 proxy.goaccess.middlewares.request.set_headers.Host: goaccess volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro - ./logs:/var/www/goaccess:ro depends_on: - goaccess goaccess: image: hectorm/goaccess:latest restart: always volumes: - ./logs:/srv/logs command: > # for combined format /srv/logs/access.log -o /srv/logs/report.html -j 4 # 4 threads --real-time-html --ws-url=<your goaccess url>:443 # i.e. goaccess.my.app:443 --log-format='%v %h %^[%d:%t %^] "%r" %s %b "%R" "%u"'
Caddyfile
{ auto_https off } goaccess:80 { @websockets { header Connection *Upgrade header Upgrade websocket } handle @websockets { reverse_proxy goaccess:7890 } root * /var/www/goaccess file_server rewrite / /report.html }
Fixes
- duplicated notification after config reload
timeout
was defaulted to0
in some cases causing health check to failredirectHTTP
middleware may not work on non standard http port- various other small bugs
realIP
andcloudflareRealIP
middlewares- prometheus metrics gone after a single route reload
- WebUI app links now works when
match_domains
is not set - WebUI config editor now display validation errors properly
- upgraded dependencies to the latest
v0.7.7
What's changed
Changed
- logging: moved API request log to debug level (introduced in 0.7.6)
- code: simplified label parsing implementation, more readable, maintainable and also faster
- code: removed unnecessary mutex and mutex locking
- healthcheck: health checker now send an user agent indicating GoDoxy and its version
Fixed
- logging: fixed missing error subject on validation error for routes from include file
- bug: panic on invalid map value in docker labels
- bug:
healthcheck.disable
not being respected - bug: incorrect health check returned unhealthy even if it isn't in some scenerios
- bug: health checker looking for incorrect address for stream routes
- webui: fixed statistics not loading property
v0.7.6
What's changed
New
- New: Prometheus metrics server See Grafana dashboard template
Changed
- Update setup instructions by @codekoala in #30
- Updated to go1.23.3
Fixed
ModifyRequest
middlewareset_header
not working properly forHost
headerCIDRAllowList
middlewares may share there IP cache map between each other
Full Changelog: 0.7.5...0.7.6
v0.7.5
What's changed
New
- Default app categories detected from alias and docker image name d89d97b
- Option in
config.yml
to disable it cf1ecbc
Changed
- Default config added inside docker image c6a9a81
- Rebrand as
GoDoxy
- WebUI / API Authentication will be disabled by default if JWT secret is not set or empty b63ebfc
Fixed
v0.7.4
What's changed
New:
- New rate limiter middleware
Changed:
- API server is now protected with rate limiter
Fixed:
- Extra dot in app URLs on WebUI dashboard (introduced in v0.7.3)
v0.7.3
v0.7.2
v0.7.1
What's changed
New
GOPROXY_API_JWT_TOKEN_TTL
: control JWT token time-to-live
Changed
- Moved environment variables from docker compose to
.env.example
- Updated
compose.example.yml
Fixed
- Incorrect behaviors for
ls-*
commands - several typos
Full Changelog: 0.7.0...0.7.1
v0.7
What's changed
New
- Health status monitoring feature
- status and uptime on dashboard
app: healthcheck: disabled: false # default false path: "" # default empty use_get: false # use GET instead of HEAD, default false interval: 5s # default 5s timeout: 5s # default 5s
- Gotify support: send notification when service health status changed
# under config.yml -> providers section providers: include: ... docker: ... notification: gotify: url: https://gotify.domain.tld token: abcdef.12345
Breaking Changes
- webui: now WebUI and APIs require authentication
- environment variables: new, required
GOPROXY_API_JWT_SECRET
: base64 string of jwt secret, generate withopenssl rand -base64 32
GOPROXY_API_USER
: login username (defaults toadmin
)GOPROXY_API_PASSWORD
: login password (defaults topassword
)
Non-breaking Changes
- docker:
proxy.aliases
is now optional,proxy.<alias>.<field>
will work without it - middleware:
ip_hash
load balancer now support realIP middleware - logging: migrated from
sirupsen/logrus
tors/zerolog
- logging: better output and error formatting
- logging: suggest "Do you mean ____?" on invalid options
- code: introduced new
task
module to manage context and tasks to ensure resources are released and goroutines are stopped correctly - code: rewritten
error
module - code: rewritten config and docker reload handling with event queue
Fixed
- loadbalancer:
ip_hash
incorrect behavior - loadbalancer: services with same alias will no longer cause conflict
- idlewatcher: load-balanced routes now works with
idle_timeout
- reload: include file reload does not show in log
- reload: proxy url turns into
127.0.0.1:80
after reload - reload: streams stucked forever on stop
- reload: removed routes persist on config reload
- webui: loadbalanced routes no longer show up in dashboard (i.e. only loadbalancer nginx is shown but not nginx-1, nginx-2, ... )
- bug: shutdown stuck causing graceful shutdown to fail
- bug: various bugs that causing nil deference panic
- bug: memory leak for stream routes
- bug: route not removed on container destroy
- bug: crash on invalid middleware options
Full Changelog: 0.6.4-1...0.7.0