Documentation Index
Fetch the complete documentation index at: https://mintlify.com/HNU-himematsu/HNU-TimeLetter/llms.txt
Use this file to discover all available pages before exploring further.
HNU-TimeLetter supports two deployment models. Vercel is the simplest path for preview branches and visual review; it uses the JSON artifacts committed to the repo as build-time data. Self-hosted with PM2 is required for production use because node-schedule (the sync scheduler) needs a persistent process — serverless runtimes restart between invocations and cannot maintain scheduled jobs.
Vercel Deployment
Vercel is ideal for preview deployments on feature branches. The build process syncs Feishu data at build time, so the deployed site always contains the data available at the moment of the build.Connect the GitHub repository
Import the repository in the Vercel dashboard. Vercel auto-detects Next.js and sets the correct framework preset. Set environment variables
In Settings → Environment Variables, add every variable from .env.example. At minimum you need:FEISHU_APP_ID
FEISHU_APP_SECRET
FEISHU_APP_TOKEN
FEISHU_TABLE_ID
FEISHU_VIEW_ID
ALIYUN_OSS_REGION
ALIYUN_OSS_BUCKET
ALIYUN_OSS_ACCESS_KEY_ID
ALIYUN_OSS_ACCESS_KEY_SECRET
ADMIN_PASSWORD
ADMIN_SESSION_SECRET
ADMIN_SESSION_SECRET must be at least 32 random bytes in production. Generate one with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))".
Configure the build command
Set the Build Command to:This runs npm run sync (pulls Feishu data) followed by npm run build. The JSON artifacts are embedded into the build output.Alternatively, use the default npm run build if you want to rely on the JSON files already committed to the repo as fallback data. Deploy
Push to any branch. Vercel builds and deploys automatically. The live URL is shown in the deployment dashboard.
Vercel Limitations
The node-schedule scheduler does not persist between Vercel serverless function invocations. Scheduled syncs will not fire on Vercel. Use the sync webhook with an external cron service (e.g. GitHub Actions scheduled workflow, cron-job.org) to trigger syncs on a schedule instead. Self-Hosted Deployment with PM2
Self-hosted deployment with PM2 supports the full feature set: persistent scheduler (node-schedule), real-time hot-update via the admin panel, and Feishu Automation webhook.Prerequisites
- Node.js ≥ 20
- PM2 installed globally:
npm install -g pm2
- A reverse proxy (nginx recommended) serving port 80/443 → Node port 3000
PM2 Configuration
The repo includes ecosystem.config.js:module.exports = {
apps: [
{
name: 'web',
script: './node_modules/.bin/next',
args: 'start',
instances: 1,
exec_mode: 'fork',
autorestart: true,
watch: false,
max_memory_restart: '512M',
out_file: './logs/pm2/out.log',
error_file: './logs/pm2/error.log',
merge_logs: true,
env_production: {
NODE_ENV: 'production',
PORT: 3000,
// All other env vars loaded from .env.production at startup
},
},
],
};
Manual Deploy Steps
Clone the repository on the server
git clone https://github.com/HNU-himematsu/HNU-TimeLetter.git /var/www/web
cd /var/www/web
npm ci
Create .env.production
Create /var/www/web/.env.production with all required environment variables. Next.js loads this file automatically when NODE_ENV=production.Never commit .env.production to version control. Add it to .gitignore.
Build with Feishu sync
This runs npm run sync then npm run build. The build embeds the synced JSON data. Start with PM2
pm2 start ecosystem.config.js --env production
pm2 save
pm2 startup # enable autostart on server reboot
Common PM2 commands:pm2 show web # process details
pm2 logs web # tail logs
pm2 reload web --update-env # zero-downtime reload after code update
pm2 stop web # stop the process
GitHub Actions CI/CD
The included .github/workflows/deploy.yml automates the full pipeline on every push to the release branch:
- Checkout + setup Node 20
- Quality gates:
npm run lint, npm run typecheck, npm audit --omit=dev
- Build:
npm run publish (= npm run sync && npm run build)
- Deploy: Pack build artifacts, upload to Aliyun OSS, then SSH into the server to pull from OSS and run
pm2 reload web --update-env
Required GitHub Secrets (Settings → Secrets and Variables → Actions):| Secret | Purpose |
|---|
FEISHU_APP_ID | Feishu app credentials |
FEISHU_APP_SECRET | Feishu app credentials |
FEISHU_APP_TOKEN | Bitable app token |
FEISHU_TABLE_ID | Stories table ID |
FEISHU_VIEW_ID | Stories view ID |
ALIYUN_OSS_REGION | OSS region |
ALIYUN_OSS_BUCKET | OSS bucket name |
ALIYUN_OSS_ACCESS_KEY_ID | OSS credentials |
ALIYUN_OSS_ACCESS_KEY_SECRET | OSS credentials |
ADMIN_PASSWORD | Admin panel password |
ADMIN_SESSION_SECRET | ≥32-byte session secret |
SYNC_WEBHOOK_SECRET | Webhook auth token |
SERVER_SSH_KEY | SSH private key for deployment |
SERVER_HOST | Deployment server hostname |
SERVER_USERNAME | SSH username |
Optional Variables (Settings → Secrets and Variables → Variables):| Variable | Default |
|---|
SERVER_PORT | 22 |
DEPLOY_PATH | /var/www/web |
PM2_APP_NAME | web |
Hot-Update After Admin Sync
On the self-hosted model, the admin panel can trigger a Feishu sync that writes new JSON artifacts to src/data/. The frontend reads these via the runtime APIs (/api/content, /api/creation-board, /api/contributors) — no rebuild or restart needed. The next page load picks up the new data automatically.
Build Verification Commands
Before every production deployment, run these checks:
npm run lint # ESLint
npm run typecheck # tsc --noEmit
npm audit --omit=dev # Security audit (production deps only)
npm run build # Full Next.js production build