# syntax=docker/dockerfile:1.7 # Wine CSP Service - GOST cryptographic operations via Wine-hosted CryptoPro CSP # # WARNING: For TEST VECTOR GENERATION ONLY - not for production signing # # Build: # docker buildx build -f ops/wine-csp/Dockerfile -t wine-csp:latest . # # Run: # docker run -p 5099:5099 -e WINE_CSP_MODE=limited wine-csp:latest # ============================================================================== # Stage 1: Build .NET application for Windows x64 # ============================================================================== ARG SDK_IMAGE=mcr.microsoft.com/dotnet/sdk:10.0-preview-bookworm-slim FROM ${SDK_IMAGE} AS build ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 \ DOTNET_NOLOGO=1 \ DOTNET_ROLL_FORWARD=LatestMajor \ SOURCE_DATE_EPOCH=1704067200 WORKDIR /src # Copy solution files and NuGet configuration COPY Directory.Build.props Directory.Build.rsp NuGet.config ./ # Copy local NuGet packages if available COPY local-nugets/ ./local-nugets/ # Copy Wine CSP Service source COPY src/__Tools/WineCspService/ ./src/__Tools/WineCspService/ # Copy GostCryptography fork dependency COPY third_party/forks/AlexMAS.GostCryptography/ ./third_party/forks/AlexMAS.GostCryptography/ # Restore and publish for Windows x64 (runs under Wine) RUN --mount=type=cache,target=/root/.nuget/packages \ dotnet restore src/__Tools/WineCspService/WineCspService.csproj && \ dotnet publish src/__Tools/WineCspService/WineCspService.csproj \ -c Release \ -r win-x64 \ --self-contained true \ -o /app/publish \ /p:PublishSingleFile=true \ /p:EnableCompressionInSingleFile=true \ /p:DebugType=none \ /p:DebugSymbols=false # ============================================================================== # Stage 2: Runtime with Wine and CryptoPro CSP support # ============================================================================== FROM ubuntu:22.04 AS runtime # OCI Image Labels LABEL org.opencontainers.image.title="StellaOps Wine CSP Service" \ org.opencontainers.image.description="GOST cryptographic test vector generation via Wine-hosted CryptoPro CSP" \ org.opencontainers.image.vendor="StellaOps" \ org.opencontainers.image.source="https://git.stella-ops.org/stellaops/router" \ com.stellaops.component="wine-csp" \ com.stellaops.security.production-signing="false" \ com.stellaops.security.test-vectors-only="true" # Wine CSP service configuration ARG WINE_CSP_PORT=5099 ARG APP_USER=winecsp ARG APP_UID=10001 ARG APP_GID=10001 ENV DEBIAN_FRONTEND=noninteractive \ # Wine configuration WINEDEBUG=-all \ WINEPREFIX=/home/${APP_USER}/.wine \ WINEARCH=win64 \ # Service configuration WINE_CSP_PORT=${WINE_CSP_PORT} \ ASPNETCORE_URLS=http://+:${WINE_CSP_PORT} \ DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 \ # CSP configuration WINE_CSP_MODE=limited \ WINE_CSP_INSTALLER_PATH=/opt/cryptopro/csp-installer.msi \ WINE_CSP_LOG_LEVEL=Information \ # Display for Wine (headless) DISPLAY=:99 # Install Wine and dependencies # Using WineHQ stable repository for consistent Wine version RUN set -eux; \ dpkg --add-architecture i386; \ apt-get update; \ apt-get install -y --no-install-recommends \ ca-certificates \ curl \ gnupg2 \ software-properties-common \ wget \ xvfb \ cabextract \ p7zip-full \ procps; \ # Add WineHQ repository key mkdir -pm755 /etc/apt/keyrings; \ wget -O /etc/apt/keyrings/winehq-archive.key \ https://dl.winehq.org/wine-builds/winehq.key; \ # Add WineHQ repository wget -NP /etc/apt/sources.list.d/ \ https://dl.winehq.org/wine-builds/ubuntu/dists/jammy/winehq-jammy.sources; \ apt-get update; \ # Install Wine stable apt-get install -y --no-install-recommends \ winehq-stable; \ # Install winetricks for runtime dependencies wget -O /usr/local/bin/winetricks \ https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks; \ chmod +x /usr/local/bin/winetricks; \ # Cleanup apt-get clean; \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # Create non-root user for Wine service # Note: Wine requires writable home directory for prefix RUN groupadd -r -g ${APP_GID} ${APP_USER} && \ useradd -r -u ${APP_UID} -g ${APP_GID} -m -d /home/${APP_USER} -s /bin/bash ${APP_USER} && \ mkdir -p /app /opt/cryptopro /var/log/wine-csp /var/run/wine-csp && \ chown -R ${APP_UID}:${APP_GID} /app /home/${APP_USER} /opt/cryptopro /var/log/wine-csp /var/run/wine-csp WORKDIR /app # Copy application from build stage COPY --from=build --chown=${APP_UID}:${APP_GID} /app/publish/ ./ # Copy supporting scripts COPY --chown=${APP_UID}:${APP_GID} ops/wine-csp/entrypoint.sh /usr/local/bin/entrypoint.sh COPY --chown=${APP_UID}:${APP_GID} ops/wine-csp/healthcheck.sh /usr/local/bin/healthcheck.sh COPY --chown=${APP_UID}:${APP_GID} ops/wine-csp/install-csp.sh /usr/local/bin/install-csp.sh RUN chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/healthcheck.sh /usr/local/bin/install-csp.sh # Switch to non-root user for Wine prefix initialization USER ${APP_UID}:${APP_GID} # Initialize Wine prefix (creates .wine directory with Windows environment) # This must run as the app user to set correct ownership # Using xvfb-run for headless Wine initialization RUN set -eux; \ # Start virtual framebuffer and initialize Wine xvfb-run --auto-servernum --server-args="-screen 0 1024x768x24" \ wine64 wineboot --init; \ wineserver --wait; \ # Install Visual C++ 2019 runtime via winetricks (required for .NET) xvfb-run --auto-servernum --server-args="-screen 0 1024x768x24" \ winetricks -q vcrun2019 || true; \ wineserver --wait; \ # Set Windows version to Windows 10 for compatibility wine64 reg add "HKCU\\Software\\Wine\\Version" /v Windows /d "win10" /f || true; \ wineserver --wait; \ # Cleanup Wine temp files rm -rf /home/${APP_USER}/.cache/winetricks /tmp/.X* /tmp/winetricks* || true EXPOSE ${WINE_CSP_PORT} # Health check using custom script that probes /health endpoint # Extended start_period due to Wine initialization time HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \ CMD /usr/local/bin/healthcheck.sh # Volumes for persistence and CSP installer # - Wine prefix: stores CSP installation, certificates, keys # - CSP installer: mount customer-provided CryptoPro MSI here # - Logs: service logs VOLUME ["/home/${APP_USER}/.wine", "/opt/cryptopro", "/var/log/wine-csp"] ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] CMD ["wine64", "/app/WineCspService.exe"]