Swagger конейнер на основе Windows в Docker

Содержание
Введение
Структура проекта
Код докерфайла
Сборка и публикация
Статьи про Docker

Введение

Допустим существует какой-то сервер с API, к которому нативно не приделали Swagger. Для простоты будем называть его API

Он может крутиться в Docker контейнере на основе Windows. Стоит задача поднять рабочий Swagger чтобы из него демонстировать Try it out запросы.

Можно добавить его в существующий контейнер либо поднять рядом новый. Будем поднимать рядом новый руководствовуясь принципом

Один сервис - один конейнер

Структура проекта

Так как конейнер на базе Windows, в этом проекте будет использоваться Docker с Windows engine , соответственно все остальные контейнеры будут на базе Windows то есть использовать нативный контейнер swaggerapi/swagger-ui не получится.

Из секции Plain old HTML/CSS/JS (Standalone) официальной инструкции по установке Swagger мы можем узнать, что скачать актуальную версию в виде архива можно здесь .

В этом примере используется версия 5.11.10 скачивать и настраивать её мы будем PowerShell скриптом, но советую также скачать эту директорию вручную и изучить содержимое. Основная директория, в которой мы будет работать - это dist

separate_containers/ |-- docker-compose.yml `-- dockerfiles |-- Dockerfile.server |-- Dockerfile.swagger.python |-- setup.ps1 |-- src | `-- bin | `-- Server.exe `-- swagger_config `- dist |-- swagger-initializer.js `-- swagger.json

Dockerfile.server и директория src/bin относятся к API.

Нас мало интересует что там внутри, главное чтобы докер образ подходил нашей Windows

Допустим докер файл выглядит так

# Dockerfile.server # Host: Microsoft Windows [Version 10.0.22621.3155] FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 COPY src/bin/ /bin EXPOSE 9500 WORKDIR /bin ENTRYPOINT ["Server.exe"]

Dockerfile.swagger.python нужен нам для запуска http сервера в директории swagger-ui/dist

# Dockerfile.swagger.python # Host: Microsoft Windows [Version 10.0.22621.3155] FROM python:3.12.2-windowsservercore LABEL author="https://devhops.ru" COPY swagger-ui /swagger-ui WORKDIR /swagger-ui/dist ENTRYPOINT [ "python", "-m", "http.server" ]

Если по какой-то причине вам не подходит образ на основе Python можно использовать образ servercore и установить туда Node.js

# Dockerfile.swagger.node # Host: Microsoft Windows [Version 10.0.22621.3155] FROM mcr.microsoft.com/windows/servercore:ltsc2022 LABEL author="www.DevHops.ru" RUN powershell.exe -Command \ Invoke-WebRequest -OutFile nodejs.zip -UseBasicParsing "https://nodejs.org/download/release/v16.20.2/node-v16.20.2-win-x64.zip"; \ Expand-Archive -Path nodejs.zip -DestinationPath C:\; \ Rename-Item "C:\node-v16.20.2-win-x64" C:\nodejs; WORKDIR "C:\nodejs" RUN setx path "%path%;C:\nodejs" WORKDIR /bin COPY swagger-ui /swagger-ui RUN npm install -g http-server WORKDIR /swagger-ui/dist ENTRYPOINT [ "http-server", "--cors" ]

docker-compose.yml

Простой compose файл docker-compose.yml связывает контейнеры вместе.

# docker-compose.yml services: compose-swagger-win: build: context: ./dockerfiles dockerfile: Dockerfile.swagger.python ports: - "8002:8000" container_name: compose_swagger_win compose-colreg-server: build: context: ./dockerfiles dockerfile: Dockerfile.colreg ports: - "9500:9801" container_name: compose_colreg_win

РЕКЛАМА от Яндекса. Может быть недоступна в вашем регионе

Конец рекламы. Если там пусто считайте это рекламой моей телеги

Нужно подготовить файл с описание API. Раз это не сделано автоматически, значит придётся наскебать информации по фрагментам, например по телам запросов и так далее.

Можно предварительно установить Swagger editor и там писать openapi.yaml файл а потом сконвертировать его в JSON

Так или иначе нужно подготовить swagger.json

{ "openapi": "3.0.3", "info": { "title": "www.TopBicycle.ru", "version": "0.1.0" }, "servers": [ { "url": "http://localhost:9500" } ], "paths": { "/endpoint": { "post": { "summary": "Update bike Info", "operationId": "update_bike_info_bikes_post", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Body_update_bike_info_bikes_post" } } }, "required": true }, "responses": { "200": { "description": "Successful Response", "headers": { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "*", "Access-Control-Allow-Headers": "*" }, "content": { "application/json": { "schema": {} } } }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HTTPValidationError" } } } } } } } }, "components": { "schemas": { "Body_update_bike_info_bikes_post": { "type": "array", "items": { "$ref": "#/components/schemas/bikes" }, "required": [ "bike1", "bike2" ], "title": "Body_update_bike_info_bikes_post" }, "HTTPValidationError": { "properties": { "detail": { "items": { "$ref": "#/components/schemas/ValidationError" }, "type": "array", "title": "Detail" } }, "type": "object", "title": "HTTPValidationError" }, "Info": { "properties": { "id": { "type": "integer", "title": "Id" }, "name": { "type": "string", "title": "Name" }, "manuf": { "type": "string", "title": "Manufacturer" }, "type": "object", "required": [ "id", "name", "manuf" ], "title": "Info" } }, "Bikes": { "properties": { "bike1": { "$ref": "#/components/schemas/Bike" }, "bike2": { "$ref": "#/components/schemas/Bike" } }, "required": [ "bike1", "bike2" ] }, "Bike": { "properties": { "info": { "$ref": "#/components/schemas/Info" }, "type": "object", "required": [ "info" ], "title": "bike" } } } } }

Затем подоговим файл swagger-initializer.js

window.onload = function() { //<editor-fold desc="Changeable Configuration Block"> // the following lines will be replaced by docker/configurator, when it runs in a docker-container window.ui = SwaggerUIBundle({ url: "swagger.json", dom_id: '#swagger-ui', deepLinking: true, presets: [ SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset ], plugins: [ SwaggerUIBundle.plugins.DownloadUrl ], layout: "StandaloneLayout" }); //</editor-fold> };

Если бы мы запускали нативный контейнер, то, скорее-всего пришлось бы редактировать файл translator.js из swagger-ui/docker/configurator

url: { value: "swagger.json", schema: { type: "string", base: true } },

Но нам это сейчас не нужно. Эти файлы можно предварительно скачать здесь как уже было сказано в начале статьи.

Сборка и запуск

Собирать и запускать проект будет скрипт setup.ps1 который сперва скачает и распакует архив со swagger-ui затем подставит туда заранее приготовленные файлы swagger.json и swagger-initializer.js и затем выполнит команды docker compose up --build

$SWAGGER_VERSION = "5.11.10" $SWAGGER_URL = "https://github.com/swagger-api/swagger-ui/archive/refs/tags/v${SWAGGER_VERSION}.zip"; $SWAGGER_DIR = "swagger-ui" $swagger_ui_path = Join-Path ${pwd} ${SWAGGER_DIR}; $json_path = Join-Path ${pwd} "swagger_config\dist\swagger.json"; $initializer_path = Join-Path ${pwd} "swagger_config\dist\swagger-initializer.js"; # $translator_path = Join-Path ${pwd} "swagger_config\docker\configurator\translator.js"; $dist = Join-Path ${pwd} "${SWAGGER_DIR}\dist\"; # $configurator = Join-Path ${pwd} "${SWAGGER_DIR}\docker\configurator\"; If (Test-Path -path ${swagger_ui_path}) { Write-Host "${SWAGGER_DIR} dir exists" -f Green; } Else { Write-Host "${SWAGGER_DIR} dir does not exist - starting download" -f Yellow Invoke-WebRequest $SWAGGER_URL -OutFile swagger-ui.zip Expand-Archive -Path swagger-ui.zip -DestinationPath . Remove-Item swagger-ui.zip Rename-Item -Path "swagger-ui-${SWAGGER_VERSION}" -NewName ${SWAGGER_DIR} Copy-Item -Path ${json_path} -Destination ${dist} -Recurse -force Copy-Item -Path ${initializer_path} -Destination ${dist} -Recurse -force # Copy-Item -Path ${translator_path} -Destination ${configurator} -Recurse -force } docker compose build docker compose up

После завершения сборки нужно будет в браузере, например в Firefox открыть адрес

localhost:8002

И в открывшемся Swagger UI выполнять запросы Try it out к API

Похожие статьи
Docker
build: Создание контейнеров + примеры
Dockerfile
Ubuntu в контейнере на Windows 10
Контейнер с доступом по SSH
Контейнер с Nginx
Контейнер для Jenkins агента
Контейнер для PyTest
Контейнер для Swagger
Make

РЕКЛАМА хостинга Beget, которым я пользуюсь более десяти лет

Изображение баннера

Конец рекламы хостинга Beget, который я всем рекомендую.

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящую по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: