This is a comprehensive guide to building a full-stack application using React for the frontend and Aspire for the backend based on Building a Full-Stack App with React and Aspire: A Step-by-Step Guide .
According to the Building a Full-Stack App with React and Aspire: A Step-by-Step Guide, you need to create the React app with vite, and create some jsx files and modify files like index.html, main.jsx, App.jsx, index.css, App.css.
If you want to use TypeScript, you should create the React app with TypeScript, and make the same modifications.
Additionally, you need to make the following changes.
-
Install @types/node to devDependencies
npm install --save-dev @types/node
-
Modify vite.config.ts
import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');
return {
plugins: [react()],
server: {
port: parseInt(env.VITE_PORT),
proxy: {
// "apiservice" is the name of the API in AppHost.cs.
'/api': {
target: process.env.services__apiservice__https__0 || process.env.services__apiservice__http__0,
changeOrigin: true,
secure: false,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
build: {
outDir: 'dist',
rollupOptions: {
input: './index.html'
}
}
}
})target: process.env.services__apiservice__https__0 || process.env.services__apiservice__http__0, is for forwarding API requests to the Aspire backend. process.env.services__apiservice__https__0 and process.env.services__apiservice__http__0 are environment variables that will be replaced with the actual URL of the API backend.
- Fix the errors in tsx files
Most errors are caused by missing type definitions for variables, arguments, and return values. You can fix these errors by updating your code or by copying type definitions from this repository and adding them to your files.
You need to make the following changes to create a Docker image.
- Create Dockerfile in todo-frontend root directory
FROM node:22.19.0-alpine@sha256:d2166de198f26e17e5a442f537754dd616ab069c47cc57b889310a717e0abbf9 AS build
WORKDIR /app
COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/default.conf.template /etc/nginx/templates/default.conf.template
COPY --from=build /app/dist /usr/share/nginx/html
# Expose the default nginx port
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]- Create default.conf.template in todo-frontend root directory
This is for configuring nginx to serve the React app and proxy API requests to the Aspire backend.
server {
listen ${VITE_PORT};
listen [::]:${VITE_PORT};
server_name localhost;
access_log /var/log/nginx/server.access.log main;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass ${services__apiservice__https__0};
proxy_http_version 1.1;
proxy_ssl_server_name on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
rewrite ^/api(/.*)$ $1 break;
}
}Similar to the configuration in vite.config.ts, proxy_pass ${services__apiservice__https__0}; is used to forward API requests to the API backend.
${VITE_PORT} is an environment variable that needs to be defined in the docker-compose.yaml file.
We have 2 options to create a docker image for TodoTsAspire.ApiService.
- Using Dockerfile
- Using the built-in container support in .NET SDK
You should create a Dockerfile in the root directory of TodoTsAspire. Do not create it in the TodoTsAspire.ApiService directory.
FROM mcr.microsoft.com/dotnet/sdk:9.0@sha256:ae000be75dac94fc40e00f0eee903289e985995cc06dac3937469254ce5b60b6 AS build
WORKDIR /app
# Copy everything
COPY . ./
# Change to ApiService directory
WORKDIR /app/TodoTsAspire.ApiService
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:9.0@sha256:515c08e27cf8d933af442f0e1b6c92cc728acb71f113ca529f56c79cb597adb5
WORKDIR /app
# ApiServiceの成果物をコピー
COPY --from=build /app/TodoTsAspire.ApiService/out .
ENTRYPOINT ["dotnet", "TodoTsAspire.ApiService.dll"]To create the image, run the following command in the root directory of TodoTsAspire.
docker build -t apiservice:latest .You can use the built-in container support in .NET SDK to create a docker image for TodoTsAspire.ApiService. The necessary configurations have already been added to the TodoTsAspire.ApiService.csproj file.
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Docker Image Tag Name-->
<ContainerRepository>apiservice</ContainerRepository>
<!-- Chage user in container from app to root to allow writing the SQLite file -->
<ContainerUser>root</ContainerUser>
</PropertyGroup>As shown above, ContainerRepository is set to apiservice, which will be the name of the Docker image. ContainerUser is set to root to allow writing the SQLite file.
To create the Docker image, run the following command in the root directory of TodoTsAspire.ApiService.
dotnet publish --os linux --arch arm64 /t:PublishContainerIf you are using an x64 machine, change --arch arm64 to --arch x64.
A docker-compose.yaml file has already been created in the docker-compose-artifacts directory. You can use it to run the application.
docker compose -f ./docker-compose-artifacts/docker-compose.yaml up