13
votes

The Readme on https://github.com/swagger-api/swagger-ui specifies that Swagger-UI can be run with your own file like this

docker run -p 80:8080 -e SWAGGER_JSON=/foo/swagger.json -v /bar:/foo swaggerapi/swagger-ui

which works I if I translate it to

docker build . -t swagger-ui-local && \
  docker run -p 80:8080 -e SWAGGER_JSON=/foo/my-file.json -v $PWD:/foo swagger-ui-local

This, however, ignores my local changes.

I can run my local changes with

npm run dev

but I can't figure out how to get this dev server to run anything else than the Petstore example.

Can anyone help me combine the two, so I can run swagger-ui with local code changes AND my own swagger.json?

8

8 Answers

14
votes

Make sure you are volume mounting the correct local directory.

Locally, I had my swagger config in $PWD/src/app/swagger/swagger.yaml. Running the following worked fine:

docker run -p 80:8080 -e SWAGGER_JSON=/tmp/swagger.yaml -v `pwd`/src/app/swagger:/tmp swaggerapi/swagger-ui

Simply refreshing the Swagger-UI page or clicking the "Explore" button in the header triggered a refresh of the data from my YAML file.

You can also specify BASE_URL excerpt from swagger-installation

docker run -p 80:8080 -e BASE_URL=/swagger -e SWAGGER_JSON=/foo/swagger.json -v /bar:/foo swaggerapi/swagger-ui

9
votes

Here's how I ended up solving this, it also allows you to have multiple YML files:

docker run -p 80:8080 \                                                                                                                                 
  -e URLS_PRIMARY_NAME=FIRST \                                                                                                                             
  -e URLS="[ \                                                                                                                                           
    { url: 'docs/first.yml', name: 'FIRST' } \                                                                                                               
    , { url: 'docs/second.yml', name: 'SECOND' } \                                                                                                             
  ]" \                                                                                                                                                   
  -v `pwd`:/usr/share/nginx/html/docs/ \                                                                                                                 
  swaggerapi/swagger-ui   
8
votes

I found this topic because I wanted to see a visual representation of my local swagger file, but could not seem to get swagger-ui (running in docker) to display anything other than the petstore.

Ultimately, my issue was with understanding the -e SWAGGER_JSON and -v flags, so I wanted to explain them here.

-v <path1>:<path2>

This option says "Mount the path <path1> from my local file system within the swagger-ui docker container on path <path2>"

-e SWAGGER_JSON=<filepath>

This option says "By default, show the swagger for the file at <filepath> using the docker container's file system." The important part here, is that this filepath should take into account how you set <path2> above

Putting it all together, I ended up with the following:

docker run -p 8085:8080 -e SWAGGER_JSON=/foo/swagger.json -v `pwd`:/foo swaggerapi/swagger-ui

This says in english: "Run my swagger-ui instance on port 8085. Mount my current working directory as '/foo' in the docker container. By default, show the swagger file at '/foo/swagger.json'."

The important thing to note is that I have a file called swagger.json in my current working directory. This command mounts my current working directory as /foo in the docker container. Then, swagger UI can pick up my swagger.json as /foo/swagger.json.

5
votes

I figured it out for npm run dev:

Place my-file.json in the dev-helpers folder. Then it's available from the search bar in on http://localhost:3200/.

To load it automatically when opening the server, alter dev-helpers/index.html by changing

url: "http://petstore.swagger.io/v2/swagger.json"

to

url: "my-file.json"
1
votes

Just in case you are running a maven project with Play Framework the following steps solved my issue :

1.) Alter the conf/routes file. Add the below line : GET /swagger.json controllers.Assets.at(path="/public/swagger-ui",file="swagger.json")

2.) Add the swagger.json file to your Swagger-UI folder

so when you run the mvn project in a port example 7777, start the play server using mvn play2:run and then, localhost:7777/docs will automatically pull the Json file that is added locally.

1
votes

Docker compose solution:

create .env file and add the following:

URLS_PRIMARY_NAME=FIRST
URLS=[ { url: 'docs/swagger.yaml', name: 'FIRST' } ]

And create a docker-compose file with contents below:

version: "3.3"

services:
 swagger-ui:
  image: swaggerapi/swagger-ui
  container_name: "swagger-ui"
  ports:
    - "80:8080"
  volumes:
   - /local/tmp:/usr/share/nginx/html/docs/
  environment:
    - URLS_PRIMARY_NAME=${URLS_PRIMARY_NAME}
    - URLS=${URLS}

the swagger.yaml is at /local/tmp.

0
votes

For people facing this issue in mac, its a permission problem. By default after Catalina, docker doesn't have permission to allow its images to read local files in your system. Once its given it worked for me and it took my local swagger json file.

To grant privileges now, go to System preferences > Security & Privacy > Files and Folders, and add Docker for Mac and your shared directory. enter image description here

0
votes

Another solution if you want to provide multiple URLs and from a specific folder (not default /usr/share/nginx/html/docs/):

docker run -p 80:8080 \
    -e SWAGGER_JSON=/docs/api.yaml \
    -e URLS="[ \
        { url: '/api1.yaml', name: 'API 1' }, \
        { url: '/api2.yaml', name: 'API 2' } \
    ]" \
    -v `pwd`/docs:/docs \
    swaggerapi/swagger-ui

Or for docker compose:

version: '3.8'
services:
  swagger-ui:
    image: swaggerapi/swagger-ui
    volumes:
      - ./docs:/docs
    environment:
      SWAGGER_JSON: /docs/api.yaml
      URLS: '[{ url: "/api1.yaml", name: "API 1" }, { url: "/api2.yaml", name: "API 2" }]'

Please note, SWAGGER_JSON requires an absolute path, URLs in URLS require relative paths from the specified volume