The official redocly/redoc image is nginx serving one page with the Redoc bundle already in it.
No build step, no npm, no files of your own — you point it at an API description with an
environment variable and it serves the docs.
This example is a README rather than a project: the image is the deliverable, so there is nothing to copy. It is also one of two examples CI does not smoke-test — the image carries its own bundle and has no hook to swap it, so a test here would exercise the published image instead of this checkout (see ../README.md).
Serve a remote API description:
docker run --rm -p 8080:80 \
-e SPEC_URL='https://cdn.jsdelivr.net/gh/Redocly/redoc@1f67fe5ae769910c1144d76ac0786bcb5499d712/demo/cafe.yaml' \
redocly/redocOpen http://localhost:8080. That URL is the same Cafe API every other example renders.
Serve a file from your machine — mount it into the web root, then name it relative to that root:
docker run --rm -p 8080:80 \
-v "$(pwd)/openapi.yaml:/usr/share/nginx/html/openapi.yaml" \
-e SPEC_URL=openapi.yaml \
redocly/redocMount a whole directory when your description is split across $refed files. Edits show up on
reload, so this doubles as a preview loop:
docker run --rm -p 8080:80 \
-v "$(pwd)/specs:/usr/share/nginx/html/specs" \
-e SPEC_URL=specs/openapi.yaml \
redocly/redocAsyncAPI and GraphQL work the same way — Redoc detects the type from the document:
docker run --rm -p 8080:80 \
-e SPEC_URL='https://example.com/asyncapi.yaml' \
redocly/redocA remote SPEC_URL must be served with CORS, since the browser fetches it, not nginx. For a
local file the mount above avoids the problem entirely; to serve one from your host instead:
npx http-server . --cors -p 8000Pin a version with a tag (redocly/redoc:<version>) for anything you deploy — latest moves.
Every option is an environment variable. config/docker/README.md in this repository is the
canonical reference; these are the ones you need to run it:
REDOC_OPTIONS is where anything Redoc-specific goes, verbatim as tag attributes:
docker run --rm -p 8080:80 \
-e SPEC_URL=openapi.yaml \
-e REDOC_OPTIONS='router="history"' \
redocly/redocTwo notes on the ones that trip people up:
BASE_PATH— routing is hash-based by default, so deep links need nothing special. They also surviverouter="history": the image's nginx servesindex.htmlfor any path that is not a file, and under a prefix it passesbase-pathto Redoc for you. When the description is mounted as a file, a relativeSPEC_URLsuch asopenapi.yamlresolves against the web root (under theBASE_PATHprefix when it is set) onceBASE_PATHorrouter="history"is set, so deep links load it too; a path such as/v1/openapi.yamlis used as given.PORT— port80is restricted on OpenShift, so setPORT=8080there and match it in the container spec. The image already runs as an arbitrary UID;config/docker/README.mdexplains which directories are group-writable and why.--read-only— start-up writes only to/tmp, so add--tmpfs /tmp.
From the repository root, to get an image from this checkout rather than Docker Hub:
docker build -t redocly/redoc -f config/docker/Dockerfile .The build compiles bundles/redoc.standalone.js from source and copies it into the nginx image,
so what you get matches the code you have, not the last release.
