Introduction
When configuring JFrog Artifactory with Docker subdomain access using Kubernetes Ingress, the approach relies on regex-based host matching via the nginx.ingress.kubernetes.io/server-alias annotation.
However, starting with NGINX Ingress Controller v1.12.0, the controller enforces stricter annotation validation rules. This change causes the regex pattern in the server-alias annotation to be rejected, preventing ingress creation or synchronization.
Symptoms
When deploying Artifactory using Helm with the following Ingress configuration:
ingress:
enabled: true
className: "nginx"
hosts:
- "artifactory.support-testlab.com"
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-read-timeout: "2400"
nginx.ingress.kubernetes.io/proxy-send-timeout: "2400"
nginx.ingress.kubernetes.io/server-alias: ~(?<repo>.+)\.artifactory.support-testlab.com
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite ^/(v1|v2)/(.*) /artifactory/api/docker/$repo/$1/$2 break;
rewrite ^/(v1|v2)/ /artifactory/api/docker/$1/; The Ingress Controller logs show errors such as
-
admission webhook "validate.nginx.ingress.kubernetes.io" denied the request:annotation nginx.ingress.kubernetes.io/server-alias contains invalid value
-
W0805 09:00:18.820054 7 validators.go:243] validation error on ingress artifactory/artifactory:annotation server-alias contains invalid value ~(?<repo>.+)\.artifactory.support-testlab.com
Cause of the Issue
Beginning with NGINX Ingress Controller v1.12.0, regex-based values in the server-alias annotation are no longer accepted due to stricter validation checks introduced in the admission webhook (validate.nginx.ingress.kubernetes.io).
The older pattern:
nginx.ingress.kubernetes.io/server-alias: ~(?<repo>.+)\.artifactory.example.com is considered invalid syntax by the new controller validation logic.
Impact
-
Deployments using NGINX Ingress Controller v1.12.0 and later fail to apply the Ingress resource.
-
Regex-based subdomain matching for Docker repositories no longer works.
Affected setups cannot use Docker subdomain routing
Resolution
Use server-snippet Instead of server-alias:
The server-snippet annotation can replicate the same behavior without relying on server-alias. This approach works with NGINX Ingress Controller v1.12+.
Example Ingress Values:
ingress:
enabled: true
defaultBackend:
enabled: true
hosts:
- "artifactory.support-testlab.com"
routerPath: /
artifactoryPath: /artifactory/
className: "nginx"
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-read-timeout: "2400s"
nginx.ingress.kubernetes.io/proxy-send-timeout: "2400s"
nginx.ingress.kubernetes.io/server-snippet: |
server_name ~^(?<repo>.+)\.artifactory\.support-testlab\.com$;
if ($repo = "") {
set $repo "docker";
}
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite ^/(v1|v2)/(.*) /artifactory/api/docker/$repo/$1/$2 break;
rewrite ^/(v1|v2)/ /artifactory/api/docker/$1/; Ingress Controller ConfigMap:
Ensure following configurations is set in the NGINX Ingress Controller ConfigMap:
apiVersion: v1
kind: ConfigMap
data:
allow-snippet-annotations: "true"
annotations-risk-level: Critical
use-forwarded-headers: "true"
This setting allows the use of server-snippet safely.
Verification of Docker Subdomain Method:
After applying the new configuration verifying docker pull using docker subdomain method:
docker pull / push <REPOSITORY_KEY>.artifactory.support-testlab.com/<IMAGE>:<TAG>
docker login -u <USER_NAME> -p <USER_PASSWORD> <REPOSITORY_KEY>.artifactory.support-testlab.com
Example:
docker login jfrog-docker-remote.artifactory.support-testlab.com
docker pull jfrog-docker-remote.artifactory.support-testlab.com/busybox:latest
Expected Output:
Login Succeeded
latest: Pulling from busybox
Digest: sha256:2f590fc602ce325cbff2ccfc39499014d039546dc400ef8bbf5c6ffb860632e7
Status: Downloaded newer image for jfrog-docker-remote.artifactory.support-testlab.com/busybox:latest
References