Deploying Next.js to shared hosting can be tricky, and there's no universal solution. Every hosting platform has its differences, whether it's the operating system or available features. For example, some hosts allow SSH access, while others (like mine) don't. Because of that the solution that worked for me might not work for you
In my case, I had to rely solely on the cPanel dashboard to set up my Node.js app and troubleshoot issues.
I know, there are certainly better options out there but if you're on a budget or just want to experiment, shared hosting can be an accessible starting point.
Let me walk you through my experience.
The first step was modifying the Next.js configuration. I needed to set the export 'standalone'
mode. This change accomplishes two important things:
It eliminates the need to run any scripts in the cPanel build panel. I had an out-of-memory issue when I tried to run
npm run build
.
It generates a server.js file, which becomes our main entry point.
However, by default, not all required files are copied over.(Here's more info on that) So I also extended package.json with a postbuild
script to copy the necessary files to the standalone folder:
"build": "next build",
"start": "next start",
"lint": "next lint",
"postbuild": "npm run copy-static",
"copy-static": "mkdir -p .next/standalone/public && cp -r public/* .next/standalone/public/ && mkdir -p .next/standalone/.next/static && cp -r .next/static/* .next/standalone/.next/static/",
Next, I set up a GitHub Action to automate the build and deployment process. This action handles two tasks:
- Runs the build for the Next.js application
- Transfers the built files to the correct location on the shared hosting server via FTP (I created a separate FTP user with limited access to the destination folder)
name: Deploy Next.js to cPanel via FTP
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build Next.js app
run: npm run build
- name: Deploy to cPanel via FTP
uses: SamKirkland/FTP-Deploy-Action@v4.3.4
with:
server: ftp.yourserver.com
username: your-ftp@username
password: ${{ secrets.FTP_PASSWORD }}
local-dir: .next/standalone/
protocol: ftp
port: 21
Note: If you're like me after every build and deployment you would need to manually restart the node js app on Cpanel.
After pressing the Run NPM Install button and starting the application, your app should be live at its Application URL. However, in my case, the images weren’t optimized and when I checked the stderr.log
file in the application folder (You can use cPanel's File Manager to navigate there), I found this error:
⨯ Error: 'sharp' is required to be installed in standalone mode for image optimization to function correctly. Read more at: https://nextjs.org/docs/messages/sharp-missing-in-production
At first, I was confused because I had already installed sharp
, and I could see it in the symlinked node_modules
folder.
To figure out what was happening, I temporarily modified the server.js
file and added some code to collect debug information. Here's the snippet I used:
// Collect debug information
const debugInfo = {
dirname: __dirname,
cwd: process.cwd(),
nodePath: process.env.NODE_PATH,
path: process.env.PATH,
sharpStatus: 'Not checked yet',
sharpLocation: '',
};
// Try to load Sharp
try {
const sharp = require('sharp');
debugInfo.sharpStatus = `Loaded. Version: ${sharp.versions.sharp}`;
debugInfo.sharpLocation = `Sharp location: ${require.resolve('sharp')}`;
} catch (error) {
debugInfo.sharpStatus = `Error loading: ${error.message}`;
}
// Throw an error with the debug information
throw new Error(`Debug Info:
__dirname: ${debugInfo.dirname}
process.cwd(): ${debugInfo.cwd}
NODE_PATH: ${debugInfo.nodePath}
PATH: ${debugInfo.path}
Sharp status: ${debugInfo.sharpStatus}
Sharp location: ${debugInfo.sharpLocation}
`);
This block of code gathers some information like NODE_PATH:
which is an environment variable that tells Node.js where to look for modules in addition to the default node_modules directories and it can help you understand if there are any custom module resolution paths set up on your server.
Went back to stderr.log
and I saw:
Error: Debug Info:
...
Sharp status: Error loading: Could not load the "sharp" module using the linux-x64 runtime
ERR_DLOPEN_FAILED: /lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /home/ozuyuggp/nodevenv/yourdir/20/lib/node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64.node)
Possible solutions:
- Ensure optional dependencies can be installed:
npm install --include=optional sharp
- Ensure your package manager supports multi-platform installation:
See https://sharp.pixelplumbing.com/install#cross-platform
- Add platform-specific dependencies:
npm install --os=linux --cpu=x64 sharp
- Update your OS:
Found glibc 2.17
Requires glibc >=2.26
- Consult the installation documentation:
See https://sharp.pixelplumbing.com/install
After some digging, since I didn’t have control over the server environment, I would not be able to update packages, I decided the simplest solution was to roll back to an earlier version of sharp that had worked for others in similar situations.
I reverted to:
"sharp": "^0.32.6"
Hit npm install
, restart the app, and open the application URL again. Important note: Make sure to open or refresh the application URL every time. If not, server.js might not start, and you could miss new errors in the log file.
This time, the stderr.log showed:
Error: Debug Info:
__dirname: /home/yourserver/yourdirectory
process.cwd(): /home/yourserver/yourdirectory
NODE_PATH: /home/yourserver/nodevenv/yourdirectory/20/lib/node_modules:/opt/alt/alt-nodejs20/root/lib/node_modules:/opt/alt/alt-nodejs20/root/lib64/node_modules:
PATH: /home/yourserver/nodevenv/yourdirectory/20/bin:/opt/alt/alt-nodejs20/root/usr/bin:/home/yourserver/nodevenv/yourdirectory/20/lib/bin/:/usr/local/bin:/bin:/usr/bin
Sharp status: Loaded. Version: 0.32.6
Sharp location: Sharp. Location: /home/yourserver/nodevenv/yourdirectory/20/lib/node_modules/sharp/lib/index.js
Yeyy! sharp was loading correctly. But, after removing the debug code from server.js, the original error came back:
⨯ Error: 'sharp' is required to be installed in standalone mode for image optimization to function correctly. Read more at: https://nextjs.org/docs/messages/sharp-missing-in-production
The fix:
For some reason, Next.js couldn’t locate sharp. To resolve this, I set the NEXT_SHARP_PATH
environment variable to explicitly point to the location of sharp:
NEXT_SHARP_PATH=/home/yourserver/nodevenv/yourdirectory/20/lib/node_modules/sharp/lib
After saving and repeating the restart process, everything finally worked. The images were properly minified and transformed, just as expected.
Top comments (0)