Alexis Bruneteau d5c1c90c50 feat(dockerfile): add multi-stage Next.js Docker build configuration
Update Dockerfile for Next.js 15 migration with production-optimized build:
- Multi-stage build separating compilation from runtime
- Next.js standalone output mode (~150-200MB final image)
- Non-root user (nextjs:1000) for security hardening
- Health check endpoint for orchestration monitoring
- Node.js 20 Alpine runtime for minimal footprint

Add .dockerignore to exclude development files from build context,
reducing build time and image size.

Update README with comprehensive Docker deployment documentation including
environment variable configuration and image features.

OpenSpec: Implements fix-dockerfile-nextjs proposal (26/30 tasks completed)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 00:49:03 +02:00

300 lines
7.2 KiB
Markdown

# Portfolio Hosting Platform - Frontend
A modern Next.js application for managing and deploying portfolio websites with custom domains.
## Tech Stack
- **Framework**: Next.js 15 with App Router
- **Language**: TypeScript 5.8
- **Styling**: Tailwind CSS 4.1 with shadcn/ui components
- **State Management**: React Context API + hooks
- **Forms**: React Hook Form
- **Icons**: Lucide React
- **Authentication**: JWT Bearer tokens
## Features
- **User Authentication**: Login and registration with JWT tokens
- **Portfolio Management**: Create, upload, and deploy portfolio websites
- **File Upload**: ZIP file upload with progress tracking
- **Dashboard**: Comprehensive portfolio management interface
- **Responsive Design**: Mobile-first, fully responsive UI
- **Protected Routes**: Middleware-based authentication
## Project Structure
```
/
├── app/ # Next.js App Router pages
│ ├── layout.tsx # Root layout with AuthProvider
│ ├── page.tsx # Landing page
│ ├── login/ # Login page
│ ├── register/ # Registration page
│ └── dashboard/ # Dashboard (protected)
├── components/ # React components
│ ├── ui/ # shadcn/ui primitives
│ └── auth/ # Authentication components
├── lib/ # Utilities and API client
│ ├── api-client.ts # Fetch wrapper with auth
│ ├── types.ts # TypeScript interfaces
│ └── utils.ts # Utility functions
├── hooks/ # Custom React hooks
│ ├── use-auth.ts # Authentication hook
│ └── use-portfolios.ts # Portfolio data hook
└── middleware.ts # Route protection
```
## Getting Started
### Prerequisites
- Node.js 18+ and npm
- Backend API running (see API section)
### Installation
```bash
# Install dependencies
npm install
# Set up environment variables
cp .env.local.example .env.local
# Edit .env.local with your API URL
```
### Environment Variables
Create a `.env.local` file:
```env
NEXT_PUBLIC_API_URL=http://localhost:8000/api
```
For production, create `.env.production`:
```env
NEXT_PUBLIC_API_URL=https://api.portfolio-host.com/api
```
### Development
```bash
# Start development server
npm run dev
```
Visit [http://localhost:3000](http://localhost:3000)
### Build
```bash
# Build for production
npm run build
# Start production server
npm start
```
### Docker Deployment
The project includes a multi-stage Dockerfile optimized for Next.js standalone output:
```bash
# Build Docker image
docker build -t hosting-frontend:latest .
# Run container with default settings
docker run -p 3000:3000 hosting-frontend:latest
# Run with custom API URL
docker run -p 3000:3000 \
-e NEXT_PUBLIC_API_URL=https://api.example.com/api \
hosting-frontend:latest
# Run with Docker Compose
docker-compose up
```
#### Docker Image Features
- **Multi-stage build**: Separates build and runtime stages for minimal image size
- **Standalone output**: Uses Next.js `output: 'standalone'` mode (~150-200MB image)
- **Non-root user**: Container runs as `nextjs` user (UID 1000) for security
- **Health check**: Includes automatic health check endpoint monitoring
- **Node.js 20 Alpine**: Lightweight runtime based on Alpine Linux
#### Docker Environment Variables
Pass environment variables at runtime:
```bash
docker run \
-e NEXT_PUBLIC_API_URL=https://api.example.com/api \
-e PORT=3000 \
-p 3000:3000 \
hosting-frontend:latest
```
#### Building Optimized Images
The `.dockerignore` file excludes unnecessary files from the build context:
- Development dependencies
- Git history
- Node modules (rebuilt in build stage)
- Local environment files
## API Integration
The application integrates with a backend API for:
### Authentication Endpoints
- `POST /auth/register` - User registration
- `POST /auth/login` - User login
- `POST /auth/logout` - Logout
- `GET /auth/user` - Get current user
- `POST /auth/refresh` - Refresh token
### Portfolio Endpoints
- `GET /portfolios` - List user's portfolios
- `POST /portfolios` - Create new portfolio
- `POST /portfolios/{id}/upload` - Upload ZIP file
- `POST /portfolios/{id}/deploy` - Deploy portfolio
- `GET /portfolio/random` - Get random portfolio
### API Response Format
All API responses follow this structure:
```typescript
{
success: boolean;
data?: T;
message?: string;
errors?: any;
}
```
## Key Components
### Authentication Flow
1. User logs in via `/login`
2. API returns JWT token
3. Token stored in localStorage
4. AuthContext provides auth state globally
5. Middleware protects `/dashboard/*` routes
6. API client automatically injects Bearer token
### Portfolio Management Flow
1. User creates portfolio (name + domain)
2. Upload ZIP file containing portfolio files
3. Deploy portfolio to make it live
4. Status indicators show portfolio state:
- **Pending Payment**: Not yet active
- **Pending Upload**: Active but no files
- **Uploaded**: Ready to deploy
## Code Style & Conventions
### File Naming
- Components: `PascalCase.tsx`
- Utilities: `kebab-case.ts`
- Pages: Next.js conventions (`page.tsx`, `layout.tsx`)
### Component Patterns
- Use `'use client'` directive for client components
- Server components by default
- Colocate styles with components
### State Management
- Global auth state: `AuthContext`
- Component state: `useState`
- Form state: React Hook Form
### API Calls
- Use `apiClient` from `lib/api-client.ts`
- Wrap in try/catch
- Handle loading and error states
## Migration from Angular
This project was migrated from Angular 20 to Next.js 15. Key changes:
- **Framework**: Angular → Next.js + React
- **Routing**: Angular Router → Next.js App Router
- **State**: RxJS → React Context API
- **Forms**: Angular Reactive Forms → React Hook Form
- **HTTP**: Angular HttpClient → Fetch API
The Angular code has been backed up to `/angular-backup` for reference.
## Deployment
### Production Build
The production build uses Next.js standalone output for optimal performance:
```bash
npm run build
```
Output is in `.next/standalone/`
### Environment Configuration
- Development: `.env.local`
- Production: `.env.production`
- Staging: `.env.staging`
### Docker
The included `Dockerfile` creates an optimized production image:
```dockerfile
# Build and run
docker build -t portfolio-frontend .
docker run -p 3000:3000 -e NEXT_PUBLIC_API_URL=https://api.example.com portfolio-frontend
```
## Troubleshooting
### Build Errors
**Issue**: Tailwind CSS errors
```bash
# Ensure @tailwindcss/postcss is installed
npm install @tailwindcss/postcss
```
**Issue**: TypeScript errors
```bash
# Regenerate types
rm -rf .next
npm run build
```
### Runtime Errors
**Issue**: API connection failed
- Check `NEXT_PUBLIC_API_URL` in `.env.local`
- Verify backend API is running
- Check CORS configuration on backend
**Issue**: Authentication not working
- Check localStorage for `auth_token`
- Verify JWT token format
- Check middleware configuration
## Contributing
1. Create feature branch from `main`
2. Make changes following code style
3. Test locally with `npm run build`
4. Submit pull request
## License
Copyright © 2025 Portfolio Host. All rights reserved.