Release-based SSH deployment for Next.js apps with symlinks, dependency caching, and PM2 management
npm install @philiprehberger/next-deployRelease-based SSH deployment for Next.js apps with symlinks, dependency caching, and PM2 management
npm install @philiprehberger/next-deploy
/var/www/myapp/
├── releases/
│ ├── 20251212112502/
│ ├── 20251213093015/
│ └── ..
├── current -> releases/20251213093015/
└── shared/
└── .env
npx next-deploy
npx next-deploy --skip-build
npx next-deploy --fresh
npx next-deploy --dry-run
npx next-deploy --keep 10 # override releasesToKeep at runtime
npx next-deploy rollback # switch to the previous release and restart
deploy.config.js)module.exports = {
server: {
host: 'example.com',
username: 'deploy',
privateKeyPath: '~/.ssh/id_rsa',
},
paths: {
basePath: '/var/www/myapp',
},
pm2Process: 'myapp',
filesToTransfer: ['.next', 'public', 'package.json', 'package-lock.json', 'next.config.mjs'],
releasesToKeep: 5,
};
SERVER_HOST=example.com
SERVER_USERNAME=deploy
SERVER_PRIVATE_KEY=~/.ssh/id_rsa
SERVER_BASE_PATH=/var/www/myapp
SERVER_PM2_PROCESS=myapp
RELEASES_TO_KEEP=5
import { deploy, loadConfigFromEnv } from '@philiprehberger/next-deploy';
const config = loadConfigFromEnv({
hooks: {
postDeploy: (releaseName) => {
console.log(`Deployed ${releaseName}!`);
},
},
});
const result = await deploy(config, { skipBuild: false });
console.log(result.success ? 'Done!' : `Failed: ${result.error}`);
| Method | Description |
|---|---|
deploy(config, options?) | Run a full deployment with the given config and options |
rollback(config) | Switch the current symlink to the previous release and restart PM2 |
loadConfig(projectRoot) | Load deploy config from a config file in the project root |
loadConfigFromEnv(overrides?) | Load deploy config from environment variables with optional overrides |
npm install
npm run build
npm test
If you find this project useful: