Landing page + admin + API built with Node.js (server.js) and static HTML/CSS/JS.
- Node.js HTTP server (CommonJS)
- SQLite (
brain.db) by default vianode:sqlite - Optional Postgres (
DATABASE_URL) via@neondatabase/serverless - Email sending via Resend REST API
- Copy sample env:
cp .env.example .env
- Install deps:
npm install
- Build admin assets:
npm run build
- Run server:
node server.js
Default URL: http://localhost:3000
- Prepare server
- Install Node.js
>=22 - Install Nginx
- Install Node.js
- Pull code and install
git pull origin mainnpm installnpm run build
- Create production env file
cp .env.example .env.production- Fill real values in
.env.production
- Set up systemd
- Copy
deploy/systemd/landing-page.serviceto/etc/systemd/system/ - Update
WorkingDirectory,EnvironmentFile,User, and Node path if needed - Run:
sudo systemctl daemon-reloadsudo systemctl enable landing-pagesudo systemctl start landing-page
- Copy
- Set up Nginx
- Copy
deploy/nginx/landing-page.confto/etc/nginx/sites-available/landing-page - Replace domain and upstream port if needed
- Enable config + reload nginx
- Copy
- Set up cron for email sequence
- Use
deploy/cron/email-sequence-cron.sh - Example crontab (daily 09:00 UTC):
0 9 * * * CRON_SECRET=... BASE_URL=https://your-domain.com /var/www/landing-page/deploy/cron/email-sequence-cron.sh
- Use
SSH into the server, then:
bash /var/www/landing-page/scripts/vps-deploy.shOr manually: git pull origin main, npm install, npm run build, sudo systemctl restart landing-page.
Verify: open https://your-domain.com/api/store-info — should include "buildId":"2026-05-29-main". Homepage nav should show Giới thiệu Học viên.
If the public site still shows the old hero (“Nhận Bằng Cao Học”), the VPS is not running this repo’s latest code (wrong folder, old node process, or pull was run on your PC instead of the server).
- Never commit
.env,.env.*, orresend_config.txt - Rotate any previously exposed keys immediately
- Keep secrets only in server env / secret manager