<p>I have a node.js API run inside a Docker container on Kubernetes cluster within a pod.
The pod is connected to Kubernetes service of type LoadBalancer, so I can connect to it from outside, and also from the Swagger UI, by passing to the Swagger UI which is run as another Docker container on the same Kubernetes cluster an API IP address <code>http://&lt;API IP address&gt;:&lt;port&gt;/swagger.json.</code></p>
<p>But in my case I would like to call the API endpoints via Swagger UI using the service name like this <code>api-service.default:&lt;port&gt;/swagger.json</code> instead of using an external API IP address.</p>
<p>For Swagger UI I' am using the latest version of swaggerapi/swagger-ui docker image from here: <a href="https://hub.docker.com/r/swaggerapi/swagger-ui" rel="nofollow noreferrer">https://hub.docker.com/r/swaggerapi/swagger-ui</a></p>
<p>If I try to assign the <code>api-service.default:&lt;port&gt;/swagger.json</code> to Swagger-UI container environment variable then the Swagger UI result is: <strong>Failed with load API definition</strong></p>
<p><img src="https://i.stack.imgur.com/3jBD0.jpg" alt="swagger.screenshot" /></p>
<p>Which I guess is obvious because the browser does not recognize the internal cluster service name.</p>
<p>Is there any way to communicate Swagger UI and API in Kubernetes cluster using service names?</p>
<p><strong>--- Additional notes ---</strong></p>
<p>The Swagger UI CORS error is misleading in that case. I am using this API from many other services.</p>
<p><img src="https://i.stack.imgur.com/X8gyr.jpg" alt="enter image description here" /></p>
<p>I have also tested the API CORS using cURL.</p>
<p><img src="https://i.stack.imgur.com/lc4dI.jpg" alt="enter image description here" /></p>
<p>I assume that swagger-ui container inside a pod can resolve that internal cluster service name, but the browser cannot because the browser works out of my Kubernetes cluster.</p>
<p>On my other web services running in the browser (out of my cluster) served on nginx which also consumes this API, I use the nginx reverse proxy mechanizm.</p>
<p><a href="https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/" rel="nofollow noreferrer">https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/</a></p>
<p>This mechanizm redirects my API request invoked from the browser level to the internal cluster service name: <code>api-service.default:8080</code> where the nginx server is actually running. I mean the nginx is runnig on the cluster, browser not.</p>
<p>Unfortunately, I dont't how to achive this in that swagger ui case.</p>
<p>Swagger mainfest file:</p>
<pre><code># SERVICE
apiVersion: v1
kind: Service
metadata:
  name: swagger-service
  labels:
    kind: swagger-service
spec:
  selector:
    tier: api-documentation
  ports:
    - protocol: 'TCP'
      port: 80
      targetPort: 8080
  type: LoadBalancer
---
# DEPLOYMENT
apiVersion: apps/v1
kind: Deployment
metadata:
  name: swagger-deployment
  labels:
    kind: swagger-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      tier: api-documentation
  template:
    metadata:
      labels:
        tier: api-documentation
    spec:
      containers:
        - name: swagger
          image: swaggerapi/swagger-ui
          imagePullPolicy: Always
          env:
            - name: URL
              value: 'http://api-service.default:8080/swagger.json'
</code></pre>
<p>API manifest file:</p>
<pre><code># SERVICE
apiVersion: v1
kind: Service
metadata:
  name: api-service
  labels:
    kind: api-service
spec:
  selector:
    tier: backend
  ports:
    - protocol: 'TCP'
      port: 8080
      targetPort: 8080
  type: LoadBalancer
---
# DEPLOYMENT
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
  labels:
    kind: api-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      tier: backend
  template:
    metadata:
      labels:
        tier: backend
    spec:
      containers:
        - name: api
          image: &lt;my-api-image&gt;:latest
</code></pre>

<p>I solved it by adding nginx reverse proxy to /etc/nginx/nginx.conf file in swagger UI container which redirects all requests ended with /swagger.json to the API service.</p>
<p>After this file changes you need to reload the nginx server: <code>nginx -s reload</code></p>
<pre><code>server {
    listen            8080;
    server_name       localhost;
    index             index.html index.htm;
    
    location /swagger.json {
      proxy_pass http://api-service.default:8080/swagger.json;
    }

    location / {
      absolute_redirect off;
      alias            /usr/share/nginx/html/;
      expires 1d;

      location ~* \.(?:json|yml|yaml)$ {
        #SWAGGER_ROOT
        expires -1;

        include cors.conf;
      }

      include cors.conf;
    }
</code></pre>
<p><strong>Important</strong> is to assign only <code>/swagger.json</code> to ENV of the SwaggerUI continer. It is mandatory because requests must be routed to nginx in order to be resolved.</p>
<p>Swagger manifest</p>
<pre><code># SERVICE
apiVersion: v1
kind: Service
metadata:
  name: swagger-service
  labels:
    kind: swagger-service
spec:
  selector:
    tier: api-documentation
  ports:
    - protocol: 'TCP'
      port: 80
      targetPort: 8080
  type: LoadBalancer
---
# DEPLOYMENT
apiVersion: apps/v1
kind: Deployment
metadata:
  name: swagger-deployment
  labels:
    kind: swagger-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      tier: api-documentation
  template:
    metadata:
      labels:
        tier: api-documentation
    spec:
      containers:
        - name: swagger
          image: swaggerapi/swagger-ui
          imagePullPolicy: Always
          env:
            - name: URL
              value: '/swagger.json'
</code></pre>
