Doesn't read swagger.json from SWAGGER_JSON path in docker. Copied everything to that folder
Hi @azamatsulaiman !
I think issue is that doc shows wrong example.
Or you can provide your own swagger.json on your host
docker run -p 80:8080 -e "SWAGGER_JSON=/foo/swagger.json" -v /bar:/foo swaggerapi/swagger-ui
In case if use
"SWAGGER_JSON=/foo/swagger.json" as parameter it will not be recognized as kwarg. It should be
docker run -p 80:8080 -e SWAGGER_JSON=/foo/swagger.json -v /bar:/foo swaggerapi/swagger-ui
I guess doc should be updated
I tried this work around already but still have same issue @wolendranh
Make sure your path names are correct. I struggled with this issue for an hour before reading the docker-run and seeing what SWAGGER_JSON should have been doing and finding this issue page.
Interesting. Which OS are you on? Just tested both variants (with and without quotes) and they both worked for me.
@webron CentOS 7 - have that issue
@webron Ubuntu 16 -- with quotes was not picking up the env variable correctly
Could you share your docker version? And the exact command you're using? And for completeness, your shell/version ( ie: bash/zsh/fish?).
-e one=two should be identical to -e "one=two" as I believe bash/zsh will remove those.
More importantly, the path your provide should be mounted as a volume, ie: -v /local/path:/foo. foo is arbitrary, and needs to match what you put in SWAGGER_PATH=/foo/...
This command works for me... ( LinuxMint 18)
docker run -p 80:8080 -e SWAGGER_JSON=/foo/petstore.yaml -v /home/josh/:/foo swaggerapi/swagger-ui
# as well as..
docker run -p 80:8080 -e "SWAGGER_JSON=/foo/petstore.yaml" -v /home/josh/:/foo swaggerapi/swagger-ui
# FYI
â–¶ docker version
Client:
Version: 1.12.6
API version: 1.24
Go version: go1.6.4
Git commit: 78d1802
Built: Tue Jan 10 20:38:45 2017
OS/Arch: linux/amd64
Server:
Version: 1.12.6
API version: 1.24
Go version: go1.6.4
Git commit: 78d1802
Built: Tue Jan 10 20:38:45 2017
OS/Arch: linux/amd64
And also make sure you have the latest docker image...
docker pull swaggerapi/swagger-ui
I definitely have the latest docker image (I actually tried 4 other older tags as well in case there was a docker-run bug introduced at some point).
$ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
$ sudo docker version
Client:
Version: 1.11.0-rc5
API version: 1.23
Go version: go1.5.3
Git commit: 6178547
Built: Mon Apr 11 21:16:15 2016
OS/Arch: linux/amd64
Server:
Version: 1.11.0-rc5
API version: 1.23
Go version: go1.5.3
Git commit: 6178547
Built: Mon Apr 11 21:16:15 2016
OS/Arch: linux/amd64
After retrying today I get it work with and without quotes -- but its the identical command I used yesterday when it kept loading http://petstore.swagger.io/v2/swagger.json default page instead. I'm sure what environment setup changed between yesterday and today :/
@MSeal - thanks. I don't mind at all merging your PR, just trying to figure out why it sometimes works and sometimes doesn't. 'magic' is not good enough of a reason ;)
While testing the command, it did take me a few times to get it working, but that's because I had no idea what I was doing with mounting the file system and pointing it to the right place.
Yeah, I think the tricky part is the --volume | -v flag for mounting the directory.
docker will _NOT_ have access to your file system, so you need to mount volumes on to it. We do so with -v ( there is a newer syntax, but its just a more general one, called --mount)
We can enforce a convention, ie remove the need for SWAGGER_JSON env, and just advise users to mount to -v /home/josh/swagger-specs/:/specs where /specs is searched for swagger.yaml | swagger.json file in the docker container. The idea is to force a convention - for simplicity.
+1
I've been searching everywhere for this. In my opinion it would be super convenient to enforce such a convention to enable auto-loading of specs. Would be great if we could suffice with just a docker-compose.yml like so:
version: "2"
services:
swagger_ui:
environment:
- SWAGGER_JSON=./swagger.json
image: "swaggerapi/swagger-ui"
volumes: ["./swagger.json:/usr/share/nginx/html/swagger.json"]
restart: always
ports: ["9000:8080"]
By the way, would be great to also have auto-loading of specs in the editor.
I'm ok with having a default for as a convention, but we should still allow users to have the ability to manually point to a specific file.
yeah I agree @webron
@MidnightP you can have a docker-compose file like that today.... just need to tweak it....
# docker-compose.yaml
version: "2"
services:
swagger_ui:
environment:
- SWAGGER_JSON=/swagger.json
image: "swaggerapi/swagger-ui"
volumes: ["/usr/share/nginx/html/swagger.json:/swagger.json"]
restart: always
ports: ["9000:8080"]
tested that with...
docker-compose --version
# docker-compose version 1.8.0, build unknown
docker-compose -f ./docker-compose.yaml up
@ponelat Thanks!
Now I receive "Failed to load spec." on initial load... Can the ui read from the root?
version: "2"
services:
swagger_ui:
environment:
- SWAGGER_JSON=/swagger.json
image: "swaggerapi/swagger-ui"
volumes: ["./swagger.json:/swagger.json"]
restart: always
ports: ["9000:8080"]
docker-compose --version
docker-compose version 1.10.0, build 4bd6f1a
@MidnightP yeah it can read from root.
If it can't find the file, it'll show the default petstore.
So it might be the spec.
The above looks fine, you can inspect your mount points if you like...
docker ps # To get the container ID
docker inspect --format '{{.Mounts}}' <docker-container-id>
And also stick your spec into editor.swagger.io to see if there are any validation issues.
Happy hunting :)
This works for me:
version: "2"
services:
swagger_ui:
environment:
- API_URL=/swagger.json
image: "swaggerapi/swagger-ui"
volumes: ["./swagger.json:/usr/share/nginx/html/swagger.json"]
restart: always
ports: ["9000:8080"]
My issue was actually related to docker volumes not functioning properly in windows subsystem linux, it works fine otherwise
Any suggestions on what to change in the docs, or if the PR should be closed? Seems like most of the issues have been more volume based than quote based once investigated.
Perhaps we just add a primer on docker volumes..
Docker containers are isolated from their hosts in many ways. Including the filesystem.
In order to get your swagger spec inside the docker container, we need to _mount_ or _bind_ it.
docker has the -v or --volume flag to do this. It takes a single argument of the form... -v /laptop-dir/or-file:/docker-dir/or-file:permission-flags. Where the file/dir you want to mount comes first, followed by a colon : and the file/dir that'll be exposed inside the docker container. You can optionally provide permission flags. For example: -v /home/josh/foo.txt:/foo.txt:ro will mount the file in my home directory called foo.txt. The docker container can read this file from /foo.txt, but cannot write to it ( because of the ro flags, read-only).
For our purposes the swagger file can be anywhere on your host, and we typically mount it to /swagger.json on the docker container.
We can make it simpler. Ping @webron @shockey
Not sure this is an issue. The specification file via SWAGGER_JSON is mounted inside the container on boot. Therefore you need to provide the volume like this:
docker run -d -p 1337:8080 -e "SWAGGER_JSON=/spec/swagger.json" -v /Projects/cool-api/spec:/spec swaggerapi/swagger-ui
I guess there's room for improvement. In terms of developer experience, it would be better to be able to sync the specification file via a shared volume, instead of only via the container boot. Thoughts?
My suggestion:
# docker-compose.yaml
version: "2"
services:
swagger_ui:
environment:
- SWAGGER_JSON=other-swagger.json
image: "swaggerapi/swagger-ui"
volumes: ["/Projects/cool-api/spec:/spec"]
restart: always
ports: ["1337:8080"]
This way we pass the full spec contents to the container. This allows people to also make use of the $ref. Currently, we only support one root file (if I'm correct). So we only sync 1 file, which causes problems for people using $ref to other spec files, because they are not present in the container.
This way the SWAGGER_JSON is just the identifier for the "root file". We can default this to swagger.json.
So in the example above the /spec/other-swagger.json file would be used to generate the docs.
@guidsen yeah, that's a good idea.
We could easily allow mounting a dir. Ultimately there is a little nginx server in there, which serves up the files. The only issue I can see is, is that they share that server space with the static assets. So you can't have a spec called index.html :grin:
Is there a case where someone would call their spec index.html LOL.
@ponelat If you want I can work on this, this week and create a PR, based on the suggestion I gave. I guess it will really improve the developer experience.
I'd be happy with that. @shockey ?
Sounds good to me!
Volume is taking forever to mount at run time for me so I made a quick Dockerfile that copies the files in there and takes care of the SWAGGER_JSON environment variable, here it is in case someone have a similar issue for whatever reason:
FROM swaggerapi/swagger-ui
EXPOSE 8080
COPY swagger_file.yaml /docs/swagger_file.yaml
ENV SWAGGER_JSON "/docs/swagger_file.yaml"
CMD ["sh", "/usr/share/nginx/docker-run.sh"]
And then to build and run you just need to do:
docker build . -t company/docs
docker run -p 8080:8080 -d company/docs
Not the best way to solve it but at least it works and it's quick.
@faresbessrour How about if i want to mount app/swagger/swagger_file.yaml to /docs/swagger_file.yaml?. Because i would like to sync file from host to docker container while i editing swagger file.
I'm using docker-compose
Absolutely @minhloc2011 instead of using a Dockerfile you can use a docker-compose config like this one:
version: '3'
services:
swagger:
image: swaggerapi/swagger-ui
ports:
- 8080:8080
volumes:
- ./app/swagger/swagger_file.yaml:/docs/swagger_file.yaml
environment:
- SWAGGER_JSON="/docs/swagger_file.yaml"
What you do here is you mount your host file located in ./app/swagger/swagger_file.yaml to the /docs/swagger_file.yaml file in the container and then give it as an environment virable in SWAGGER_JSON
Mind you I didn't test this file but it should look very similar to what I have, please tag me if there is any correction to make on it!
Hope this helps.
@faresbessrour thank for reply, i got it!
The root cause of this problem is the permission issue of nginx. This soft link file does not have access to the final directory. Need to change the mounted host directory to readable.
eg:
docker run --name=ui -p 1080:8080 --privileged -e SWAGGER_JSON=/foo/swagger.json -v /root:/foo -d swaggerapi/swagger-ui
chmod 755 -R /root
I have a swagger.json on my desktop, so running this command worked:
docker run -p 9000:8080 -e SWAGGER_JSON=/mnt/swagger.json -v ~/Desktop:/mnt swaggerapi/swagger-ui
localhost:9000 is loading correct file.
After an embarrassingly long time, I realized my browser was caching. Ctrl-F5 and I was seeing my swagger.json instead of the default.
Most helpful comment
This works for me: