From 9d6967f47a4a5aa82deca7415b6e3ab8ea97373d Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Thu, 5 Jun 2025 11:27:25 +0200 Subject: [PATCH] feat(docker): build and publish unprivileged Docker image Similar to swagger-editor This will allow to deploy Swagger-UI on clusters such as OpenShift without having to meddle with the security context and security context constraints. --- .github/workflows/docker-build-push.yml | 20 ++++++++++-- Dockerfile | 2 +- Dockerfile.unprivileged | 42 +++++++++++++++++++++++++ docs/development/docker.md | 21 +++++++++++++ 4 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 Dockerfile.unprivileged create mode 100644 docs/development/docker.md diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index 5b32e21d3e2..456b6effb01 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -56,6 +56,12 @@ jobs: - linux/arm64 - linux/386 - linux/ppc64le + docker: + - file: Dockerfile + tag: ${{ needs.inputs.outputs.docker_tag }} + - file: Dockerfile.unprivileged + tag: ${{ needs.inputs.outputs.docker_tag }}-unprivileged + needs: - inputs @@ -82,6 +88,8 @@ jobs: with: context: . platforms: ${{ matrix.platform }} + file: ${{ matrix.docker.file }} + tags: ${{ matrix.docker.tag }} provenance: false outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true @@ -114,6 +122,12 @@ jobs: - inputs - build + strategy: + matrix: + tag: + - ${{ needs.inputs.outputs.docker_tag }} + - ${{ needs.inputs.outputs.docker_tag }}-unprivileged + steps: - name: Download digests uses: actions/download-artifact@v4 @@ -134,10 +148,10 @@ jobs: - name: Create manifest list and push working-directory: /tmp/digests run: | - docker buildx imagetools create -t ${{ env.REGISTRY_IMAGE }}:${{ needs.inputs.outputs.docker_tag }} \ - ${{ env.REGISTRY_IMAGE }}:${{ needs.inputs.outputs.docker_tag }} \ + docker buildx imagetools create -t ${{ env.REGISTRY_IMAGE }}:${{ matrix.tag }} \ + ${{ env.REGISTRY_IMAGE }}:${{ matrix.tag }} \ $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) - name: Inspect image run: | - docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ needs.inputs.outputs.docker_tag }} + docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ matrix.tag }} diff --git a/Dockerfile b/Dockerfile index e4679a157dd..e69b5f3df54 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,7 +31,7 @@ COPY --chmod=0555 ./docker/docker-entrypoint.d/ /docker-entrypoint.d/ COPY --chmod=0666 ./docker/configurator /usr/share/nginx/configurator # Simulates running NGINX as a non root; in future we want to use nginxinc/nginx-unprivileged. -# In future we will have separate unpriviledged images tagged as v5.1.2-unprivileged. +# In future we will have separate unprivileged images tagged as v5.1.2-unprivileged. RUN chmod 777 /usr/share/nginx/html/ /etc/nginx/conf.d/ /etc/nginx/conf.d/default.conf /var/cache/nginx/ /var/run/ EXPOSE 8080 diff --git a/Dockerfile.unprivileged b/Dockerfile.unprivileged new file mode 100644 index 00000000000..16b6904fc08 --- /dev/null +++ b/Dockerfile.unprivileged @@ -0,0 +1,42 @@ +# Looking for information on environment variables? +# We don't declare them here — take a look at our docs. +# https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md + +FROM nginxinc/nginx-unprivileged:1.27.5-alpine + +LABEL maintainer="vladimir.gorej@gmail.com" \ + org.opencontainers.image.authors="vladimir.gorej@gmail.com" \ + org.opencontainers.image.url="docker.swagger.io/swaggerapi/swagger-ui" \ + org.opencontainers.image.source="https://github.com/swagger-api/swagger-ui" \ + org.opencontainers.image.description="SwaggerUI Docker image" \ + org.opencontainers.image.licenses="Apache-2.0" + +USER root + +RUN apk add --update-cache --no-cache "nodejs" "libxml2>=2.13.4-r6" "libexpat>=2.7.0-r0" "libxslt>=1.1.42-r2" "xz-libs>=5.6.3-r1" "c-ares>=1.34.5-r0" +RUN mkdir /etc/nginx/templates && \ + mkdir /usr/share/nginx/configurator && \ + # If user is set to a different ID at runtime, html must be writable by them too + chown -R nginx:nginx /usr/share/nginx/html && \ + chmod a+rw /usr/share/nginx/html + +USER nginx + +LABEL maintainer="char0n" + +ENV API_KEY="**None**" \ + SWAGGER_JSON="/app/swagger.json" \ + PORT="8080" \ + PORT_IPV6="" \ + BASE_URL="/" \ + SWAGGER_JSON_URL="" \ + CORS="true" \ + EMBEDDING="false" + +COPY --chmod=0666 ./docker/default.conf.template ./docker/cors.conf ./docker/embedding.conf /etc/nginx/templates/ + +COPY --chown=nginx --chmod=0666 ./dist/* /usr/share/nginx/html/ +COPY --chmod=0555 ./docker/docker-entrypoint.d/ /docker-entrypoint.d/ +COPY --chown=nginx --chmod=0666 ./docker/configurator /usr/share/nginx/configurator + +EXPOSE 8080 diff --git a/docs/development/docker.md b/docs/development/docker.md new file mode 100644 index 00000000000..0cacdc3c8fd --- /dev/null +++ b/docs/development/docker.md @@ -0,0 +1,21 @@ +# Docker images + +## Building locally + +**Privileged image**: + +```sh + $ docker build . -t swaggerapi/swagger-ui:next + $ docker run -d -p 8080:8080 swaggerapi/swagger-ui:next +``` + +Now open your browser at `http://localhost:8080/`. + +**Unprivileged image**: + +```sh + $ docker build . -f Dockerfile.unprivileged -t swaggerapi/swagger-ui:next-unprivileged + $ docker run -d -p 8080:8080 swaggerapi/swagger-ui:next-unprivileged +``` + +Now open your browser at `http://localhost:8080/`.