OIDC failed #71

Closed
opened 2025-12-29 09:22:36 +01:00 by adam · 9 comments
Owner

Originally created by @siper on GitHub (May 12, 2025).

Hello, thanks for cool proxy tool. Have a problem with OIDC (Pocket-id). I setup Pocket-Id like in wiki example with Docker, but when i'l try to auth godoxy.example.com, it recursevly sends me to pocket-id. I'll try to make oidc for other container (code-server), but after auth in pocket, i'll receive Origin server is not reachable. error page. I use 0.13.0 godoxy version.
Pocket-ID docker-compose.yml

  pocket-id:
    image: ghcr.io/pocket-id/pocket-id
    restart: unless-stopped
    container_name: pocket-id
    environment:
      - PUBLIC_APP_URL=https://pocket-id.example.com
      - TRUST_PROXY=true
      - PUID=1000
      - PGID=100
      - CADDY_PORT=1444
    ports:
      - "1444:1444"
    volumes:
      - "/volume1/docker/pocket-id:/app/backend/data"
    healthcheck:
      test: "curl -f http://localhost:1444/healthz"
      interval: 1m30s
      timeout: 5s
      retries: 2
      start_period: 10s
    labels:
      - proxy.aliases=pocket-id
      - proxy.pocket-id.port=1444
      - proxy.pocket-id.healthcheck.disable=true
      - proxy.pocket-id.middlewares.redirect_http

Code-server docker-compose.yml


services:
  code-server:
    image: lscr.io/linuxserver/code-server:latest
    container_name: code-server
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=$TIMEZONE
      - PROXY_DOMAIN=code-server.example.com
      - DEFAULT_WORKSPACE=/ext
    volumes:
      - /volume1/docker/code-server:/config
      - /volume1/ext:/ext
    restart: unless-stopped
    ports:
      - 4488:8443
    labels:
      - proxy.aliases=code-server
      - proxy.code-server.port=4488
      - proxy.code-server.healthcheck.disable=true
      - proxy.code-server.middlewares.oidc

Pocket-Id OIDC client settings

Image

Godoxy docker-compose.yml

  socket-proxy:
    container_name: socket-proxy
    image: ghcr.io/yusing/socket-proxy:latest
    environment:
      - ALLOW_START=1
      - ALLOW_STOP=1
      - ALLOW_RESTARTS=1
      - CONTAINERS=1
      - EVENTS=1
      - INFO=1
      - PING=1
      - POST=1
      - VERSION=1
    volumes:
      - ${DOCKER_SOCKET:-/var/run/docker.sock}:/var/run/docker.sock
    restart: unless-stopped
    tmpfs:
      - /run
    ports:
      - ${SOCKET_PROXY_LISTEN_ADDR:-127.0.0.1:2375}:2375
    labels:
      proxy.exclude: true

  frontend:
    image: ghcr.io/yusing/godoxy-frontend:${TAG:-latest}
    container_name: godoxy-frontend
    restart: unless-stopped
    network_mode: host
    env_file: .env
    user: ${GODOXY_UID:-1000}:${GODOXY_GID:-1000}
    read_only: true
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - all
    depends_on:
      - app
    environment:
      HOSTNAME: 127.0.0.1
      PORT: ${GODOXY_FRONTEND_PORT:-3000}
    labels:
      proxy.aliases: ${GODOXY_FRONTEND_ALIASES:-godoxy}
      proxy.#1.port: ${GODOXY_FRONTEND_PORT:-3000}
      # proxy.#1.middlewares.cidr_whitelist: |
      #   status: 403
      #   message: IP not allowed
      #   allow:
      #     - 127.0.0.1
      #     - 10.0.0.0/8
      #     - 192.168.0.0/16
      #     - 172.16.0.0/12
  app:
    image: ghcr.io/yusing/godoxy:${TAG:-latest}
    container_name: godoxy
    restart: always
    network_mode: host # do not change this
    env_file: .env
    user: ${GODOXY_UID:-1000}:${GODOXY_GID:-1000}
    depends_on:
      socket-proxy:
        condition: service_started
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - all
    cap_add:
      - NET_BIND_SERVICE
    environment:
      - DOCKER_HOST=tcp://${SOCKET_PROXY_LISTEN_ADDR:-127.0.0.1:2375}
    volumes:
      - /volume1/docker/godoxy:/app/config
      - /volume1/docker/godoxy/logs:/app/logs
      - /volume1/docker/godoxy/error_pages:/app/error_pages:ro
      - /volume1/docker/godoxy/data:/app/data
      - /volume1/docker/godoxy/certs:/app/certs

Godoxy env for docker:

TAG=latest

# set timezone to get correct log timestamp
TZ=Europe/Moscow

# container uid and gid (must match the owner of mounted directories)
GODOXY_UID=1000
GODOXY_GID=100

# API JWT Configuration (common)
# generate secret with `openssl rand -base64 32`
GODOXY_API_JWT_SECRET=//rand secret
# the JWT token time-to-live
# leave empty to use default (24 hours)
# format: https://pkg.go.dev/time#Duration
GODOXY_API_JWT_TOKEN_TTL=

# API/WebUI user password login credentials (optional)
# These fields are not required for OIDC authentication
# GODOXY_API_USER=// filled, but commented for OIDC
# GODOXY_API_PASSWORD=// filled, but commented for OIDC

# OIDC Configuration (optional)
# Uncomment and configure these values to enable OIDC authentication.
#
GODOXY_OIDC_ISSUER_URL=https://pocket-id.example.com
GODOXY_OIDC_CLIENT_ID=// id exists, removed for issue
GODOXY_OIDC_CLIENT_SECRET=// secret exists, removed for issue
GODOXY_OIDC_SCOPES=openid, profile, email, groups, offline_access
GODOXY_OIDC_ALLOWED_USERS=// admin username from pocket-id, removed for issue

# Proxy listening address
GODOXY_HTTP_ADDR=:8080
GODOXY_HTTPS_ADDR=:4443

# Enable HTTP3
GODOXY_HTTP3_ENABLED=true

# API listening address
GODOXY_API_ADDR=127.0.0.1:8888

# Metrics
GODOXY_METRICS_DISABLE_CPU=false
GODOXY_METRICS_DISABLE_MEMORY=false
GODOXY_METRICS_DISABLE_DISK=false
GODOXY_METRICS_DISABLE_NETWORK=false
GODOXY_METRICS_DISABLE_SENSORS=false

# Frontend listening port
GODOXY_FRONTEND_PORT=3000

# Frontend aliases (subdomains / FQDNs, e.g. godoxy, godoxy.domain.com)
GODOXY_FRONTEND_ALIASES=godoxy

# Docker socket
# /var/run/podman/podman.sock for podman
DOCKER_SOCKET=/var/run/docker.sock
SOCKET_PROXY_LISTEN_ADDR=127.0.0.1:2375

# Debug mode
GODOXY_DEBUG=false
Originally created by @siper on GitHub (May 12, 2025). Hello, thanks for cool proxy tool. Have a problem with OIDC (Pocket-id). I setup Pocket-Id like in wiki example with Docker, but when i'l try to auth godoxy.example.com, it recursevly sends me to pocket-id. I'll try to make oidc for other container (code-server), but after auth in pocket, i'll receive Origin server is not reachable. error page. I use 0.13.0 godoxy version. Pocket-ID docker-compose.yml ```services: pocket-id: image: ghcr.io/pocket-id/pocket-id restart: unless-stopped container_name: pocket-id environment: - PUBLIC_APP_URL=https://pocket-id.example.com - TRUST_PROXY=true - PUID=1000 - PGID=100 - CADDY_PORT=1444 ports: - "1444:1444" volumes: - "/volume1/docker/pocket-id:/app/backend/data" healthcheck: test: "curl -f http://localhost:1444/healthz" interval: 1m30s timeout: 5s retries: 2 start_period: 10s labels: - proxy.aliases=pocket-id - proxy.pocket-id.port=1444 - proxy.pocket-id.healthcheck.disable=true - proxy.pocket-id.middlewares.redirect_http ``` Code-server docker-compose.yml ```version: '3' services: code-server: image: lscr.io/linuxserver/code-server:latest container_name: code-server environment: - PUID=${PUID} - PGID=${PGID} - TZ=$TIMEZONE - PROXY_DOMAIN=code-server.example.com - DEFAULT_WORKSPACE=/ext volumes: - /volume1/docker/code-server:/config - /volume1/ext:/ext restart: unless-stopped ports: - 4488:8443 labels: - proxy.aliases=code-server - proxy.code-server.port=4488 - proxy.code-server.healthcheck.disable=true - proxy.code-server.middlewares.oidc ``` Pocket-Id OIDC client settings ![Image](https://github.com/user-attachments/assets/042f9b5a-a734-4c04-8368-af85677b5002) Godoxy docker-compose.yml ```services: socket-proxy: container_name: socket-proxy image: ghcr.io/yusing/socket-proxy:latest environment: - ALLOW_START=1 - ALLOW_STOP=1 - ALLOW_RESTARTS=1 - CONTAINERS=1 - EVENTS=1 - INFO=1 - PING=1 - POST=1 - VERSION=1 volumes: - ${DOCKER_SOCKET:-/var/run/docker.sock}:/var/run/docker.sock restart: unless-stopped tmpfs: - /run ports: - ${SOCKET_PROXY_LISTEN_ADDR:-127.0.0.1:2375}:2375 labels: proxy.exclude: true frontend: image: ghcr.io/yusing/godoxy-frontend:${TAG:-latest} container_name: godoxy-frontend restart: unless-stopped network_mode: host env_file: .env user: ${GODOXY_UID:-1000}:${GODOXY_GID:-1000} read_only: true security_opt: - no-new-privileges:true cap_drop: - all depends_on: - app environment: HOSTNAME: 127.0.0.1 PORT: ${GODOXY_FRONTEND_PORT:-3000} labels: proxy.aliases: ${GODOXY_FRONTEND_ALIASES:-godoxy} proxy.#1.port: ${GODOXY_FRONTEND_PORT:-3000} # proxy.#1.middlewares.cidr_whitelist: | # status: 403 # message: IP not allowed # allow: # - 127.0.0.1 # - 10.0.0.0/8 # - 192.168.0.0/16 # - 172.16.0.0/12 app: image: ghcr.io/yusing/godoxy:${TAG:-latest} container_name: godoxy restart: always network_mode: host # do not change this env_file: .env user: ${GODOXY_UID:-1000}:${GODOXY_GID:-1000} depends_on: socket-proxy: condition: service_started security_opt: - no-new-privileges:true cap_drop: - all cap_add: - NET_BIND_SERVICE environment: - DOCKER_HOST=tcp://${SOCKET_PROXY_LISTEN_ADDR:-127.0.0.1:2375} volumes: - /volume1/docker/godoxy:/app/config - /volume1/docker/godoxy/logs:/app/logs - /volume1/docker/godoxy/error_pages:/app/error_pages:ro - /volume1/docker/godoxy/data:/app/data - /volume1/docker/godoxy/certs:/app/certs ``` Godoxy env for docker: ```# docker image tag (latest, nightly) TAG=latest # set timezone to get correct log timestamp TZ=Europe/Moscow # container uid and gid (must match the owner of mounted directories) GODOXY_UID=1000 GODOXY_GID=100 # API JWT Configuration (common) # generate secret with `openssl rand -base64 32` GODOXY_API_JWT_SECRET=//rand secret # the JWT token time-to-live # leave empty to use default (24 hours) # format: https://pkg.go.dev/time#Duration GODOXY_API_JWT_TOKEN_TTL= # API/WebUI user password login credentials (optional) # These fields are not required for OIDC authentication # GODOXY_API_USER=// filled, but commented for OIDC # GODOXY_API_PASSWORD=// filled, but commented for OIDC # OIDC Configuration (optional) # Uncomment and configure these values to enable OIDC authentication. # GODOXY_OIDC_ISSUER_URL=https://pocket-id.example.com GODOXY_OIDC_CLIENT_ID=// id exists, removed for issue GODOXY_OIDC_CLIENT_SECRET=// secret exists, removed for issue GODOXY_OIDC_SCOPES=openid, profile, email, groups, offline_access GODOXY_OIDC_ALLOWED_USERS=// admin username from pocket-id, removed for issue # Proxy listening address GODOXY_HTTP_ADDR=:8080 GODOXY_HTTPS_ADDR=:4443 # Enable HTTP3 GODOXY_HTTP3_ENABLED=true # API listening address GODOXY_API_ADDR=127.0.0.1:8888 # Metrics GODOXY_METRICS_DISABLE_CPU=false GODOXY_METRICS_DISABLE_MEMORY=false GODOXY_METRICS_DISABLE_DISK=false GODOXY_METRICS_DISABLE_NETWORK=false GODOXY_METRICS_DISABLE_SENSORS=false # Frontend listening port GODOXY_FRONTEND_PORT=3000 # Frontend aliases (subdomains / FQDNs, e.g. godoxy, godoxy.domain.com) GODOXY_FRONTEND_ALIASES=godoxy # Docker socket # /var/run/podman/podman.sock for podman DOCKER_SOCKET=/var/run/docker.sock SOCKET_PROXY_LISTEN_ADDR=127.0.0.1:2375 # Debug mode GODOXY_DEBUG=false ```
adam closed this issue 2025-12-29 09:22:36 +01:00
Author
Owner

@yusing commented on GitHub (May 12, 2025):

it recursevly sends me to pocket-id

Mind sharing your config.yml too?

receive Origin server is not reachable

  1. We don't need to map it to the host with ports, but I guess you have another rp running which needs this
  2. It should point to container port 8443 instead of host port 4448

services:
  code-server:
    image: lscr.io/linuxserver/code-server:latest
    container_name: code-server
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=$TIMEZONE
      - PROXY_DOMAIN=code-server.example.com
      - DEFAULT_WORKSPACE=/ext
    volumes:
      - /volume1/docker/code-server:/config
      - /volume1/ext:/ext
    restart: unless-stopped
    ports:
      - 4488:8443
    labels:
      - proxy.aliases=code-server
      - proxy.code-server.port=8443
      - proxy.code-server.healthcheck.disable=true
      - proxy.code-server.middlewares.oidc
@yusing commented on GitHub (May 12, 2025): > it recursevly sends me to pocket-id Mind sharing your `config.yml` too? > receive Origin server is not reachable 1. We don't need to map it to the host with `ports`, but I guess you have another rp running which needs this 2. It should point to container port `8443` instead of host port `4448` ```yaml services: code-server: image: lscr.io/linuxserver/code-server:latest container_name: code-server environment: - PUID=${PUID} - PGID=${PGID} - TZ=$TIMEZONE - PROXY_DOMAIN=code-server.example.com - DEFAULT_WORKSPACE=/ext volumes: - /volume1/docker/code-server:/config - /volume1/ext:/ext restart: unless-stopped ports: - 4488:8443 labels: - proxy.aliases=code-server - proxy.code-server.port=8443 - proxy.code-server.healthcheck.disable=true - proxy.code-server.middlewares.oidc ```
Author
Owner

@siper commented on GitHub (May 12, 2025):

config.yml

// autocert deleted for issue

# 3. other providers, see https://github.com/yusing/godoxy/wiki/Supported-DNS%E2%80%9001-Providers#supported-dns-01-providers

# acl:
#   default: allow # or deny (default: allow)
#   allow_local: true # or false (default: true)
#   allow:
#     - ip:1.2.3.4
#     - cidr:1.2.3.4/32
#     - country:US
#     - timezone:Asia/Shanghai
#   deny:
#     - ip:1.2.3.4
#     - cidr:1.2.3.4/32
#     - country:US
#     - timezone:Asia/Shanghai
#   log: # warning: logging ACL can be slow based on the number of incoming connections and configured rules
#     buffer_size: 65536 # (default: 64KB)
#     path: /app/logs/acl.log # (default: none)
#     stdout: false # (default: false)
#     keep: last 10 # (default: none)

entrypoint:
  middlewares:
    - use: RedirectHTTP
    - use: real_ip
      header: X-Real-IP
      from:
        - 127.0.0.1
        - 192.168.1.0/24
        - 10.0.0.0/8
      recursive: true
    - use: ModifyResponse
      set_headers:
        Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD
        Access-Control-Allow-Headers: "*"
        Access-Control-Allow-Origin: "*"
        Access-Control-Max-Age: 180
        Vary: "*"
        X-XSS-Protection: 1; mode=block
        Content-Security-Policy: "object-src 'self'; frame-ancestors 'self';"
        X-Content-Type-Options: nosniff
        X-Frame-Options: SAMEORIGIN
        Referrer-Policy: same-origin
        Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
  # Below define an example of middleware config
  # 1. block non local IP connections
  # 2. redirect HTTP to HTTPS
  #
  # middlewares:
  #   - use: CIDRWhitelist
  #     allow:
  #       - "127.0.0.1"
  #       - "10.0.0.0/8"
  #       - "172.16.0.0/12"
  #       - "192.168.0.0/16"
  #     status: 403
  #     message: "Forbidden"
  #   - use: RedirectHTTP

  # below enables access log
  access_log:
    format: combined
    path: /app/logs/entrypoint.log

providers:
  # include files are standalone yaml files under `config/` directory
  #
  # include:
  #   - file1.yml
  #   - file2.yml

  docker:
    # $DOCKER_HOST implies environment variable `DOCKER_HOST` or unix:///var/run/docker.sock by default
    local: $DOCKER_HOST

    # explicit only mode
    # only containers with explicit aliases will be proxied
    # add "!" after provider name to enable explicit only mode
    #
    # local!: $DOCKER_HOST
    #
    # add more docker providers if needed
    # for value format, see https://docs.docker.com/reference/cli/dockerd/
    #
    # remote-1: tcp://10.0.2.1:2375
    # remote-2: ssh://root:1234@10.0.2.2

  # notification providers (notify when service health changes)
  #
  # notification:
  #   - name: gotify
  #     provider: gotify
  #     url: https://gotify.domain.tld
  #     token: abcd
  #   - name: discord
  #     provider: webhook
  #     url: https://discord.com/api/webhooks/...
  #     template: discord # this means use payload template from internal/notif/templates/discord.json

  # Proxmox providers (for idlesleep support for proxmox LXCs)
  #
  # proxmox:
  #   - url: https://pve.domain.com:8006/api2/json
  #     token_id: root@pam!abcdef
  #     secret: aaaa-bbbb-cccc-dddd
  #     no_tls_verify: true

match_domains:
  - example.com

# homepage config
homepage:
  # use default app categories detected from alias or docker image name
  use_default_categories: true

# Below are fixed options (non hot-reloadable)

# timeout for shutdown (in seconds)
timeout_shutdown: 5

@siper commented on GitHub (May 12, 2025): config.yml ``` // autocert deleted for issue # 3. other providers, see https://github.com/yusing/godoxy/wiki/Supported-DNS%E2%80%9001-Providers#supported-dns-01-providers # acl: # default: allow # or deny (default: allow) # allow_local: true # or false (default: true) # allow: # - ip:1.2.3.4 # - cidr:1.2.3.4/32 # - country:US # - timezone:Asia/Shanghai # deny: # - ip:1.2.3.4 # - cidr:1.2.3.4/32 # - country:US # - timezone:Asia/Shanghai # log: # warning: logging ACL can be slow based on the number of incoming connections and configured rules # buffer_size: 65536 # (default: 64KB) # path: /app/logs/acl.log # (default: none) # stdout: false # (default: false) # keep: last 10 # (default: none) entrypoint: middlewares: - use: RedirectHTTP - use: real_ip header: X-Real-IP from: - 127.0.0.1 - 192.168.1.0/24 - 10.0.0.0/8 recursive: true - use: ModifyResponse set_headers: Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD Access-Control-Allow-Headers: "*" Access-Control-Allow-Origin: "*" Access-Control-Max-Age: 180 Vary: "*" X-XSS-Protection: 1; mode=block Content-Security-Policy: "object-src 'self'; frame-ancestors 'self';" X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Referrer-Policy: same-origin Strict-Transport-Security: max-age=63072000; includeSubDomains; preload # Below define an example of middleware config # 1. block non local IP connections # 2. redirect HTTP to HTTPS # # middlewares: # - use: CIDRWhitelist # allow: # - "127.0.0.1" # - "10.0.0.0/8" # - "172.16.0.0/12" # - "192.168.0.0/16" # status: 403 # message: "Forbidden" # - use: RedirectHTTP # below enables access log access_log: format: combined path: /app/logs/entrypoint.log providers: # include files are standalone yaml files under `config/` directory # # include: # - file1.yml # - file2.yml docker: # $DOCKER_HOST implies environment variable `DOCKER_HOST` or unix:///var/run/docker.sock by default local: $DOCKER_HOST # explicit only mode # only containers with explicit aliases will be proxied # add "!" after provider name to enable explicit only mode # # local!: $DOCKER_HOST # # add more docker providers if needed # for value format, see https://docs.docker.com/reference/cli/dockerd/ # # remote-1: tcp://10.0.2.1:2375 # remote-2: ssh://root:1234@10.0.2.2 # notification providers (notify when service health changes) # # notification: # - name: gotify # provider: gotify # url: https://gotify.domain.tld # token: abcd # - name: discord # provider: webhook # url: https://discord.com/api/webhooks/... # template: discord # this means use payload template from internal/notif/templates/discord.json # Proxmox providers (for idlesleep support for proxmox LXCs) # # proxmox: # - url: https://pve.domain.com:8006/api2/json # token_id: root@pam!abcdef # secret: aaaa-bbbb-cccc-dddd # no_tls_verify: true match_domains: - example.com # homepage config homepage: # use default app categories detected from alias or docker image name use_default_categories: true # Below are fixed options (non hot-reloadable) # timeout for shutdown (in seconds) timeout_shutdown: 5 ```
Author
Owner

@siper commented on GitHub (May 12, 2025):

I change port for code-server with proxy.code-server.port=8443, receives error in godoxy logs:
Image

@siper commented on GitHub (May 12, 2025): I change port for code-server with proxy.code-server.port=8443, receives error in godoxy logs: ![Image](https://github.com/user-attachments/assets/792449c9-6116-47a1-b94a-74da84f77c67)
Author
Owner

@yusing commented on GitHub (May 12, 2025):

I change port for code-server with proxy.code-server.port=8443, receives error in godoxy logs: Image

proxy.code-server.scheme=http

@yusing commented on GitHub (May 12, 2025): > I change port for code-server with proxy.code-server.port=8443, receives error in godoxy logs: ![Image](https://github.com/user-attachments/assets/792449c9-6116-47a1-b94a-74da84f77c67) `proxy.code-server.scheme=http`
Author
Owner

@yusing commented on GitHub (May 12, 2025):

it recursevly sends me to pocket-id

I'm not sure the root cause of this, try adding proxy.#1.middlewares.oidc: to frontend and see if it works.

@yusing commented on GitHub (May 12, 2025): > it recursevly sends me to pocket-id I'm not sure the root cause of this, try adding `proxy.#1.middlewares.oidc:` to frontend and see if it works.
Author
Owner

@siper commented on GitHub (May 12, 2025):

proxy.code-server.scheme=http

Yes, it works, thanks!

@siper commented on GitHub (May 12, 2025): > proxy.code-server.scheme=http Yes, it works, thanks!
Author
Owner

@yusing commented on GitHub (May 12, 2025):

proxy.code-server.scheme=http

Yes, it works, thanks!

Idk why codeserver uses an HTTPS port 8443 for HTTP, this is stupid and we should file an issue to the image maintainer

@yusing commented on GitHub (May 12, 2025): > > proxy.code-server.scheme=http > > Yes, it works, thanks! Idk why codeserver uses an HTTPS port `8443` for HTTP, this is stupid and we should file an issue to the image maintainer
Author
Owner

@siper commented on GitHub (May 12, 2025):

I'm not sure the root cause of this, try adding proxy.#1.middlewares.oidc: to frontend and see if it works.

Yes, it works too!

@siper commented on GitHub (May 12, 2025): > I'm not sure the root cause of this, try adding proxy.#1.middlewares.oidc: to frontend and see if it works. Yes, it works too!
Author
Owner

@siper commented on GitHub (May 12, 2025):

Thanks for fast help.

@siper commented on GitHub (May 12, 2025): Thanks for fast help.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/godoxy#71