Chapter 8

Add React, Vite, and FastAPI

Replace the static page with a small React frontend and typed FastAPI backend, each built as its own image.

Just started Saved in this browser.

The full-stack snapshot keeps one responsibility per container: nginx serves built React assets, while Uvicorn runs FastAPI. The browser joins them through HTTP.

Browser traffic split through ingress to React and FastAPI

Step by step

Download this chapter's files

Use your browser to download either ivia-chapter-08.tar.gz or ivia-chapter-08.zip. The archive is self-contained; you do not need this tutorial repository.

Open a terminal after the browser download:

cd ~/Downloads
tar -xzf ivia-chapter-08.tar.gz
cd ivia-chapter-08

All remaining relative paths in this chapter start from that extracted directory.

Do this

The challenge

Challenge: build and run both full-stack containers locally, then load a React page that displays a greeting returned by FastAPI.

Prepare

Prerequisites

  • Docker or a compatible container CLI.
  • Ports 5173 and 8080 available.
  • The extracted Chapter 8 package, with your terminal in its top-level directory.
  • No host Node.js or Python installation; the images contain build tools.
Outcome

Learning goals

  • Identify frontend and backend responsibilities
  • Understand Vite build output and nginx runtime serving
  • Read minimal FastAPI routes
  • Connect two containers through browser-visible ports
Step by step

Inspect the architecture

find fullstack-app -maxdepth 3 -type f -print
sed -n '1,200p' fullstack-app/frontend/src/App.jsx
sed -n '1,200p' fullstack-app/backend/app/main.py

config.js loads before React, so deployment can replace the API URL without rebuilding. The local default is http://localhost:8080. FastAPI permits http://localhost:5173 through CORS.

Step by step

Build both images

docker build -t simple-backend:local fullstack-app/backend
docker build -t simple-frontend:local fullstack-app/frontend

Dependency manifests are copied before source files so the builder can reuse dependency layers when only source changes.

Step by step

Run and connect

docker run --rm --name simple-backend -d \
  -p 8080:8080 \
  -e GREETING='Hello from two containers!' \
  simple-backend:local
docker run --rm --name simple-frontend -d \
  -p 5173:8080 simple-frontend:local

Validate FastAPI directly:

curl --fail http://localhost:8080/health
curl --fail http://localhost:8080/api/greeting

Open http://localhost:5173. It should show Hello from two containers!. Inspect and stop:

docker logs simple-backend
docker logs simple-frontend
docker stop simple-frontend simple-backend

React runs in the browser, not the frontend container. Therefore local localhost:8080 reaches the host-published backend. Chapter 9 replaces it with an ingress hostname.

Verify

Expected validation

Health returns {"status":"ok"}. Greeting returns JSON containing Hello from two containers!. The browser displays that greeting without a CORS error in its developer console.

Troubleshoot

Troubleshooting and common pitfalls

  • Failed to fetch: check docker ps and curl the API directly.
  • CORS error: open exactly http://localhost:5173; scheme, hostname, and port define an origin.
  • Dependency download fails: check network and registry access; host dependencies do not fix a container build.
  • Backend exits: inspect logs; import errors often indicate a changed build context.
  • Old page: rebuild and recreate the frontend container, then hard-refresh.
  • Vite expected at runtime: this image uses Vite only to build; nginx serves production files.

Two independently built services now cooperate through a small HTTP contract. That is a substantial architectural step.

Reference

Official references

Just started Saved in this browser.