reactjsasp.netdocker.net-corevite

VS2022 vanilla React + ASP.NET Core using docker over HTTPS gives error


I'm facing an error with the standard weatherforecast app and backend from VS2022.

I left everything standard:

React and ASP.NET Core app

Configuration options selected

I run it with Docker Desktop which goes smooth: enter image description here

I even see it running in VS2022, although what strikes me as odd is that I don't see any environmental variable for HTTPS: enter image description here

But when I run the app (F5), it loads successfully, but vite gives the following error:

14:48:28 [vite] http proxy error: /weatherforecast
AggregateError
at internalConnectMultiple (node:net:1114:18)
at afterConnectMultiple (node:net:1667:5) (x22)

The swagger files load correctly, so reaching the API is possible without a container: enter image description here

I know this has been asked before, but none of the options work. I'm quite annoyed that a standard app provided to help you understand how these different components work together doesn't work together.

This is the vite.config:

import { fileURLToPath, URL } from 'node:url';

import { defineConfig } from 'vite';
import plugin from '@vitejs/plugin-react';
import fs from 'fs';
import path from 'path';
import child_process from 'child_process';
import { env } from 'process';

const baseFolder =
    env.APPDATA !== undefined && env.APPDATA !== ''
        ? `${env.APPDATA}/ASP.NET/https`
        : `${env.HOME}/.aspnet/https`;

const certificateName = "portfolio.client";
const certFilePath = path.join(baseFolder, `${certificateName}.pem`);
const keyFilePath = path.join(baseFolder, `${certificateName}.key`);

if (!fs.existsSync(certFilePath) || !fs.existsSync(keyFilePath)) {
    if (0 !== child_process.spawnSync('dotnet', [
        'dev-certs',
        'https',
        '--export-path',
        certFilePath,
        '--format',
        'Pem',
        '--no-password',
    ], { stdio: 'inherit', }).status) {
        throw new Error("Could not create certificate.");
    }
}

const target = env.ASPNETCORE_HTTPS_PORT ?     `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` :
    env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'https://localhost:7008';

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [plugin()],
    resolve: {
        alias: {
            '@': fileURLToPath(new URL('./src', import.meta.url))
        }
    },
    server: {
        proxy: {
            '^/weatherforecast': {
                target,
                secure: false
            }
        },
        port: 5173,
        https: {
            key: fs.readFileSync(keyFilePath),
            cert: fs.readFileSync(certFilePath),
        }
    }

Solution

  • After quite some searching and investigating (This response had the solution for), I found that I needed to add the following to my .csproj.

    <PropertyGroup>
        <DockerfileRunArguments>-p "8080:8080" -p "8081:8081"</DockerfileRunArguments>
    </PropertyGroup>
    

    Even though the server was being built correctly as a Docker image and the Docker container was appropriately deployed, the Docker container wasn't exposing the ports to the outside! My client was sending requests to 8081, and my docker had those exposed, supposedly through my DockerFile with these commands:

    EXPOSE 8080
    EXPOSE 8081
    

    but only ones I added

    -p "8080:8080" -p "8081:8081"
    

    To my Dockerfile as build arguments, did it expose them. The below works fine as long as I have the commands attached:

    FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
    USER app
    WORKDIR /app
    
    FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
    ARG BUILD_CONFIGURATION=Release
    WORKDIR /src
    COPY ["/portfolio.Server/portfolio.Server.csproj", "portfolio.Server/"]
    RUN dotnet restore "./portfolio.Server/portfolio.Server.csproj"
    COPY . .
    WORKDIR "/src/portfolio.Server"
    RUN dotnet build "./portfolio.Server.csproj" -c $BUILD_CONFIGURATION -o /app/build
    
    FROM build AS publish
    ARG BUILD_CONFIGURATION=Release
    RUN dotnet publish "./portfolio.Server.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
    
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "portfolio.Server.dll"]
        
    

    But from what I understand from this post, EXPOSE only exposes the ports to other services connected to the same network (so inside the container).