A modern full-stack AI-powered chat application built with FastAPI, Next.js, PostgreSQL, and Docker.
The project consists of a Python backend exposing REST APIs and AI integrations, and a React frontend built with Next.js. The application is fully containerized using Docker Compose, making it easy to develop, test, and deploy consistently across environments.
- FastAPI backend
- Next.js frontend
- PostgreSQL database
- SQLAlchemy Async ORM
- Alembic database migrations
- JWT-based authentication
- OpenAI integration
- Dockerized development environment
- TypeScript frontend
- Tailwind CSS UI
- TanStack Query for API communication
- Python 3.13
- FastAPI
- SQLAlchemy 2.x (Async)
- Alembic
- PostgreSQL
- asyncpg
- psycopg (binary)
- OpenAI SDK
- uv package manager
- Next.js 16
- React 19
- TypeScript
- Tailwind CSS 4
- TanStack Query
- shadcn/ui
- React Markdown
- JWT Decode
- Docker
- Docker Compose
.
├── backend
│ ├── alembic
│ ├── alembic.ini
│ ├── app
│ ├── Dockerfile
│ ├── entrypoint.sh
│ ├── __init__.py
│ ├── pyproject.toml
│ ├── README.md
│ ├── resources
│ └── uv.lock
├── Caddyfile
├── docker-compose.yaml # dev
├── docker-compose.prod.yaml # production (Caddy + services)
├── docs
│ ├── architecture.md
│ ├── database.md
│ ├── deployment.md
│ └── development.md
├── frontend
│ ├── components.json
│ ├── Dockerfile
│ ├── eslint.config.mjs
│ ├── next.config.ts
│ ├── node_modules
│ ├── package.json
│ ├── package-lock.json
│ ├── postcss.config.mjs
│ ├── public
│ ├── README.md
│ ├── src
│ └── tsconfig.json
└── README.md
┌─────────────────────┐
│ Browser │
└──────────┬──────────┘
│ HTTPS
▼
Caddy (TLS)
│
┌──────────────┴──────────────┐
│ │
▼ ▼
Next.js Frontend FastAPI Backend (/api/*)
│
┌─────────────┴─────────────┐
▼ ▼
PostgreSQL OpenAI API
Before running the project, install:
- Docker
- Docker Compose
- Git
For local Python development outside Docker:
- Python 3.13
- uv
Clone the repository:
git clone <repository-url>
cd <repository-name>Build the containers:
docker compose buildStart all services:
docker compose up -dVerify that everything is running:
docker compose psView backend logs:
docker compose logs -f backendView frontend logs:
docker compose logs -f frontendStop all services:
docker compose downcd backend && uv run --env-file .env -m app.build_indexThe application uses environment variables for configuration.
Store sensitive values in a local .env files on server.
The backend is built with FastAPI and uses SQLAlchemy's asynchronous ORM together with PostgreSQL.
The Docker image:
- Uses Python 3.13 Slim
- Installs dependencies with uv
- Creates an isolated virtual environment
- Runs as a non-root user
Start only the backend:
docker compose up backendOpen a shell:
docker compose exec backend bashThe frontend is built with Next.js 16 and React 19.
The Docker image:
- Uses Node.js Alpine
- Installs dependencies
- Builds the production bundle
- Starts the Next.js server
- Exposes port 3000
Start only the frontend:
docker compose up frontendOpen a shell:
docker compose exec frontend shThe project uses PostgreSQL with Alembic for schema migrations.
Whenever SQLAlchemy models change or new deployment:
docker compose exec backend alembic revision --autogenerate -m "migration description"Example:
docker compose exec backend alembic revision --autogenerate -m "add users and tokens"Always review generated migrations before applying them.
Migrations will be performed automatically when docker backend container is started, to set latest.
docker compose exec backend alembic upgrade headdocker compose exec backend alembic currentdocker compose exec backend alembic historyExecuted command in the "db" docker container.
-U for username, e.g. "postgres"
-d for database schema, e.g. "db"
docker compose exec db psql -U postgres -d dbList tables:
\dtExit PostgreSQL:
\qOnce the backend is running:
Swagger UI:
http://localhost:8000/docs
Redoc UI:
http://localhost:8000/redoc
OpenAPI Specification:
http://localhost:8000/openapi.json
Build containers:
docker compose buildRebuild backend:
docker compose build --no-cache backendRestart backend:
docker compose restart backendRestart frontend:
docker compose restart frontendRestart all services:
docker compose restartStop services:
docker compose stopRemove containers and volumes:
docker compose down -vView logs:
docker compose logs -fTypical development workflow:
- Update application code.
- Modify SQLAlchemy models if required.
- Generate an Alembic migration.
- Review the generated migration.
- Apply the migration.
- Test the application.
- Commit both code and migration files.
When a test suite is available:
docker compose exec backend pytestLint the frontend:
docker compose exec frontend npm run lintCheck the backend logs:
docker compose logs backendVerify the database container is running:
docker compose psVerify the current migration:
docker compose exec backend alembic currentApply pending migrations:
docker compose exec backend alembic upgrade headBackend:
docker compose build --no-cache backendFrontend:
docker compose build --no-cache frontendSee docs/deployment.md for the full guide to running
this on chat.mringdal.com.
Short version:
cp backend/.env.production.example backend/.env # fill in real secrets
docker compose -f docker-compose.prod.yaml up -d --buildCaddy handles TLS via Let's Encrypt and proxies /api/* to the backend,
everything else to the Next.js frontend. Alembic migrations run automatically
in the backend entrypoint.
Possible future enhancements include:
- CI/CD pipeline
- Automated testing
- Redis caching
- Background workers
- Rate limiting
- Monitoring and metrics
- Centralized logging
- Backup automation
- Multi-environment configuration
- API versioning
- Chat client polymorph and factory (YAGNI)