Skip to content

Commit cbe207a

Browse files
committed
release: v1.3.0 - config ejection, observability, rich status dashboard
- Add 'shipnode eject' for customizable PM2/Caddy templates with {{VAR}} placeholders - Add 'shipnode metrics' for real-time PM2 monitoring over SSH - Add 'shipnode config show|validate|path' for config inspection - Rewrite 'shipnode status' with rich dashboard (PM2 stats, uptime, CPU, memory, disk, releases) - Track deployment metadata: duration, git commit, health check timing in releases.json - Enhanced health checks with response time tracking - Default Caddy configs include security headers and JSON logging - Complete README rewrite with 'How It Works' section - Update ARCHITECTURE.md with all new modules - Bump version to 1.3.0
1 parent 3573a7b commit cbe207a

19 files changed

Lines changed: 1710 additions & 1236 deletions

ARCHITECTURE.md

Lines changed: 96 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,77 +12,104 @@ ShipNode is organized as a modular bash project to improve maintainability, test
1212
shipnode/
1313
├── shipnode # Main entry point (sources all modules)
1414
├── lib/
15-
│ ├── core.sh # Core utilities and globals
16-
│ ├── release.sh # Release management
15+
│ ├── core.sh # Core utilities, globals, template rendering
16+
│ ├── pkg-manager.sh # Package manager detection + PM2 template generation
17+
│ ├── release.sh # Release management with metadata tracking
1718
│ ├── database.sh # Database operations
1819
│ ├── users.sh # User provisioning helpers
1920
│ ├── framework.sh # Framework detection
2021
│ ├── validation.sh # Input validation
2122
│ ├── prompts.sh # Interactive prompts + Gum UI
23+
│ ├── templates.sh # Framework preset configurations
2224
│ └── commands/ # Command implementations
2325
│ ├── config.sh # Configuration loading
2426
│ ├── users-yaml.sh # Users.yml generation
2527
│ ├── user.sh # User management commands
2628
│ ├── mkpasswd.sh # Password generation
2729
│ ├── init.sh # Initialize command
2830
│ ├── setup.sh # Setup command
29-
│ ├── deploy.sh # Deploy command
30-
│ ├── status.sh # Status management
31+
│ ├── deploy.sh # Deploy command (template-aware)
32+
│ ├── doctor.sh # Diagnostics command
33+
│ ├── status.sh # Rich status dashboard
3134
│ ├── unlock.sh # Unlock command
3235
│ ├── rollback.sh # Rollback command
3336
│ ├── migrate.sh # Migrate command
3437
│ ├── env.sh # Environment upload
38+
│ ├── eject.sh # Eject PM2/Caddy templates
39+
│ ├── metrics.sh # PM2 resource monitoring
40+
│ ├── config-cmd.sh # Config show/validate/path
41+
│ ├── upgrade.sh # Upgrade command
42+
│ ├── ci.sh # CI/CD commands
43+
│ ├── harden.sh # Security hardening
3544
│ ├── help.sh # Help command
3645
│ └── main.sh # Main dispatcher
37-
└── build.sh # Build script for distribution
46+
├── templates/ # Ejectable template files
47+
│ ├── ecosystem.config.cjs.tmpl # PM2 config template
48+
│ ├── Caddyfile.backend.tmpl # Backend Caddy template
49+
│ ├── Caddyfile.frontend.tmpl # Frontend Caddy template
50+
│ ├── pre-deploy.sh.template # Pre-deploy hook template
51+
│ └── post-deploy.sh.template # Post-deploy hook template
52+
├── build.sh # Build script for distribution
53+
└── examples/ # Example projects
3854
```
3955

4056
## Module Dependencies
4157

4258
Modules are loaded in a specific order to ensure dependencies are available:
4359

44-
1. **core.sh** - No dependencies, provides globals and utilities
45-
2. **release.sh** - Depends on core.sh
46-
3. **database.sh** - Depends on core.sh
47-
4. **users.sh** - Depends on core.sh
48-
5. **framework.sh** - Depends on core.sh
49-
6. **validation.sh** - Depends on core.sh
50-
7. **prompts.sh** - Depends on core.sh
51-
8. **commands/config.sh** - Depends on core.sh
52-
9. **commands/users-yaml.sh** - Depends on core.sh, validation.sh
53-
10. **commands/user.sh** - Depends on core.sh, users.sh, validation.sh
54-
11. **commands/mkpasswd.sh** - Depends on core.sh
55-
12. **commands/init.sh** - Depends on core.sh, framework.sh, validation.sh, prompts.sh
56-
13. **commands/setup.sh** - Depends on core.sh, release.sh, database.sh
57-
14. **commands/deploy.sh** - Depends on core.sh, release.sh
58-
15. **commands/status.sh** - Depends on core.sh
59-
16. **commands/unlock.sh** - Depends on core.sh, release.sh
60-
17. **commands/rollback.sh** - Depends on core.sh, release.sh
61-
18. **commands/migrate.sh** - Depends on core.sh, release.sh
62-
19. **commands/env.sh** - Depends on core.sh
63-
20. **commands/help.sh** - Depends on core.sh
64-
21. **commands/main.sh** - Depends on all other modules
60+
1. **core.sh** - No dependencies, provides globals, logging, template rendering
61+
2. **pkg-manager.sh** - Depends on core.sh
62+
3. **release.sh** - Depends on core.sh
63+
4. **database.sh** - Depends on core.sh
64+
5. **users.sh** - Depends on core.sh
65+
6. **framework.sh** - Depends on core.sh
66+
7. **validation.sh** - Depends on core.sh
67+
8. **prompts.sh** - Depends on core.sh
68+
9. **templates.sh** - Depends on core.sh
69+
10. **commands/config.sh** - Depends on core.sh
70+
11. **commands/users-yaml.sh** - Depends on core.sh, validation.sh
71+
12. **commands/user.sh** - Depends on core.sh, users.sh, validation.sh
72+
13. **commands/mkpasswd.sh** - Depends on core.sh
73+
14. **commands/init.sh** - Depends on core.sh, framework.sh, validation.sh, prompts.sh
74+
15. **commands/setup.sh** - Depends on core.sh, release.sh, database.sh
75+
16. **commands/deploy.sh** - Depends on core.sh, release.sh, pkg-manager.sh
76+
17. **commands/doctor.sh** - Depends on core.sh
77+
18. **commands/status.sh** - Depends on core.sh
78+
19. **commands/unlock.sh** - Depends on core.sh, release.sh
79+
20. **commands/rollback.sh** - Depends on core.sh, release.sh
80+
21. **commands/migrate.sh** - Depends on core.sh, release.sh
81+
22. **commands/env.sh** - Depends on core.sh
82+
23. **commands/eject.sh** - Depends on core.sh
83+
24. **commands/metrics.sh** - Depends on core.sh
84+
25. **commands/config-cmd.sh** - Depends on core.sh
85+
26. **commands/upgrade.sh** - Depends on core.sh
86+
27. **commands/ci.sh** - Depends on core.sh
87+
28. **commands/harden.sh** - Depends on core.sh
88+
29. **commands/help.sh** - Depends on core.sh
89+
30. **commands/main.sh** - Depends on all other modules
6590

6691
## Module Descriptions
6792

6893
### Core Modules
6994

70-
#### core.sh (164 lines)
71-
**Purpose:** Global variables, colors, logging functions, OS detection, Gum installation
95+
#### core.sh (240 lines)
96+
**Purpose:** Global variables, colors, logging functions, OS detection, Gum installation, template rendering
7297

7398
**Key Functions:**
7499
- `error()`, `success()`, `info()`, `warn()` - Logging functions
75100
- `has_gum()` - Check if Gum is installed
76101
- `detect_os()` - Detect OS and package manager
77102
- `install_gum()` - Install Gum UI framework
103+
- `render_template()` - Replace `{{VAR}}` placeholders in template files using sed
104+
- `resolve_template()` - Find user template (ejected or project-root) before falling back to built-in
78105

79106
**Globals:**
80107
- `RED`, `GREEN`, `YELLOW`, `BLUE`, `NC` - Color codes
81108
- `VERSION` - ShipNode version
82109
- `USE_GUM` - Enhanced UI flag
83110

84-
#### release.sh (124 lines)
85-
**Purpose:** Zero-downtime deployment release management
111+
#### release.sh (180 lines)
112+
**Purpose:** Zero-downtime deployment release management with deployment metadata tracking
86113

87114
**Key Functions:**
88115
- `generate_release_timestamp()` - Create unique release ID
@@ -91,8 +118,8 @@ Modules are loaded in a specific order to ensure dependencies are available:
91118
- `acquire_deploy_lock()` - Prevent concurrent deployments
92119
- `release_deploy_lock()` - Release deployment lock
93120
- `switch_symlink()` - Atomic symlink switching
94-
- `perform_health_check()` - Validate deployment health
95-
- `record_release()` - Track release history
121+
- `perform_health_check()` - Validate deployment health with timing metrics
122+
- `record_release()` - Track release history with duration, commit, health check data
96123
- `get_previous_release()` - Find previous release
97124
- `cleanup_old_releases()` - Remove old releases
98125
- `rollback_to_release()` - Rollback to specific release
@@ -200,26 +227,29 @@ Modules are loaded in a specific order to ensure dependencies are available:
200227
**Key Functions:**
201228
- `cmd_setup()` - Setup server (Node, PM2, Caddy, jq)
202229

203-
#### commands/deploy.sh (353 lines)
204-
**Purpose:** Deploy applications
230+
#### commands/deploy.sh (500 lines)
231+
**Purpose:** Deploy applications with template-aware PM2 and Caddy config generation
205232

206233
**Key Functions:**
207234
- `cmd_deploy()` - Main deploy command
235+
- `cmd_deploy_dry_run()` - Preview deployment without executing
208236
- `deploy_backend()` - Deploy backend application
209237
- `deploy_backend_legacy()` - Legacy backend deploy
210-
- `deploy_backend_zero_downtime()` - Zero-downtime backend deploy
238+
- `deploy_backend_zero_downtime()` - Zero-downtime backend deploy with duration/commit tracking
211239
- `deploy_frontend()` - Deploy frontend application
212240
- `deploy_frontend_legacy()` - Legacy frontend deploy
213241
- `deploy_frontend_zero_downtime()` - Zero-downtime frontend deploy
214-
- `configure_caddy_backend()` - Configure Caddy for backend
215-
- `configure_caddy_frontend()` - Configure Caddy for frontend
242+
- `configure_caddy_backend()` - Configure Caddy for backend (checks for ejected templates)
243+
- `configure_caddy_frontend()` - Configure Caddy for frontend (checks for ejected templates)
216244

217-
#### commands/status.sh (51 lines)
218-
**Purpose:** Application status management
245+
#### commands/status.sh (200 lines)
246+
**Purpose:** Application status dashboard with rich output for backend and frontend
219247

220248
**Key Functions:**
221-
- `cmd_status()` - Check application status
222-
- `cmd_logs()` - View application logs
249+
- `cmd_status()` - Check application status (routes to backend/frontend)
250+
- `cmd_status_backend()` - Rich PM2 dashboard: status, uptime, CPU, memory, releases, disk
251+
- `cmd_status_frontend()` - Frontend status: file count, size, release, Caddy status
252+
- `cmd_logs()` - View application logs (backend only)
223253
- `cmd_restart()` - Restart application
224254
- `cmd_stop()` - Stop application
225255

@@ -229,6 +259,28 @@ Modules are loaded in a specific order to ensure dependencies are available:
229259
**Key Functions:**
230260
- `cmd_unlock()` - Clear stuck deployment lock
231261

262+
#### commands/eject.sh (150 lines)
263+
**Purpose:** Eject PM2/Caddy config templates for user customization
264+
265+
**Key Functions:**
266+
- `cmd_eject()` - Eject templates (pm2, caddy, or all)
267+
- `eject_pm2()` - Copy PM2 ecosystem template to `.shipnode/templates/`
268+
- `eject_caddy()` - Copy Caddy template to `.shipnode/templates/` (backend or frontend)
269+
270+
#### commands/metrics.sh (15 lines)
271+
**Purpose:** Real-time PM2 resource monitoring
272+
273+
**Key Functions:**
274+
- `cmd_metrics()` - Open PM2 monit dashboard over SSH
275+
276+
#### commands/config-cmd.sh (100 lines)
277+
**Purpose:** Config inspection and validation
278+
279+
**Key Functions:**
280+
- `cmd_config()` - Route config subcommands (show, validate, path)
281+
- `cmd_config_show()` - Display resolved config values
282+
- `cmd_config_validate()` - Validate config file without deploying
283+
232284
#### commands/rollback.sh (86 lines)
233285
**Purpose:** Rollback to previous releases
234286

@@ -328,6 +380,8 @@ This concatenates all modules into `shipnode-bundled` in the correct order.
328380
Potential areas for modular expansion:
329381

330382
- **plugins/** - Plugin system for third-party extensions
331-
- **hooks/** - Pre/post deploy hooks
383+
- **hooks/** - Pre/post deploy hooks with chaining and local hooks
332384
- **tests/** - Unit tests for individual modules
333385
- **docs/** - Generated API documentation
386+
- **Observability** - Deployment notification webhooks (Slack, email), uptime monitoring
387+
- **Multi-app** - Deploy multiple apps from a single shipnode.conf

CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,43 @@ All notable changes to ShipNode will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.3.0] - 2026-04-08
9+
10+
### Added
11+
12+
#### Config Ejection (Custom Templates)
13+
- **`shipnode eject`**: Eject PM2 and Caddy config templates to `.shipnode/templates/` for full customization
14+
- **`shipnode eject pm2`**: Eject only PM2 ecosystem config
15+
- **`shipnode eject caddy`**: Eject only Caddy config
16+
- Templates use `{{VAR}}` placeholders (APP_NAME, INTERPRETER, REMOTE_PATH, BACKEND_PORT, DOMAIN, SERVE_PATH)
17+
- 3-tier template resolution: ejected template > project root file > built-in default
18+
- Ejected templates are preserved across deploys (never overwritten)
19+
- New template files: `ecosystem.config.cjs.tmpl`, `Caddyfile.backend.tmpl`, `Caddyfile.frontend.tmpl`
20+
21+
#### Observability
22+
- **`shipnode status`**: Complete rewrite with rich dashboard showing PM2 status, uptime, CPU, memory, release history, disk usage
23+
- **`shipnode status`** (frontend): Now shows file count, size, release info, Caddy status (was just `ls -lh`)
24+
- **`shipnode metrics`**: New command - opens PM2 real-time monitoring dashboard over SSH
25+
- **Deployment metadata**: Every deployment now records duration, git commit, health check attempts and response time
26+
- **Enhanced releases.json**: Rich schema with `duration_seconds`, `commit`, `health_check`, `previous_release` fields
27+
28+
#### Config Management
29+
- **`shipnode config`**: New command to show resolved config values (secrets redacted)
30+
- **`shipnode config validate`**: Validate config file without deploying
31+
- **`shipnode config path`**: Show config file path
32+
33+
### Changed
34+
- PM2 config generation checks for ejected templates before using inline defaults
35+
- Caddy config generation checks for ejected templates before using inline defaults
36+
- Default Caddy configs now include security headers (X-Content-Type-Options, X-Frame-Options, X-XSS-Protection)
37+
- Default frontend Caddy config includes Referrer-Policy header and JSON-formatted logs
38+
- Health check timing now tracked (attempts count and response time in milliseconds)
39+
- Deploy duration tracked from start to finish
40+
- Git commit hash recorded in release history (best-effort)
41+
- `.shipnode/` directory excluded from rsync (prevents local templates from syncing)
42+
- README completely rewritten with clearer structure and "How It Works" section
43+
- ARCHITECTURE.md updated with all new modules
44+
845
## [1.2.0] - 2026-02-22
946

1047
### Added

0 commit comments

Comments
 (0)