> For the complete documentation index, see [llms.txt](https://nghiaxchis.gitbook.io/ncmaz-nextjs-headless-cms-wordpres-blog-magazine/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://nghiaxchis.gitbook.io/ncmaz-nextjs-headless-cms-wordpres-blog-magazine/how/deployment-guide-ncmaz-headless-wordpress-on-aapanel.md).

# Deployment Guide Ncmaz Headless WordPress on aaPanel

**Project Overview** Ncmaz is a modern, high-performance blog/magazine built as a **headless WordPress** frontend using:

* **Next.js 15**&#x20;
* **Faust.js** (Headless WordPress toolkit by WP Engine)
* **Tailwind CSS** &#x20;
* **TypeScript**

The frontend fetches content via GraphQL (WPGraphQL) from your WordPress backend, enabling full **SSR**, **ISR**, **previews**, and optimal performance without losing Next.js advantages like Image Optimization and Middleware.

This guide explains how to deploy the frontend project (folder: ncmaz-faust) to a VPS running **aaPanel** using Node.js + PM2 + Nginx reverse proxy. This setup keeps all dynamic Next.js features intact (unlike static export).

### Prerequisites

* aaPanel installed on your VPS (latest version recommended).
* Node.js ≥18 (preferably 20 or 22 for Next.js 15 compatibility).
* Your WordPress site ready with:
  * WPGraphQL plugin
  * FaustWP plugin (or ncmaz-faust-core plugin included in the theme package)
  * Permalink set to "Post name"
* Domain pointed to your VPS IP.
* Faust Secret Key from WordPress → Settings → Faust (required for previews and authentication).

### Step 1: Prepare aaPanel Environment

1. Log in to aaPanel.
2. Go to **App Store** → Install **Node.js Version Manager** (if not installed).
3. Install a compatible Node.js version (e.g., 20.x or 22.x).
4. Install **PM2 Manager** (aaPanel includes it for process management).

### Step 2: Upload the Project

1. In aaPanel → **Files** → Create a new folder: /www/wwwroot/ncmaz-faust
2. Upload your entire ncmaz-faust project folder contents here (via File Manager, FTP, or SFTP). Ensure key files are present: package.json, next.config.js, faust.config.ts, app/, public/, Tailwind config, etc.

### Step 3: Install Dependencies and Build

1. Open aaPanel **Terminal** (or SSH into the server).
2. Navigate to the project:Bash

   ```
   cd /www/wwwroot/ncmaz-faust
   ```
3. Install dependencies:Bash

   ```
   npm install   # or yarn / pnpm if used in your project
   ```
4. Build for production:Bash

   ```
   npm run build   # This runs `faust build` or `next build` (creates .next folder)
   ```

### Step 4: Set Environment Variables

Faust.js requires these variables for connecting to WordPress:

Create or edit .env.production in the project root (or add them directly in aaPanel Node Project settings later):

text

```
NEXT_PUBLIC_WORDPRESS_URL=https://your-wordpress-site.com
FAUST_SECRET_KEY=your_faust_secret_key_from_wp_admin
```

* NEXT\_PUBLIC\_WORDPRESS\_URL: Full URL to your WordPress site (must be accessible from the VPS).
* FAUST\_SECRET\_KEY: Found in WordPress → Settings → Faust (critical for previews and revalidation).

**Note**: Do **not** commit these to Git in production.

### Step 5: Create Node Project in aaPanel

1. Go to aaPanel → **Node** → **Node Projects** → **Add Node Project**.
2. Fill in:
   * **Project Name**: ncmaz-faust (or any name)
   * **Path**: /www/wwwroot/ncmaz-faust
   * **Port**: Choose an internal port (e.g., 3000 or 3001)
   * **Startup File**: Leave default (aaPanel detects Next.js)
   * **Run Mode**: **PM2** (essential for background running and auto-restart)
   * **Run Command**: npm run start (or faust start / next start)
3. In **Environment Variables** tab: Add the two vars from Step 4.
4. Submit → aaPanel will run npm install (if needed), build, and start the app via PM2.

### Step 6: Configure Nginx Reverse Proxy

1. Go to **Website** → **Add Site** → Create site with your domain (e.g., example.com).
2. In the site's **Config** tab, edit the Nginx configuration to proxy to your Node port:

   nginx

   ```
   server {
       listen 80;
       server_name example.com www.example.com;

       location / {
           proxy_pass http://127.0.0.1:3000;  # Replace with your Node port
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forwarded-Proto $scheme;

           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "upgrade";
       }

       # Critical for Next.js Image Optimization
       location /_next/image {
           proxy_pass http://127.0.0.1:3000;
       }

       # Optional: Cache static assets
       location /_next/static {
           proxy_pass http://127.0.0.1:3000;
           expires 30d;
       }
   }
   ```
3. Enable **SSL** (Let's Encrypt) directly in the SSL tab.

### Step 7: Start and Test

1. In **Node Projects** → Start/Restart your project.
2. Visit your domain → The site should load with full SSR/ISR from your WordPress backend.
3. Check PM2 logs in aaPanel for any errors (GraphQL connection, env vars, etc.).
4. Test features: Previews, Image Optimization (next/image), ISR revalidation.

### Optimization Tips for Next.js + Faust.js

* **ISR Revalidation**: Faust handles webhook-based revalidation from WordPress automatically (via secret key).
* **Performance**: Tailwind CSS 4 purges unused styles perfectly in production build.
* **Monitoring**: Use PM2 dashboard in aaPanel to monitor CPU/memory and auto-restarts.
* **Updates**: To update code, upload new files → npm install → npm run build → Restart PM2 process.
* **Common Issues**:
  * GraphQL errors → Verify NEXT\_PUBLIC\_WORDPRESS\_URL and WPGraphQL accessibility.
  * Images not loading → Ensure \_next/image proxy is correct.
  * Previews not working → Double-check FAUST\_SECRET\_KEY.

This deployment fully leverages Next.js strengths (SSR, ISR, API routes if any) while keeping your WordPress backend separate and secure. Your Ncmaz site will be fast, SEO-friendly, and scalable.

If you encounter specific errors (PM2 logs, Nginx errors), share them for further debugging. Enjoy your headless setup! 🚀


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://nghiaxchis.gitbook.io/ncmaz-nextjs-headless-cms-wordpres-blog-magazine/how/deployment-guide-ncmaz-headless-wordpress-on-aapanel.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
