It definitely works for self-hosted Ghost. I’m doing it. (Although with ghost-cli and NginX and cloudflare, not Docker & Traefik.)
Not all .well-known traffic goes to ap. ghost.org - you may want to look at the official ghost-cli or docker repo for working examples that could be translated to traefik.
Well got it working.Solution was to split some stuff and set traefik Labels within the docker-compose. This was the key in the end. Not sure why but rules were not working within treafik.yml so I put them in the compose file.
within traefik folder I set up a ruleset for activitypub to keep traefik lean.
# Optional: If you want to enable ActivityPub Service using Traefik v3 HelmChart
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
annotations:
kubernetes.io/ingress.class: traefik
name: ghost-on-kubernetes-ingressroute
namespace: ghost-on-kubernetes
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: Host(`yourdomain.tld`) && (PathPrefix(`/.ghost/activitypub/`) || Path(`/.well-known/webfinger`) || Path(`/.well-known/nodeinfo`) )
services:
- kind: TraefikService
name: ghost-activitypub@file
serversTransport: ap-transport@file
Traefik values:
# Traefik v3 Helm Chart values needed for this implementation
# More info on https://github.com/traefik/traefik-helm-chart
# Important note: You might need to manually install Traefik's CRD, please refer to their docs for more info.
providers:
file:
enabled: true
watch: true
content: |
http:
services:
ghost-activitypub:
loadBalancer:
passHostHeader: true
serversTransport: ap-transport
servers:
- url: "https://ap.ghost.org"
serversTransports:
ap-transport:
serverName: "ap.ghost.org"
insecureSkipVerify: true
disableHTTP2: true
maxIdleConnsPerHost: 1
forwardingTimeouts:
dialTimeout: 42s
responseHeaderTimeout: 42s
idleConnTimeout: 42s
kubernetesCRD:
# -- Load Kubernetes IngressRoute provider
enabled: true
# -- Allows IngressRoute to reference resources in namespace other than theirs
allowCrossNamespace: true
# -- Allows to reference ExternalName services in IngressRoute
allowExternalNameServices: true
# -- Allows to return 503 when there are no endpoints available
allowEmptyServices: true
# -- When the parameter is set, only resources containing an annotation with the same value are processed. Otherwise, resources missing the annotation, having an empty value, or the value traefik are processed. It will also set required annotation on Dashboard and Healthcheck IngressRoute when enabled.
ingressClass: ""
# -- See [upstream documentation](https://doc.traefik.io/traefik/reference/install-configuration/providers/kubernetes/kubernetes-ingress/#opt-providers-kubernetesIngress-labelselector)
labelSelector: ""
# -- Array of namespaces to watch. If left empty, Traefik watches all namespaces. . When using `rbac.namespaced`, it will watch helm release namespace and namespaces listed in this array.
namespaces: []
# -- Defines whether to use Native Kubernetes load-balancing mode by default.
nativeLBByDefault: false
kubernetesIngress:
# -- Load Kubernetes Ingress provider
enabled: true
# -- Allows to reference ExternalName services in Ingress
allowExternalNameServices: true
# -- Allows to return 503 when there are no endpoints available
allowEmptyServices: true
# -- Only for Traefik v3.0, Deprecated since v3.1. See [upstream documentation](https://doc.traefik.io/traefik/v3.0/providers/kubernetes-ingress/#disableingressclasslookup)
disableIngressClassLookup: false
# -- When ingressClass is set, only Ingresses containing an annotation with the same value are processed. Otherwise, Ingresses missing the annotation, having an empty value, or the value traefik are processed.
ingressClass: # @schema type:[string, null]
traefik
labelSelector: # @schema type:[string, null]
# -- Array of namespaces to watch. If left empty, Traefik watches all namespaces. . When using `rbac.namespaced`, it will watch helm release namespace and namespaces listed in this array.
namespaces: []
# IP used for Kubernetes Ingress endpoints
publishedService:
# -- Enable [publishedService](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#publishedservice),
# usually with the Service provided by this Chart. It's possible to use it with an external Service using pathOverride.
enabled: true
# -- Override path of Kubernetes Service used to copy status from. Format: namespace/servicename.
# Default to Service deployed with this Chart.
pathOverride: ""
# -- Defines whether to use Native Kubernetes load-balancing mode by default.
nativeLBByDefault: false
# -- Defines whether to make prefix matching strictly comply with the Kubernetes Ingress specification.
strictPrefixMatching: false