skip to Main Content

I’m having trouble configuring nginx for subdomains.
My goal is eventually to have:

- example.com
- swagger.example.com
- api.example.com

I’m currently having problems with swagger.example.com.
My backend is written in FastAPI and I want swagger from localhost:8000/docs to be available on that domain.
But all I get is Failed to load API definition.
Somehow api.example.com/docs is working perfectly fine, though I haven’t configured it in nginx yet.

user nginx;
worker_processes 4;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    server {
        listen 80;
        listen [::]:80;
        server_name .example.com;

        return 301 https://$server_name$request_uri;
    }

    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name triptip.pro;
        server_tokens off;

        ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

        location / {
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-NginX-Proxy true;
            proxy_pass http://example_service:8000;
            proxy_ssl_session_reuse off;
            proxy_set_header Host $http_host;
            proxy_cache_bypass $http_upgrade;
            proxy_redirect off;
        }
    }

    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name swagger.example.com;

        ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

        location / {
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-NginX-Proxy true;
            proxy_pass http://example_service:8000/docs;
            proxy_ssl_session_reuse off;
            proxy_set_header Host $http_host;
            proxy_cache_bypass $http_upgrade;
            proxy_redirect off;
        }
    }
}

What am I missing?

2

Answers


  1. Chosen as BEST ANSWER

    I've made a temporal solution, which redirects to working swagger when I request swagger.example.com

        server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name swagger.example.pro;
    
        ssl_certificate /etc/letsencrypt/live/api.example.pro/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/api.example.pro/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
        
        location = / {
            return 301 https://$host/docs;
        }
    
        location / {
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-NginX-Proxy true;
            proxy_pass http://example_service:8000;
            proxy_ssl_session_reuse off;
            proxy_set_header Host $http_host;
            proxy_cache_bypass $http_upgrade;
            proxy_redirect off;
        }
    }
    

    But if I try to block other endpoints with return 404, or change "location /" in some way, swagger error reappears because of missing openapi.json.

    @MatsLindh gave me a correct hint about source of a problem, but I don't want to change internal link here.


  2. The swagger endpoint expects to load the openapi specification from /openapi.json – since you’ve mounted the sub path directly on /, there is no openapi.json present at root any longer.

    You can change where FastAPI exposes the openapi specification by giving the openapi_url parameter when creating the FastAPI instance:

    FastAPI(openapi_url="/docs/openapi.json")
    

    However, this means that the /docs endpoint might try to load it from /docs under the docs itself, so you might have to define the url to use manually.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search