Skip to main content

Deploy Nuxt.js on Ubuntu — production guide

TL;DR

Complete guide to deploying a production Nuxt 3 application on Ubuntu 24.04 with Node.js, PM2, nginx, and SSL.

Key facts

Topology
Nuxt 3 on Ubuntu 24.04

TL;DR

This guide walks through deploying Nuxt 3 on a fresh Ubuntu 24.04 server — from system preparation through Node.js installation, build process, PM2 configuration, nginx reverse proxy, and SSL termination.

Prerequisites

  • Ubuntu 24.04 LTS with root or sudo access
  • A domain name with DNS pointing to your server's IP
  • Your Nuxt 3 project in a Git repository

Step 1 — System preparation

Update the system and install essentials:

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git build-essential

Create a deploy user:

sudo adduser deploy
sudo usermod -aG sudo deploy
su - deploy

Step 2 — Install Node.js 20 LTS

Install via NodeSource:

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
node -v && npm -v

Step 3 — Clone and build

sudo mkdir -p /var/www/nuxt-app
sudo chown deploy:deploy /var/www/nuxt-app
cd /var/www/nuxt-app
git clone git@github.com:yourorg/nuxt-app.git .
npm ci

Create your production environment file:

cp .env.example .env
# Edit with production values: NUXT_PUBLIC_API_BASE, etc.

Build the application:

npx nuxt build

This produces the .output directory with the self-contained Nitro server.

Step 4 — PM2 process management

sudo npm install -g pm2

Create ecosystem.config.cjs:

module.exports = {
  apps: [{
    name: 'nuxt-app',
    script: '.output/server/index.mjs',
    cwd: '/var/www/nuxt-app',
    instances: 'max',
    exec_mode: 'cluster',
    max_memory_restart: '512M',
    exp_backoff_restart_delay: 100,
    env: {
      NODE_ENV: 'production',
      NUXT_HOST: '127.0.0.1',
      NUXT_PORT: 3000,
    },
  }],
}

Start and persist:

pm2 start ecosystem.config.cjs
pm2 startup systemd
pm2 save

Verify:

pm2 status
curl -I http://127.0.0.1:3000/

Step 5 — nginx reverse proxy

sudo apt install -y nginx

Create /etc/nginx/sites-available/nuxt-app:

server {
    listen 80;
    server_name example.com;

    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml;
    gzip_min_length 1000;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        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_read_timeout 60s;
        proxy_connect_timeout 10s;
    }

    location /_nuxt/ {
        alias /var/www/nuxt-app/.output/public/_nuxt/;
        expires 365d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }
}

Enable and test:

sudo ln -s /etc/nginx/sites-available/nuxt-app /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx

Step 6 — SSL with Certbot

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com

Certbot configures auto-renewal automatically. Verify:

sudo systemctl status certbot.timer

Step 7 — Firewall

sudo ufw allow 'Nginx Full'
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status

Step 8 — Log management

Install PM2 log rotation to prevent disk fill:

pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true

Deployment script

For subsequent deploys:

#!/bin/bash
set -euo pipefail
cd /var/www/nuxt-app
git pull origin main
npm ci
npx nuxt build
pm2 reload ecosystem.config.cjs
sleep 3
curl -sf http://127.0.0.1:3000/ > /dev/null && echo "Deploy OK" || echo "Deploy FAILED"

With Reflex

Install reflexd on your Ubuntu server to gain continuous monitoring, automated deploys, and incident recovery for your Nuxt 3 application. Reflex manages PM2 process health, nginx configuration, SSL renewal, disk/memory thresholds, and zero-downtime deployments — replacing manual SSH maintenance with audited, repeatable playbooks. See How it works.