All posts
Next.js deployment on Apache2 server with Linux terminal
  • Next.js
  • Apache
  • Deployment
  • SSL
  • Node.js

Deploying Next.js with Apache2

A comprehensive guide to deploying your Next.js application on a server running Apache2, covering both standard Node.js and static export deployments with SSL.

3 min read

Follow this guide to deploy your Next.js application on your own server running Apache2. Two deployment modes are covered: a standard Node.js deployment with full SSR support, and a static export for simpler setups.

Standard Deployment with Node.js

Deploy your app with server-side rendering, API routes, and middleware fully intact.

1. Build your Next.js app

Build locally before transferring to the server:

# Navigate to your project directory
cd your-next-app

# Install dependencies if you haven't already
npm install

# Build the app
npm run build

# This creates a .next directory with the built app

2. Transfer files to your server

Use SCP, SFTP, or any file transfer method to copy the built files:

# Example using SCP (run from your local machine)
scp -r .next package.json package-lock.json public next.config.js username@your-server-ip:/path/to/your/app

3. Install dependencies on your server

SSH into your server and install production dependencies:

cd /path/to/your/app
npm install --production

4. Set up Apache with reverse proxy

Enable the required Apache modules:

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel  # For WebSocket support
sudo a2enmod rewrite

Create the virtual host configuration file:

sudo nano /etc/apache2/sites-available/nextjs.conf

Add this configuration (adjust domain names as needed):

<VirtualHost *:80>
    ServerName yourdomain.com
    ServerAdmin webmaster@yourdomain.com

    # Proxy all requests to the Next.js server
    ProxyPreserveHost On
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/

    # WebSocket support
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule /(.*) ws://localhost:3000/$1 [P,L]

    ErrorLog ${APACHE_LOG_DIR}/nextjs_error.log
    CustomLog ${APACHE_LOG_DIR}/nextjs_access.log combined
</VirtualHost>

Enable the site and restart Apache:

sudo a2ensite nextjs.conf
sudo systemctl restart apache2

5. Run your Next.js server with PM2

PM2 keeps the Node.js process running and restarts it on server reboot. For a full PM2 reference covering ecosystem config files, cluster mode, and log rotation, see the PM2 Node.js Process Management Guide.

# Install PM2 globally
sudo npm install -g pm2

# Start your Next.js app
cd /path/to/your/app
pm2 start npm --name "next-app" -- start

# Persist across reboots
pm2 startup
pm2 save

6. Set up SSL with Certbot

Obtain and install a free Let’s Encrypt certificate. For a complete SSL guide covering HSTS, auto-renewal, and troubleshooting, see Set Up HTTPS with Let’s Encrypt on Nginx and Apache.

sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d yourdomain.com

Certbot will automatically update your Apache configuration to redirect HTTP to HTTPS.


Static Export Deployment

Use this method when you don’t need SSR, API routes, or middleware — Apache serves flat HTML files directly.

1. Configure your app for static export

Add the output setting to your next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
}

module.exports = nextConfig

2. Build your app

npm run build

This creates an out directory containing only static files.

3. Configure Apache to serve static files

Create the virtual host:

<VirtualHost *:80>
    ServerName yourdomain.com
    ServerAdmin webmaster@yourdomain.com

    DocumentRoot /path/to/your/app/out

    <Directory "/path/to/your/app/out">
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/nextjs_error.log
    CustomLog ${APACHE_LOG_DIR}/nextjs_access.log combined
</VirtualHost>

4. Enable the site and restart Apache

sudo a2ensite nextjs.conf
sudo systemctl restart apache2

5. Set up SSL

sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d yourdomain.com

Important Notes

  • Your server must have Node.js installed. Check the official Next.js docs for the minimum Node.js version required by your release — each major version may raise the minimum.
  • Static export does not support SSR, API routes, server actions, or middleware.
  • Set your environment variables in .env.production on the server — keep this file out of version control.
  • Always use HTTPS in production and consider implementing proper caching strategies.

Frequently Asked Questions

Do I need Node.js installed on the Apache server?

Yes, for the standard deployment. For static export, Apache serves the pre-built HTML files and Node.js is not required at runtime.

Would Nginx be a better fit?

Nginx generally handles static assets more efficiently and has a smaller memory footprint. If you’re not already running Apache, see Deploying Next.js with Nginx for the equivalent guide.

Will my Next.js API routes work with static export?

No. API routes, server actions, and middleware require a Node.js runtime and are incompatible with static export. Use the standard deployment if your app relies on any of these.

How do I manage environment variables in production?

Create a .env.production file on your server containing the variables. For static exports, any variables consumed client-side must be prefixed with NEXT_PUBLIC_ and be available at build time, since they get embedded into the JavaScript bundles.