9.8 KiB
AgMission Deployment Guide
Last updated: April 2026
Table of Contents
- 1 Prerequisites
- 2 Repository and Directory Layout
- 3 Deployment Script Reference
- 4 Configuration
- 5 Deployment Modes
- 6 Step-by-Step Production Deployment
- 7 PM2 Process Management
- 8 Backup and Recovery
- 9 Environment Variables Reference
1 Prerequisites
Developer machine (deploying from):
- SSH access to the production server on port
22222 rsyncinstalled- SVN working copy at
~/work/AgMission - AGN private libraries at
~/work/@agn - Angular CLI for frontend builds (
npm install -g @angular/cli)
Production server:
- Node.js 16.20.2 LTS
- PM2 (global):
npm install -g pm2 - MongoDB 4.4.x replica set (
rs0) - RabbitMQ 3.10.7+
- Redis
- Nginx 1.10.x+
2 Repository and Directory Layout
Local developer machine
~/work/AgMission/
├── trunk/Development/ ← main line source
├── branches/<branch-name>/ ← feature branches
└── tags/release-x.y.z/ ← release snapshots
~/work/@agn/ ← private AGN Node.js libraries
Remote production server
/home/agm/apps/
├── agmission/ ← API server (server/)
├── client/dist/ ← Angular build output
├── gps-server/
├── track-server/
├── satloc/
├── maintainer/
├── pm2-apps/ ← PM2 JSON configs
└── @agn/ ← private libs (rsync'd from ~/work/@agn)
3 Deployment Script Reference
Script: trunk/Others/scripts/deploy/agm-deploy.sh
Usage
./agm-deploy.sh [run_mode] [branch_name] [fe_mode]
| Argument | Values | Default | Description |
|---|---|---|---|
run_mode |
0, 1, 2 |
0 |
Deployment scope (see table below) |
branch_name |
trunk, main, or branch name |
subscription-invoicing |
Source to deploy from |
fe_mode |
run, dry-run |
run |
Frontend deploy behaviour (mode 2 only) |
run_mode |
Backend | Frontend | Use case |
|---|---|---|---|
0 (or empty) |
Dry run | Dry run | Verify what would be synced |
1 |
Deploy | Skipped | Backend-only update |
2 |
Deploy | Deploy | Full production deployment |
Configuration file recommended
# 1. Copy template
cp trunk/Others/scripts/deploy/agm-deploy.conf.template ~/.agm-deploy.conf
# 2. Edit values
nano ~/.agm-deploy.conf
# 3. Use it
source ~/.agm-deploy.conf && ./agm-deploy.sh 1 trunk
Environment variable overrides
| Variable | Default | Description |
|---|---|---|
AGM_BASE_DIR |
~/work/AgMission |
Local AgMission SVN root |
AGN_LIBS_DIR |
~/work/@agn |
Local AGN private libraries |
AGM_DEST_HOST |
agm@agmission-1.agnav.com |
SSH target (user@host) |
AGM_DEST_PORT |
22222 |
SSH port |
AGM_DEST_PATH |
/home/agm/apps |
Remote base directory |
4 Configuration
Excluded files
trunk/Others/scripts/deploy/excludes.txt lists paths excluded from rsync. These typically include:
node_modules/.env/environment*.env(never overwrite production secrets).tmp/,job-unzip/,job-uploads/- Log files and rlog crash reports
Production environment files
Environment files are not deployed by the script. They must be maintained manually on the production server. See 9 Environment Variables Reference for key variables.
5 Deployment Modes
Dry run mode 0
./agm-deploy.sh 0 trunk
Shows all files that would be synced without touching the server. Always run this first when deploying after a significant code change.
Backend only mode 1
./agm-deploy.sh 1 trunk
Deploys:
server/→/home/agm/apps/agmission/gps-server/→/home/agm/apps/gps-server/track-server/→/home/agm/apps/track-server/shared/→/home/agm/apps/shared/@agnlibraries →/home/agm/apps/@agn/
After sync, run pm2 reload on the server (see 7 PM2 Process Management).
Full deployment mode 2
./agm-deploy.sh 2 trunk
Deploys everything in mode 1, plus the Angular frontend client/dist/ to the Nginx webroot.
Before running mode 2, build the frontend locally:
cd trunk/Development/client
npm install
npm run build-prod # builds all locales: en, pt, es
6 Step-by-Step Production Deployment
graph TD
A["1. Update SVN working copy<br/>svn update trunk/"] --> B["2. Run tests<br/>cd server && npm test"]
B --> C["3. Build frontend<br/>cd client && npm run build-prod"]
C --> D["4. Dry run<br/>./agm-deploy.sh 0 trunk"]
D --> E{"Review OK?"}
E -- No --> F["Fix issues"]
F --> D
E -- Yes --> G["5. Deploy backend<br/>./agm-deploy.sh 1 trunk"]
G --> H["6. SSH to server<br/>ssh agm@agmission-1.agnav.com -p 22222"]
H --> I["7. Install dependencies<br/>cd /home/agm/apps/agmission && npm install --production"]
I --> J["8. Reload PM2<br/>pm2 reload agmission-prod"]
J --> K["9. Check logs<br/>pm2 logs agmission-prod --lines 50"]
K --> L{"Errors?"}
L -- Yes --> M["Rollback: pm2 reload with previous snapshot"]
L -- No --> N["10. Deploy frontend (if needed)<br/>./agm-deploy.sh 2 trunk"]
Post-deployment checklist
pm2 status— all processes showonlinepm2 logs agmission-prod --lines 20— no crash errors- Health check endpoint:
curl https://agmission-1.agnav.com/api/health - Login to the web UI and confirm dashboard loads
- If partner workers were updated:
pm2 reload partner_sync_worker partner_data_polling_worker - If worker code changed: check
pm2 logs job_worker --lines 20
7 PM2 Process Management
Start all services first time
# SSH into server
ssh agm@agmission-1.agnav.com -p 22222
# Start all configured apps
/home/agm/apps/pm2-apps/start_pm2_apps.sh
Reload after deployment
# Reload individual app (zero-downtime)
pm2 reload agmission-prod
# Reload all at once
pm2 reload all
# Check status
pm2 status
pm2 logs agmission-prod --lines 30
Process list
pm2 list
Expected processes:
| Name | Status |
|---|---|
agmission-prod |
online |
track_server |
online |
gps_server-agnav |
online |
gps_server-rap |
online |
job_worker |
online |
invoice_worker |
online |
cleanup_worker |
online |
partner_sync_worker |
online |
partner_data_polling_worker |
online |
Restart a single worker
pm2 restart job_worker
pm2 restart partner_sync_worker
pm2 restart invoice_worker
Save current PM2 process list
pm2 save
8 Backup and Recovery
Automated backup
trunk/Others/scripts/backup_agm.sh runs via cron. It:
- Dumps MongoDB to a gzip archive (
mongodump --gzip) - Retains 11 days of database archives
- Syncs archives to NAS via
rsync(rsync://rsync@data.agnav.com/agm/) - Syncs uploaded job files separately
- Syncs rsync log files
Manual MongoDB backup
mongodump \
--archive=/home/agm/backups/manual_$(date +%Y%m%d).gz \
--gzip \
--db agmission \
--username agm \
--authenticationDatabase agmission
Restore from backup
mongorestore \
--archive=/home/agm/backups/agmdb_YYYYMMDD.gz \
--gzip \
--db agmission \
--username agm \
--authenticationDatabase agmission \
--drop
9 Environment Variables Reference
Environment files live on the production server at /home/agm/apps/agmission/environment.env and are not managed by the deployment script.
Core server
| Variable | Description |
|---|---|
AGM_PORT |
HTTP port the API server listens on (e.g., 7000) |
PRODUCTION |
true in production |
DB_USR / DB_PWD / DB_NAME |
MongoDB credentials |
DB_HOSTS |
MongoDB host list (replica set) |
DB_REPLSET |
Replica set name (rs0) |
REDIS_PWD |
Redis password |
JWT_SECRET |
JWT signing secret |
MAX_SESSION_SECS |
Session token lifetime (default: 28800) |
Stripe billing
| Variable | Description |
|---|---|
STRIPE_SECRET_KEY |
Stripe secret key |
STRIPE_PUBLISHABLE_KEY |
Stripe publishable key |
STRIPE_API_VERSION |
Stripe API version |
STRIPE_WH_SEC |
Stripe webhook signing secret |
ESS_1 … ESS_5 |
Stripe price IDs for Essential plans |
ENT_1 … ENT_4 |
Stripe price IDs for Enterprise plans |
ADDON_1 |
Stripe price ID for add-on |
File storage
| Variable | Description |
|---|---|
UPLOAD_DIR |
Job upload directory |
UNZIP_DIR |
Temp extraction directory |
INV_UPLOAD_DIR |
Invoice image upload directory |
INV_IMG_VIR_DIR |
Virtual URL path for invoice images |
SATLOC_STORAGE_PATH |
Local storage for downloaded SatLoc log files |
RabbitMQ
| Variable | Description |
|---|---|
QUEUE_HOST |
RabbitMQ host |
QUEUE_PORT |
RabbitMQ port (default: 5672) |
QUEUE_USR / QUEUE_PWD |
RabbitMQ credentials |
QUEUE_VHOST |
Virtual host |
QUEUE_NAME_JOBS |
Job processing queue name |
QUEUE_NAME_GDATA |
GPS data queue name |
QUEUE_NAME_PARTNER |
Partner tasks queue name |
Partner integration
| Variable | Description |
|---|---|
SATLOC_API_ENDPOINT |
SatLoc Cloud base URL |
SATLOC_API_TIMEOUT |
HTTP request timeout (ms) |
PARTNER_SYNC_INTERVAL |
Partner sync interval (ms) |
PARTNER_HEALTH_CHECK_INTERVAL |
Health check interval (ms) |
PARTNER_MAX_RETRIES |
Max retry attempts before DLQ |
DLQ_CHECK_INTERVAL |
DLQ monitoring interval (ms) |
See ARCHITECTURE.md for full system design documentation.