386 lines
8.9 KiB
Markdown
386 lines
8.9 KiB
Markdown
# Deployment Guide — boha-app-ts (Ubuntu Server)
|
|
|
|
Migration from PHP boha-app to TypeScript boha-app-ts on the same Ubuntu server.
|
|
Both apps share the same MySQL database. The PHP app stays running during migration.
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
- Ubuntu server with the PHP boha-app already running
|
|
- nginx with SSL (Let's Encrypt) already configured
|
|
- MySQL database already running with production data
|
|
- NAS storage mounted (e.g., `/mnt/nas/02_PROJEKTY`)
|
|
- SSH access to the server
|
|
|
|
---
|
|
|
|
## Phase 1: Prepare on Dev Machine (Windows)
|
|
|
|
### 1.1 Create Prisma migration baseline
|
|
|
|
```bash
|
|
cd D:\cortex\boha-app-ts
|
|
mkdir -p prisma/migrations/0_init
|
|
npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
|
|
npx prisma migrate resolve --applied 0_init
|
|
git add prisma/migrations/
|
|
git commit -m "chore: create Prisma migration baseline"
|
|
```
|
|
|
|
### 1.2 Build the application
|
|
|
|
```bash
|
|
npm run build
|
|
```
|
|
|
|
This creates:
|
|
- `dist/` — compiled server (Node.js)
|
|
- `dist-client/` — compiled frontend (static files)
|
|
|
|
### 1.3 Generate new production secrets
|
|
|
|
```bash
|
|
openssl rand -hex 32
|
|
# Save this as JWT_SECRET
|
|
|
|
openssl rand -hex 32
|
|
# Save this as TOTP_ENCRYPTION_KEY (only if you want a new key)
|
|
```
|
|
|
|
### 1.4 Test the production build locally (optional)
|
|
|
|
```bash
|
|
APP_ENV=production JWT_SECRET=<your-dev-key> TOTP_ENCRYPTION_KEY=<your-dev-key> DATABASE_URL=<your-dev-db> node dist/server.js
|
|
```
|
|
|
|
Verify it starts and responds at `http://localhost:3001/api/health`.
|
|
|
|
---
|
|
|
|
## Phase 2: Prepare Ubuntu Server
|
|
|
|
### 2.1 Install Node.js 22
|
|
|
|
```bash
|
|
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
|
sudo apt-get install -y nodejs
|
|
node -v
|
|
npm -v
|
|
```
|
|
|
|
### 2.2 Install PM2
|
|
|
|
```bash
|
|
sudo npm install -g pm2
|
|
```
|
|
|
|
### 2.3 Create application directory
|
|
|
|
```bash
|
|
sudo mkdir -p /var/www/boha-app-ts
|
|
sudo chown $USER:$USER /var/www/boha-app-ts
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 3: Transfer Files to Server
|
|
|
|
### 3.1 Copy built files
|
|
|
|
From your Windows machine (Git Bash or PowerShell with SCP):
|
|
|
|
```bash
|
|
scp -r dist/ dist-client/ package.json package-lock.json prisma/ scripts/ .env.example user@server:/var/www/boha-app-ts/
|
|
```
|
|
|
|
Or use rsync if available:
|
|
|
|
```bash
|
|
rsync -avz --exclude node_modules --exclude .env dist/ dist-client/ package.json package-lock.json prisma/ scripts/ .env.example user@server:/var/www/boha-app-ts/
|
|
```
|
|
|
|
### 3.2 Install production dependencies on server
|
|
|
|
```bash
|
|
ssh user@server
|
|
cd /var/www/boha-app-ts
|
|
npm install --production
|
|
npx prisma generate
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 4: Configure Environment
|
|
|
|
### 4.1 Create production .env
|
|
|
|
```bash
|
|
cd /var/www/boha-app-ts
|
|
cp .env.example .env
|
|
nano .env
|
|
```
|
|
|
|
Fill in:
|
|
|
|
```env
|
|
# Database — same as the PHP app
|
|
DATABASE_URL=mysql://user:password@localhost:3306/your_db_name
|
|
|
|
# Server
|
|
PORT=3001
|
|
HOST=127.0.0.1
|
|
APP_ENV=production
|
|
|
|
# Auth — use the NEW secrets generated in step 1.3
|
|
JWT_SECRET=<paste-new-jwt-secret>
|
|
ACCESS_TOKEN_EXPIRY=900
|
|
REFRESH_TOKEN_SESSION_EXPIRY=3600
|
|
REFRESH_TOKEN_REMEMBER_EXPIRY=2592000
|
|
|
|
# TOTP — use SAME key as PHP app (unless you want to re-encrypt)
|
|
TOTP_ENCRYPTION_KEY=<same-key-as-php-app>
|
|
|
|
# NAS — Linux mount point
|
|
NAS_PATH=/mnt/nas/02_PROJEKTY
|
|
MAX_UPLOAD_SIZE=52428800
|
|
|
|
# Email
|
|
CONTACT_EMAIL_TO=manager@boha-automation.cz
|
|
CONTACT_EMAIL_FROM=web@boha-automation.cz
|
|
SMTP_FROM=noreply@boha-automation.cz
|
|
|
|
# CORS — your production domain(s)
|
|
CORS_ORIGINS=https://app.boha-automation.cz,https://www.boha-automation.cz
|
|
```
|
|
|
|
**Important decisions:**
|
|
|
|
| Setting | Recommendation |
|
|
|---------|---------------|
|
|
| `JWT_SECRET` | **New key.** All PHP sessions will be invalid — users re-login. This is expected. |
|
|
| `TOTP_ENCRYPTION_KEY` | **Same key as PHP app.** Avoids re-encrypting all TOTP secrets. |
|
|
| `DATABASE_URL` | **Same database as PHP app.** Both apps share it. |
|
|
| `NAS_PATH` | **Linux mount point** instead of Windows drive letter. |
|
|
|
|
---
|
|
|
|
## Phase 5: Database Setup
|
|
|
|
### 5.1 Mark Prisma baseline as applied
|
|
|
|
```bash
|
|
cd /var/www/boha-app-ts
|
|
npx prisma migrate resolve --applied 0_init
|
|
```
|
|
|
|
This tells Prisma the database already has all tables. No SQL is executed.
|
|
|
|
### 5.2 Verify database connection
|
|
|
|
```bash
|
|
npx prisma db pull --print | head -20
|
|
```
|
|
|
|
Should show your existing tables.
|
|
|
|
---
|
|
|
|
## Phase 6: TOTP Key Rotation (only if using new encryption key)
|
|
|
|
**Skip this section if you're using the same `TOTP_ENCRYPTION_KEY` as the PHP app.**
|
|
|
|
If you generated a new encryption key:
|
|
|
|
```bash
|
|
cd /var/www/boha-app-ts
|
|
|
|
# Dry run — verify all secrets can be decrypted and re-encrypted
|
|
npx tsx scripts/rotate-totp-key.ts <old-key> <new-key> --dry-run
|
|
|
|
# If all [OK], run for real
|
|
npx tsx scripts/rotate-totp-key.ts <old-key> <new-key>
|
|
```
|
|
|
|
After this, the PHP app's TOTP verification will break (secrets are now encrypted with the new key). Only do this when you're ready to cut over.
|
|
|
|
---
|
|
|
|
## Phase 7: Start Application with PM2
|
|
|
|
### 7.1 Create PM2 config
|
|
|
|
```bash
|
|
cd /var/www/boha-app-ts
|
|
cat > ecosystem.config.js << 'EOF'
|
|
module.exports = {
|
|
apps: [{
|
|
name: 'boha-app-ts',
|
|
script: 'dist/server.js',
|
|
cwd: '/var/www/boha-app-ts',
|
|
instances: 1,
|
|
env: {
|
|
NODE_ENV: 'production',
|
|
},
|
|
}]
|
|
};
|
|
EOF
|
|
```
|
|
|
|
### 7.2 Start the app
|
|
|
|
```bash
|
|
pm2 start ecosystem.config.js
|
|
pm2 save
|
|
pm2 startup
|
|
# Follow the printed command to enable auto-start on boot
|
|
```
|
|
|
|
### 7.3 Verify
|
|
|
|
```bash
|
|
pm2 status
|
|
pm2 logs boha-app-ts --lines 20
|
|
curl http://localhost:3001/api/health
|
|
```
|
|
|
|
Expected: `{"status":"ok","timestamp":"..."}`
|
|
|
|
---
|
|
|
|
## Phase 8: Nginx Configuration
|
|
|
|
### 8.1 Create nginx config
|
|
|
|
```bash
|
|
sudo nano /etc/nginx/sites-available/boha-app-ts
|
|
```
|
|
|
|
Paste:
|
|
|
|
```nginx
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name app.boha-automation.cz;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/app.boha-automation.cz/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/app.boha-automation.cz/privkey.pem;
|
|
|
|
client_max_body_size 55M;
|
|
|
|
location / {
|
|
proxy_pass http://127.0.0.1:3001;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection 'upgrade';
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_cache_bypass $http_upgrade;
|
|
}
|
|
}
|
|
|
|
server {
|
|
listen 80;
|
|
server_name app.boha-automation.cz;
|
|
return 301 https://$host$request_uri;
|
|
}
|
|
```
|
|
|
|
Adjust `server_name` and SSL paths to match your setup.
|
|
|
|
### 8.2 Enable and reload
|
|
|
|
```bash
|
|
sudo ln -s /etc/nginx/sites-available/boha-app-ts /etc/nginx/sites-enabled/
|
|
sudo nginx -t
|
|
sudo systemctl reload nginx
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 9: Testing
|
|
|
|
### 9.1 Verify in browser
|
|
|
|
Open `https://app.boha-automation.cz` and test:
|
|
|
|
- [ ] Login page loads
|
|
- [ ] Login works (users will need to re-login due to new JWT_SECRET)
|
|
- [ ] TOTP verification works (if using same encryption key)
|
|
- [ ] Dashboard loads with data
|
|
- [ ] Offers — list, create, edit, PDF export
|
|
- [ ] Orders — list, create from offer, status transitions
|
|
- [ ] Invoices — list, create, PDF with QR code
|
|
- [ ] Projects — list, create, file manager (upload/download)
|
|
- [ ] Attendance — clock in/out, admin view, print
|
|
- [ ] Trips — list, history
|
|
- [ ] Settings — company settings, users, roles
|
|
|
|
### 9.2 Check logs for errors
|
|
|
|
```bash
|
|
pm2 logs boha-app-ts --lines 50
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 10: Cutover Strategy
|
|
|
|
Both apps run simultaneously on the same database. Recommended approach:
|
|
|
|
1. **Week 1:** Run both apps. Use the TS app for daily work. Fall back to PHP if issues arise.
|
|
2. **Week 2:** If stable, redirect the main domain to the TS app.
|
|
3. **Week 3:** Stop the PHP app.
|
|
|
|
To redirect the PHP domain to the TS app, update the nginx config for the PHP domain to proxy to port 3001 instead.
|
|
|
|
---
|
|
|
|
## Future Updates
|
|
|
|
When you push code changes:
|
|
|
|
```bash
|
|
# On dev machine
|
|
npm run build
|
|
git push
|
|
|
|
# On server
|
|
cd /var/www/boha-app-ts
|
|
git pull
|
|
npm install --production
|
|
npx prisma generate
|
|
npx prisma migrate deploy # runs any new migrations
|
|
pm2 restart boha-app-ts
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
| Problem | Solution |
|
|
|---------|----------|
|
|
| `EADDRINUSE: port 3001` | `pm2 stop boha-app-ts` then `pm2 start` |
|
|
| Prisma connection error | Check `DATABASE_URL` in `.env` |
|
|
| TOTP verification fails | Verify `TOTP_ENCRYPTION_KEY` matches the key used to encrypt secrets |
|
|
| NAS files not accessible | Check mount: `ls /mnt/nas/02_PROJEKTY`, verify permissions |
|
|
| 502 Bad Gateway | App not running: `pm2 status`, check logs: `pm2 logs` |
|
|
| CSS/JS not loading | Verify `dist-client/` was copied, check `APP_ENV=production` |
|
|
| CORS errors | Check `CORS_ORIGINS` in `.env` matches your domain exactly |
|
|
|
|
---
|
|
|
|
## Quick Reference
|
|
|
|
| Command | Purpose |
|
|
|---------|---------|
|
|
| `pm2 start ecosystem.config.js` | Start the app |
|
|
| `pm2 restart boha-app-ts` | Restart after update |
|
|
| `pm2 stop boha-app-ts` | Stop the app |
|
|
| `pm2 logs boha-app-ts` | View logs |
|
|
| `pm2 monit` | Live monitoring |
|
|
| `npx prisma migrate deploy` | Apply database migrations |
|
|
| `npx prisma studio` | Database GUI (dev only) |
|