How to deploy a internal used api document - OAuth2 protected swagger UI

Now our company is to develop app. We need a internal API document platform help us corlaboration. After searching online, I found that most of open source API document project do not support auth. So I learned how to use OAuth2 Proxy protect our Swagger UI. In this toturial, I will use self managed Gitea as OAuth2 provider.

Install Swagger UI with OAuth2 protection

Log into your server as root.

1
2
3
mkdir swagger
cd swagger
vim docker-compose.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
services:
# OAuth2 Proxy service for Gitea authentication
oauth2-proxy:
image: quay.io/oauth2-proxy/oauth2-proxy:latest
container_name: oauth2-proxy
command:
- --http-address=0.0.0.0:4180
- --upstream=http://swagger:8080
- --email-domain=*
- --cookie-secure=true # Set to true in production with HTTPS
- --cookie-secret=${COOKIE_SECRET}
- --client-id=${CLIENT_ID}
- --client-secret=${CLIENT_SECRET}
- --provider=github
- --redirect-url=https://docs.rui.ke/oauth2/callback
- --provider-display-name=Gitea
- --login-url=https://gitea.example.com/login/oauth/authorize
- --redeem-url=https://gitea.example.com/login/oauth/access_token
- --validate-url=https://gitea.example.com/api/v1/user/emails
- --custom-templates-dir=/templates
environment:
- OAUTH2_PROXY_CLIENT_ID=${CLIENT_ID}
- OAUTH2_PROXY_CLIENT_SECRET=${CLIENT_SECRET}
- OAUTH2_PROXY_COOKIE_SECRET=${COOKIE_SECRET}
volumes:
- ./templates:/templates:ro
ports:
- "127.0.0.1:1688:4180"
depends_on:
- swagger
networks:
- swagger-net
restart: unless-stopped

# Swagger UI service
swagger:
image: swaggerapi/swagger-ui:latest
container_name: swagger-ui
environment:
- SWAGGER_JSON=/spec/openapi.yaml # Path to your OpenAPI spec
- BASE_URL=/
- PORT=8080
- VALIDATOR_URL=
volumes:
- /srv/swagger/spec:/spec:ro # Mount your OpenAPI spec file
expose:
- "8080"
networks:
- swagger-net
restart: unless-stopped

networks:
swagger-net:
driver: bridge
1
vim .env
1
2
3
CLIENT_ID=your_client_id # get this from your gitea application
CLIENT_SECRET=your_client_secret # get this from your gitea application
COOKIE_SECRET=a_random_string
1
docker compose up -d
1
vim /etc/nginx/sites-available/docs.example.com
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Serve docs.example.com, handle ACME challenges, and proxy to Swagger UI (IPv4 + IPv6)
server {
server_name docs.example.com;

# === Let’s Encrypt HTTP-01 challenge location ===
location ^~ /.well-known/acme-challenge/ {
root /var/lib/letsencrypt;
default_type "text/plain";
access_log off;
}

location / {
proxy_pass http://127.0.0.1:1688;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_send_timeout 90;
}

listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/docs.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/docs.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}


server {
if ($host = docs.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot


listen 80;
listen [::]:80;
server_name docs.example.com;
return 404; # managed by Certbot


}
1
2
3
ln -s /etc/nginx/sites-available/docs.example.com /etc/nginx/sites-enabled
certbot --nginx -d docs.example.com
service nginx restart

Gitea CI-CD configure

1
2
# go to your repo
vim .gitea/workflows/ci-cd.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
name: Sync OpenAPI to Swagger

on:
push:
branches:
- main

env:
REPO_URL: git@gitea.example.com:user/repo.git
CLONED_REPO_DIR: /home/git/repo
DEPLOYED_DIR: /srv/swagger/spec

jobs:
sync-openapi:
name: Sync OpenAPI to Swagger
runs-on: linux_amd64

steps:
- name: Pull
run: |
cd $CLONED_REPO_DIR
git pull origin main

- name: Copy OpenAPI spec
run: |
cd $CLONED_REPO_DIR
cp docs/openapi.yaml $DEPLOYED_DIR/openapi.yaml

Install Swagger editor

1
2
3
mkdir swagger-editor
cd swagger-editor
vim docker-compose.yaml
1
2
3
4
5
6
7
services:
swagger-editor:
image: docker.swagger.io/swaggerapi/swagger-editor:latest
container_name: swagger-editor
ports:
- "127.0.0.1:1689:8080" # map host port 80 → container port 8080
restart: unless-stopped
1
vim /etc/nginx/sites-available/editor.example.com
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 1) Redirect all HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name editor.example.com;

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

# 2) Main HTTPS server block
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name editor.example.com;

# SSL certs managed by Certbot
ssl_certificate /etc/letsencrypt/live/editor.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/editor.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

# Reverse-proxy to your Docker-Compose Swagger Editor
location / {
proxy_pass http://127.0.0.1:1689;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

1
2
3
ln -s /etc/nginx/sites-available/editor.example.com /etc/nginx/sites-enabled
certbot --nginx -d editor.example.com
service nginx restart

Reference

  1. https://github.com/swagger-api/swagger-editor
  2. https://github.com/oauth2-proxy/oauth2-proxy/blob/master/contrib/local-environment/docker-compose.yaml
  3. https://oauth2-proxy.github.io/oauth2-proxy/configuration/providers/gitea/