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
2025-06-02 10:13:46 +02:00
2025-05-30 13:25:49 +02:00
2025-06-02 12:17:44 +02:00
2025-06-02 10:04:42 +02:00
2025-05-30 13:25:49 +02:00
2025-05-30 13:25:49 +02:00
2025-05-31 02:43:51 +02:00
2025-05-30 13:25:49 +02:00
2025-05-30 13:25:49 +02:00

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

# 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:

NEXT_PUBLIC_API_URL=http://localhost:8000/api

For production, create .env.production:

NEXT_PUBLIC_API_URL=https://api.portfolio-host.com/api

Development

# Start development server
npm run dev

Visit http://localhost:3000

Build

# 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:

# 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:

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:

{
  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:

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:

# 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

# Ensure @tailwindcss/postcss is installed
npm install @tailwindcss/postcss

Issue: TypeScript errors

# 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.

Description
No description provided
Readme 55 MiB
Languages
HTML 92.1%
TypeScript 7.5%
CSS 0.4%