# Frontend Separation Deployment This guide will help you independently deploy PPanel frontend applications and connect them to the deployed backend service. ## Overview Frontend separation deployment allows you to deploy PPanel frontend applications on independent servers or CDN, communicating with backend services through APIs. PPanel frontend includes two independent applications: - **User Web** (`ppanel-user-web`): User-facing interface - **Admin Web** (`ppanel-admin-web`): Administrator backend management interface ### Advantages - 🚀 Leverage CDN to accelerate static resource access - 🌍 Support multi-region distribution - 📦 Independent frontend deployment without affecting backend services - 🔄 Facilitate rapid frontend iteration and updates - 🎨 Modern tech stack (React 19, TypeScript, TailwindCSS 4) ## Prerequisites - Completed [Backend Deployment](./backend.md) - Backend API address (e.g., `https://api.your-domain.com`) - Frontend domains: - User Web: `https://user.your-domain.com` - Admin Web: `https://admin.your-domain.com` ## Tech Stack - **Runtime**: Bun (recommended) / Node.js 20+ - **Build Tool**: Vite 6 - **Framework**: React 19 + TypeScript - **Router**: TanStack Router - **Styling**: TailwindCSS 4 - **State Management**: Zustand - **i18n**: i18next - **Monorepo**: Turborepo ## Deployment Methods ### Method 1: Build from Source (Recommended) #### 1. Environment Setup Install Bun (recommended): ```bash # Linux/macOS curl -fsSL https://bun.sh/install | bash # Windows (WSL2) curl -fsSL https://bun.sh/install | bash # Verify installation bun --version ``` Or use Node.js (requires 20+): ```bash # Check Node.js version node --version # Should be v20 or higher ``` #### 2. Clone Repository ```bash git clone https://github.com/perfect-panel/frontend.git cd frontend ``` #### 3. Install Dependencies ```bash # Using Bun (recommended, faster) bun install # Or using npm npm install # Or using pnpm pnpm install ``` #### 4. Configure Environment Variables Create environment configuration files in application directories. **Admin Web Config** (`apps/admin/.env.production`): ```bash # Backend API address (required) VITE_API_BASE_URL=https://api.your-domain.com # CDN address (optional, for accelerating static resources) VITE_CDN_URL=https://cdn.jsdmirror.com # Enable tutorial documentation (optional) VITE_TUTORIAL_DOCUMENT=true # Show landing page (optional, set to false to redirect to login directly) VITE_SHOW_LANDING_PAGE=true # Development default credentials (leave empty in production) VITE_USER_EMAIL= VITE_USER_PASSWORD= ``` **User Web Config** (`apps/user/.env.production`): ```bash # Backend API address (required) VITE_API_BASE_URL=https://api.your-domain.com # CDN address (optional) VITE_CDN_URL=https://cdn.jsdmirror.com # Enable tutorial documentation (optional) VITE_TUTORIAL_DOCUMENT=true # Development default credentials (leave empty in production) VITE_USER_EMAIL= VITE_USER_PASSWORD= ``` #### 5. Build Applications Build all applications: ```bash # Using Bun bun run build # Or using npm npm run build ``` Build specific application: ```bash # Navigate to application directory cd apps/admin # or apps/user # Build bun run build # or npm run build ``` After build completes, static files will be output to: - Admin Web: `apps/admin/dist/` - User Web: `apps/user/dist/` #### 6. Preview Build ```bash # In application directory bun run serve # or npm run serve # Default access address: # Admin Web: http://localhost:4173 # User Web: http://localhost:4173 ``` ### Method 2: Deploy with Vercel (One-Click) #### Admin Web Deployment Click the button below to deploy to Vercel with one click: [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?demo-description=PPanel%20is%20a%20pure%2C%20professional%2C%20and%20perfect%20open-source%20proxy%20panel%20tool&demo-image=https%3A%2F%2Furlscan.io%2Fliveshot%2F%3Fwidth%3D1920%26height%3D1080%26url%3Dhttps%3A%2F%2Fadmin.ppanel.dev&demo-title=PPanel%20Admin%20Web&repository-url=https%3A%2F%2Fgithub.com%2Fperfect-panel%2Ffrontend&root-directory=apps%2Fadmin) #### User Web Deployment [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?demo-description=PPanel%20is%20a%20pure%2C%20professional%2C%20and%20perfect%20open-source%20proxy%20panel%20tool&demo-image=https%3A%2F%2Furlscan.io%2Fliveshot%2F%3Fwidth%3D1920%26height%3D1080%26url%3Dhttps%3A%2F%2Fuser.ppanel.dev&demo-title=PPanel%20User%20Web&repository-url=https%3A%2F%2Fgithub.com%2Fperfect-panel%2Ffrontend&root-directory=apps%2Fuser) After deployment, configure environment variables in Vercel console: - `VITE_API_BASE_URL`: Your backend API address - `VITE_CDN_URL`: CDN address (optional) ### Method 3: Deploy with Netlify #### 1. Install Netlify CLI ```bash npm install -g netlify-cli ``` #### 2. Login to Netlify ```bash netlify login ``` #### 3. Deploy Application ```bash # Admin Web cd apps/admin bun run build netlify deploy --prod --dir=dist # User Web cd apps/user bun run build netlify deploy --prod --dir=dist ``` #### 4. Configure Environment Variables Add in Netlify console under Site settings → Build & deploy → Environment: - `VITE_API_BASE_URL` - `VITE_CDN_URL` ### Method 4: Deploy with Cloudflare Pages #### 1. Connect GitHub Repository Login to Cloudflare Dashboard → Workers & Pages → Create application → Pages → Connect to Git #### 2. Configure Build Settings **Admin Web**: - **Framework preset**: None - **Build command**: `cd .. && bun install && cd apps/admin && bun run build` - **Build output directory**: `apps/admin/dist` - **Root directory**: `apps/admin` **User Web**: - **Framework preset**: None - **Build command**: `cd .. && bun install && cd apps/user && bun run build` - **Build output directory**: `apps/user/dist` - **Root directory**: `apps/user` #### 3. Configure Environment Variables Add in Settings → Environment variables: - `VITE_API_BASE_URL` - `VITE_CDN_URL` ## Self-Hosted Server Deployment ### Using Nginx #### 1. Install Nginx ```bash # Ubuntu/Debian sudo apt update sudo apt install nginx -y # CentOS/RHEL sudo yum install nginx -y ``` #### 2. Upload Build Files ```bash # Create directories sudo mkdir -p /var/www/ppanel/{admin,user} # Upload build files sudo cp -r apps/admin/dist/* /var/www/ppanel/admin/ sudo cp -r apps/user/dist/* /var/www/ppanel/user/ # Set permissions sudo chown -R www-data:www-data /var/www/ppanel ``` #### 3. Configure Nginx **Admin Web Config** (`/etc/nginx/sites-available/ppanel-admin`): ```nginx server { listen 80; server_name admin.your-domain.com; root /var/www/ppanel/admin; index index.html; # Gzip compression gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; gzip_vary on; gzip_min_length 1024; # Static resource caching location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; } # SPA routing support location / { try_files $uri $uri/ /index.html; } # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; } ``` **User Web Config** (`/etc/nginx/sites-available/ppanel-user`): ```nginx server { listen 80; server_name user.your-domain.com; root /var/www/ppanel/user; index index.html; # Other config same as admin web gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; } location / { try_files $uri $uri/ /index.html; } add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; } ``` #### 4. Enable Sites ```bash # Enable sites sudo ln -s /etc/nginx/sites-available/ppanel-admin /etc/nginx/sites-enabled/ sudo ln -s /etc/nginx/sites-available/ppanel-user /etc/nginx/sites-enabled/ # Test configuration sudo nginx -t # Reload Nginx sudo systemctl reload nginx ``` #### 5. Configure HTTPS (Recommended) Use Certbot to automatically configure SSL certificates: ```bash # Install Certbot sudo apt install certbot python3-certbot-nginx -y # Obtain certificates sudo certbot --nginx -d admin.your-domain.com sudo certbot --nginx -d user.your-domain.com # Test auto-renewal sudo certbot renew --dry-run ``` ### Using Caddy Caddy automatically handles HTTPS with simpler configuration. #### 1. Install Caddy ```bash # Ubuntu/Debian sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddy ``` #### 2. Configure Caddyfile Create `/etc/caddy/Caddyfile`: ```caddy admin.your-domain.com { root * /var/www/ppanel/admin encode gzip file_server try_files {path} /index.html @static { path *.js *.css *.png *.jpg *.jpeg *.gif *.ico *.svg *.woff *.woff2 *.ttf *.eot } header @static Cache-Control "public, max-age=31536000, immutable" header { X-Frame-Options "SAMEORIGIN" X-Content-Type-Options "nosniff" X-XSS-Protection "1; mode=block" } } user.your-domain.com { root * /var/www/ppanel/user encode gzip file_server try_files {path} /index.html @static { path *.js *.css *.png *.jpg *.jpeg *.gif *.ico *.svg *.woff *.woff2 *.ttf *.eot } header @static Cache-Control "public, max-age=31536000, immutable" header { X-Frame-Options "SAMEORIGIN" X-Content-Type-Options "nosniff" X-XSS-Protection "1; mode=block" } } ``` #### 3. Start Caddy ```bash sudo systemctl restart caddy sudo systemctl enable caddy ``` ## CDN Configuration ### Cloudflare Configuration 1. Add domain to Cloudflare 2. Configure DNS records pointing to origin server 3. Enable optimization options: - **Auto Minify**: Enable JavaScript, CSS, HTML minification - **Brotli**: Enable Brotli compression - **Rocket Loader**: Enable JS async loading (optional) - **Caching Level**: Set to Standard 4. Configure page rules: ``` *your-domain.com/* - Cache Level: Cache Everything - Edge Cache TTL: 1 month - Browser Cache TTL: Respect Existing Headers ``` ### Alibaba Cloud CDN 1. Create CDN acceleration domain 2. Configure origin server: Point to frontend server 3. Configure caching rules: - Static files (js, css, images): Cache 1 year - HTML files: Cache 5 minutes or no cache 4. Enable HTTPS and HTTP/2 ## Environment Variables | Variable | Description | Required | Default | Example | |----------|-------------|----------|---------|---------| | `VITE_API_BASE_URL` | Backend API address | ✅ | - | `https://api.your-domain.com` | | `VITE_CDN_URL` | CDN address | ❌ | `https://cdn.jsdmirror.com` | `https://cdn.your-domain.com` | | `VITE_TUTORIAL_DOCUMENT` | Enable tutorial docs | ❌ | `true` | `true` / `false` | | `VITE_SHOW_LANDING_PAGE` | Show landing page | ❌ | `true` | `true` / `false` | | `VITE_USER_EMAIL` | Default login email (dev only) | ❌ | - | - | | `VITE_USER_PASSWORD` | Default login password (dev only) | ❌ | - | - | ## Verify Deployment ### Check Frontend Service ```bash # Access frontend addresses curl -I https://admin.your-domain.com curl -I https://user.your-domain.com # Expected output # HTTP/2 200 # content-type: text/html ``` ### Check API Connection Open frontend address in browser, open developer tools: 1. Check Network tab 2. Verify API requests are successful 3. Confirm request addresses are correct (`https://api.your-domain.com`) 4. Check response data is normal ### Check Build Version Access `/version.lock` file to view currently deployed version: ```bash curl https://admin.your-domain.com/version.lock # Example output: 1.2.0 ``` ## Performance Optimization ### 1. Enable HTTP/2 In Nginx: ```nginx listen 443 ssl http2; ``` ### 2. Enable Brotli Compression ```bash # Install Nginx Brotli module sudo apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static -y ``` In Nginx configuration: ```nginx brotli on; brotli_types text/plain text/css application/json application/javascript text/xml application/xml; brotli_comp_level 6; ``` ### 3. Preload Critical Resources Vite automatically handles this during build, adding `` in `index.html`. ### 4. Enable Service Worker Frontend has built-in PWA support, Service Worker caching is automatically enabled after build. ### 5. Use CDN Acceleration Configure `VITE_CDN_URL` environment variable to load static resources from CDN. ## Troubleshooting ### API Request Failed **Issue**: Frontend cannot connect to backend API **Solution**: 1. Check if `VITE_API_BASE_URL` is correctly configured 2. Check if backend CORS configuration allows frontend domain 3. Open browser console for specific error messages 4. Use `curl` to test if backend API is accessible ```bash curl https://api.your-domain.com/api/health ``` ### Page Route 404 **Issue**: Refreshing page or directly accessing sub-route returns 404 **Solution**: Ensure web server has SPA fallback configured ```nginx # Nginx try_files $uri $uri/ /index.html; # Apache (.htaccess) RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] ``` ### Static Resource Loading Failed **Issue**: JS/CSS files 404 or cannot load **Solution**: 1. Check file permissions 2. Check if Nginx `root` path is correct 3. Clear browser cache 4. Check CDN configuration ### Build Failed **Issue**: `bun run build` or `npm run build` fails **Solution**: 1. Ensure Node.js version >= 20 2. Delete `node_modules` and lock file, reinstall ```bash rm -rf node_modules bun.lockb bun install ``` 3. Check for syntax errors or type errors ```bash bun run check ``` ## Update Deployment ### Update from Source ```bash # Pull latest code git pull origin main # Reinstall dependencies bun install # Rebuild bun run build # Update files sudo rm -rf /var/www/ppanel/admin sudo rm -rf /var/www/ppanel/user sudo cp -r apps/admin/dist /var/www/ppanel/admin sudo cp -r apps/user/dist /var/www/ppanel/user # Clear CDN cache (if using CDN) ``` ### Vercel Update Vercel automatically monitors GitHub repository changes and deploys automatically. Can also trigger manually: ```bash vercel --prod ``` ### Netlify Update ```bash cd apps/admin # or apps/user bun run build netlify deploy --prod ``` ## Security Recommendations 1. **Enable HTTPS**: Must use SSL/TLS certificates 2. **Configure CSP**: Content Security Policy ```nginx add_header Content-Security-Policy "default-src 'self'; connect-src 'self' https://api.your-domain.com; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval';"; ``` 3. **Set Security Headers**: Already included in Nginx configuration 4. **Disable Directory Browsing**: `Options -Indexes` (Apache) or `autoindex off;` (Nginx) 5. **Limit File Upload Size**: ```nginx client_max_body_size 10M; ``` ## Monitoring and Analytics ### Add Web Analytics Supports Google Analytics, Umami, Plausible, etc. Configuration: Add tracking code in `index.html` or configure via environment variables. ### Error Tracking Frontend supports integrating Sentry for error tracking (needs code configuration). ## Development and Production ### Local Development ```bash # Use development server cd apps/admin # or apps/user bun run dev # Admin Web runs on http://localhost:3001 by default # User Web runs on http://localhost:3000 by default ``` Development environment uses Vite's proxy feature to proxy API requests to backend. ### Preview Production Build ```bash # Preview after build bun run build bun run serve ``` ## Next Steps - [Backend Separation Deployment](./backend.md) - If backend not yet deployed - [Node Agent Installation](../node/installation.md) - Deploy node service - [Feature Documentation](/admin/dashboard) - Learn feature usage