3 min read

Deploying Node.js Applications (Nuxt + NestJS) on Ubuntu 24.04

We used AI while writing this content.

Supported Platforms

Ubuntu 24.04 LTS
Ubuntu 22.04 LTS
Debian 12+
Other Linux distributions ✅ (with adjustments)

Setup

1. Install Node.js and npm

Update your system and install Node.js:

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

Verify installation:

node --version
npm --version

Tip: Node.js 20.x is the current LTS (Long Term Support) version. Adjust the version number as needed.

2. Install PM2 process manager

PM2 keeps your application running in the background and restarts it automatically on crashes or server reboots:

sudo npm install -g pm2

3. Clone and prepare your application

Navigate to your deployment directory and clone your repository:

cd /var/www
sudo mkdir -p myapp
sudo chown -R <app_user>:<app_user_group> myapp
cd myapp
git clone https://github.com/yourusername/your-repo.git .

Install dependencies:

npm install

4. Build your application

For Nuxt (Frontend)

npm run build

This creates a .output directory with your production-ready application.

For NestJS (Backend)

npm run build

This compiles TypeScript to JavaScript in the dist directory.

5. Configure environment variables

Create a .env file in your project root:

nano .env

Add your production configuration:

NODE_ENV=production
PORT=3000
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
API_SECRET=your-secret-key

Security note: Never commit .env files to version control. Keep sensitive credentials secure.

6. Start application with PM2

For Nuxt application

pm2 start .output/server/index.mjs --name "nuxt-app"

For NestJS application

pm2 start dist/main.js --name "nestjs-api"

For combined setup (monorepo)

pm2 start ecosystem.config.js

Example ecosystem.config.js:

module.exports = {
  apps: [
    {
      name: 'nuxt-frontend',
      script: '.output/server/index.mjs',
      env: {
        NODE_ENV: 'production',
        PORT: 3000
      }
    },
    {
      name: 'nestjs-backend',
      script: 'dist/main.js',
      env: {
        NODE_ENV: 'production',
        PORT: 3001
      }
    }
  ]
};

7. Configure PM2 to start on system boot

pm2 startup systemd
pm2 save

Follow the command output instructions (you may need to run a generated command with sudo).

8. Set up Nginx as reverse proxy

Install Nginx:

sudo apt install -y nginx

Create a new Nginx configuration:

sudo nano /etc/nginx/sites-available/myapp

Add the following configuration:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    # Frontend (Nuxt)
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    # Backend API (NestJS)
    location /api {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

Enable the site and restart Nginx:

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

9. Configure firewall

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

Install Certbot:

sudo apt install -y certbot python3-certbot-nginx

Obtain and install SSL certificate:

sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Follow the prompts. Certbot will automatically configure Nginx for HTTPS.

Useful PM2 commands

Monitor applications:

pm2 status
pm2 logs
pm2 monit

Restart applications:

pm2 restart all
pm2 restart nuxt-app

Stop applications:

pm2 stop all
pm2 delete all

Updating your application

cd /var/www/myapp
git pull origin main
npm install
npm run build
pm2 restart all

Copyleft Statement

Renoncé du droit d'auteur

Much of our content is freely available under the Creative Commons BY-NC-ND 4.0 licence, which allows free distribution and republishing of our content for non-commercial purposes, as long as Ronzz.org is appropriately credited and the content is not being modified materially to express a different meaning than it is originally intended for. It must be noted that some images on Ronzz.org are the intellectual property of third parties. Our permission to use those images may not cover your reproduction. This does not affect your statutory rights.

Nous mettons la plupart de nos contenus disponibles gratuitement sous la licence Creative Commons By-NC-ND 4.0, qui permet une distribution et une republication gratuites de notre contenu à des fins non commerciales, tant que Ronzz.org est correctement crédité et que le contenu n'est pas modifié matériellement pour exprimer un sens différent que prévu à l'origine.Il faut noter que certaines images sur Ronzz.org sont des propriétés intellectuelles de tiers. Notre autorisation d'utiliser ces images peut ne pas couvrir votre reproduction. Cela n'affecte pas vos droits statutaires.