Next.js应用首次部署与重新部署最佳方案及更新不生效问题排查
Background
You've developed a Next.js sample app, completed deployment with npm run build, and are following the custom server guide. Here's your current setup (with a critical fix noted):
- Created
server.jsin the root of thebuilddirectory - Updated
package.jsonscripts:"scripts": { "dev": "node server.js", "build": "next build", "start": "NODE_ENV=production node server.js" } - Corrected
next.config.js: You originally had two separatemodule.exportsblocks (the second would overwrite the first). Here's the merged, functional version:const path = require("path"); module.exports = { reactStrictMode: true, distDir: "build", sassOptions: { includePaths: [path.join(__dirname, "styles")], }, env: { DOM: process.env.DOM, SERDOM: process.env.SERDOM, PAPI: process.env.PAPI, UAPI: process.env.UAPI, PAEXIST: process.env.PAEXIST, USEREXIST: process.env.USEREXIST }, }; - Original
package.json:{ "name": "New demo", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "bootstrap": "^5.0.2", "next": "11.0.1", "node-sass": "^4.14.1", "react": "17.0.2", "react-bootstrap": "^1.6.1", "react-dom": "17.0.2", "react-icons": "^4.2.0" }, "devDependencies": { "eslint": "7.29.0", "eslint-config-next": "11.0.1" }, "proxy": "http://localhost:3008" }
1. Do I need to specify the path to server.js when using pm2?
Yes, you’ll need to specify the path unless you’re running the pm2 command directly from the build directory where server.js lives.
Here’s how to handle it:
- If you’re in your project’s root folder, start pm2 with:
pm2 start ./build/server.js --name "next-custom-server" - If you first
cd build, you can simplify to:pm2 start server.js --name "next-custom-server"
Also, double-check that your server.js is configured to listen on port 3000 (and your Next.js app uses 3001) to avoid port conflicts. Use pm2 list to verify running processes and their ports.
2. After re-running npm run build, the online app doesn't show new changes—cache or other issues? How to let users see updates?
This almost always boils down to two common issues:
a. The old server process is still running
pm2 keeps the existing server.js process alive, which means it’s still serving the old build files. Restart the process to load the new build:
# Restart by name pm2 restart next-custom-server # Or by process ID (find it with pm2 list) pm2 restart <process-id>
For zero-downtime updates, use pm2 reload next-custom-server instead—it spins up a new instance before shutting down the old one.
b. Caching problems
- Browser cache: Next.js automatically adds content hashes to static asset filenames (like
main.[unique-hash].js) so new assets have unique URLs. If users still see old content, ask them to do a force refresh (Ctrl+Shift+Ron Windows/Linux,Cmd+Shift+Ron Mac). - Server/proxy cache: If you’re using Nginx or another reverse proxy, make sure it’s configured to not cache dynamic Next.js routes, and to cache hashed static assets with long expiry headers (e.g.,
Cache-Control: public, max-age=31536000, immutable).
Also, verify that npm run build completed without errors—sometimes failed builds leave the old build intact, so no changes get deployed.
3. Best practices for initial deployment and subsequent updates of a Next.js app?
Initial Deployment
- Validate configuration: Fix any conflicting settings (like the duplicated
module.exportsinnext.config.js) before deploying. - Environment variables: Ensure all production env vars are set (via
.env.productionor server environment variables) so your app can access values likeDOMorPAPI. - Process management: Use pm2 (or systemd) to keep your server running in the background, auto-restart on crashes, and monitor logs.
- Reverse proxy: Set up Nginx or Apache to handle HTTPS, route traffic to your Next.js server (port 3000), and manage static asset caching.
- Pre-deployment testing: Run
npm run buildlocally, then start the production server withnpm run startto catch issues before pushing to production.
Subsequent Updates
- Automate with CI/CD: Use tools like GitHub Actions or GitLab CI to automatically pull code, install dependencies, run tests/linting, build, and deploy—this reduces human error.
- Zero-downtime deployments: Use
pm2 reloadinstead of restart, or implement blue-green deployment (run two app instances, switch traffic to the new one once it’s healthy). - Post-deployment checks: Verify the update with
pm2 logs next-custom-serverto ensure no errors, and manually test key app features to confirm changes are live. - Clean up old builds: Periodically delete outdated build files to save space, but only after confirming the new build is stable.
内容的提问来源于stack exchange,提问作者tekf

