hostfn 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/dist/__tests__/core/backup.test.d.ts +2 -0
  2. package/dist/__tests__/core/backup.test.d.ts.map +1 -0
  3. package/dist/__tests__/core/backup.test.js +108 -0
  4. package/dist/__tests__/core/backup.test.js.map +1 -0
  5. package/dist/__tests__/core/health.test.d.ts +2 -0
  6. package/dist/__tests__/core/health.test.d.ts.map +1 -0
  7. package/dist/__tests__/core/health.test.js +97 -0
  8. package/dist/__tests__/core/health.test.js.map +1 -0
  9. package/dist/__tests__/core/lock.test.d.ts +2 -0
  10. package/dist/__tests__/core/lock.test.d.ts.map +1 -0
  11. package/dist/__tests__/core/lock.test.js +136 -0
  12. package/dist/__tests__/core/lock.test.js.map +1 -0
  13. package/dist/__tests__/core/nginx-multi-domain.test.d.ts +2 -0
  14. package/dist/__tests__/core/nginx-multi-domain.test.d.ts.map +1 -0
  15. package/dist/__tests__/core/nginx-multi-domain.test.js +158 -0
  16. package/dist/__tests__/core/nginx-multi-domain.test.js.map +1 -0
  17. package/dist/__tests__/runtimes/pm2.test.d.ts +2 -0
  18. package/dist/__tests__/runtimes/pm2.test.d.ts.map +1 -0
  19. package/dist/__tests__/runtimes/pm2.test.js +111 -0
  20. package/dist/__tests__/runtimes/pm2.test.js.map +1 -0
  21. package/dist/__tests__/utils/validation.test.d.ts +2 -0
  22. package/dist/__tests__/utils/validation.test.d.ts.map +1 -0
  23. package/dist/__tests__/utils/validation.test.js +136 -0
  24. package/dist/__tests__/utils/validation.test.js.map +1 -0
  25. package/dist/commands/deploy.d.ts +11 -0
  26. package/dist/commands/deploy.d.ts.map +1 -0
  27. package/dist/commands/deploy.js +636 -0
  28. package/dist/commands/deploy.js.map +1 -0
  29. package/dist/commands/env.d.ts +21 -0
  30. package/dist/commands/env.d.ts.map +1 -0
  31. package/dist/commands/env.js +317 -0
  32. package/dist/commands/env.js.map +1 -0
  33. package/dist/commands/expose.d.ts +6 -0
  34. package/dist/commands/expose.d.ts.map +1 -0
  35. package/dist/commands/expose.js +379 -0
  36. package/dist/commands/expose.js.map +1 -0
  37. package/dist/commands/init.d.ts +2 -0
  38. package/dist/commands/init.d.ts.map +1 -0
  39. package/dist/commands/init.js +175 -0
  40. package/dist/commands/init.js.map +1 -0
  41. package/dist/commands/logs.d.ts +10 -0
  42. package/dist/commands/logs.d.ts.map +1 -0
  43. package/dist/commands/logs.js +75 -0
  44. package/dist/commands/logs.js.map +1 -0
  45. package/dist/commands/rollback.d.ts +6 -0
  46. package/dist/commands/rollback.d.ts.map +1 -0
  47. package/dist/commands/rollback.js +113 -0
  48. package/dist/commands/rollback.js.map +1 -0
  49. package/dist/commands/server/info.d.ts +2 -0
  50. package/dist/commands/server/info.d.ts.map +1 -0
  51. package/dist/commands/server/info.js +104 -0
  52. package/dist/commands/server/info.js.map +1 -0
  53. package/dist/commands/server/setup.d.ts +11 -0
  54. package/dist/commands/server/setup.d.ts.map +1 -0
  55. package/dist/commands/server/setup.js +161 -0
  56. package/dist/commands/server/setup.js.map +1 -0
  57. package/dist/commands/status.d.ts +6 -0
  58. package/dist/commands/status.d.ts.map +1 -0
  59. package/dist/commands/status.js +120 -0
  60. package/dist/commands/status.js.map +1 -0
  61. package/dist/config/loader.d.ts +21 -0
  62. package/dist/config/loader.d.ts.map +1 -0
  63. package/dist/config/loader.js +54 -0
  64. package/dist/config/loader.js.map +1 -0
  65. package/dist/config/schema.d.ts +323 -0
  66. package/dist/config/schema.d.ts.map +1 -0
  67. package/dist/config/schema.js +108 -0
  68. package/dist/config/schema.js.map +1 -0
  69. package/dist/core/backup.d.ts +34 -0
  70. package/dist/core/backup.d.ts.map +1 -0
  71. package/dist/core/backup.js +95 -0
  72. package/dist/core/backup.js.map +1 -0
  73. package/dist/core/health.d.ts +31 -0
  74. package/dist/core/health.d.ts.map +1 -0
  75. package/dist/core/health.js +78 -0
  76. package/dist/core/health.js.map +1 -0
  77. package/dist/core/local.d.ts +19 -0
  78. package/dist/core/local.d.ts.map +1 -0
  79. package/dist/core/local.js +50 -0
  80. package/dist/core/local.js.map +1 -0
  81. package/dist/core/lock.d.ts +28 -0
  82. package/dist/core/lock.d.ts.map +1 -0
  83. package/dist/core/lock.js +89 -0
  84. package/dist/core/lock.js.map +1 -0
  85. package/dist/core/nginx.d.ts +43 -0
  86. package/dist/core/nginx.d.ts.map +1 -0
  87. package/dist/core/nginx.js +131 -0
  88. package/dist/core/nginx.js.map +1 -0
  89. package/dist/core/ssh.d.ts +79 -0
  90. package/dist/core/ssh.d.ts.map +1 -0
  91. package/dist/core/ssh.js +264 -0
  92. package/dist/core/ssh.js.map +1 -0
  93. package/dist/core/sync.d.ts +25 -0
  94. package/dist/core/sync.d.ts.map +1 -0
  95. package/dist/core/sync.js +117 -0
  96. package/dist/core/sync.js.map +1 -0
  97. package/dist/core/workspace.d.ts +13 -0
  98. package/dist/core/workspace.d.ts.map +1 -0
  99. package/dist/core/workspace.js +141 -0
  100. package/dist/core/workspace.js.map +1 -0
  101. package/dist/index.d.ts +3 -0
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +232 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/runtimes/base.d.ts +115 -0
  106. package/dist/runtimes/base.d.ts.map +1 -0
  107. package/dist/runtimes/base.js +16 -0
  108. package/dist/runtimes/base.js.map +1 -0
  109. package/dist/runtimes/nodejs/detector.d.ts +47 -0
  110. package/dist/runtimes/nodejs/detector.d.ts.map +1 -0
  111. package/dist/runtimes/nodejs/detector.js +143 -0
  112. package/dist/runtimes/nodejs/detector.js.map +1 -0
  113. package/dist/runtimes/nodejs/index.d.ts +14 -0
  114. package/dist/runtimes/nodejs/index.d.ts.map +1 -0
  115. package/dist/runtimes/nodejs/index.js +213 -0
  116. package/dist/runtimes/nodejs/index.js.map +1 -0
  117. package/dist/runtimes/nodejs/pm2.d.ts +17 -0
  118. package/dist/runtimes/nodejs/pm2.d.ts.map +1 -0
  119. package/dist/runtimes/nodejs/pm2.js +60 -0
  120. package/dist/runtimes/nodejs/pm2.js.map +1 -0
  121. package/dist/runtimes/registry.d.ts +34 -0
  122. package/dist/runtimes/registry.d.ts.map +1 -0
  123. package/dist/runtimes/registry.js +58 -0
  124. package/dist/runtimes/registry.js.map +1 -0
  125. package/dist/utils/logger.d.ts +47 -0
  126. package/dist/utils/logger.d.ts.map +1 -0
  127. package/dist/utils/logger.js +76 -0
  128. package/dist/utils/logger.js.map +1 -0
  129. package/dist/utils/validation.d.ts +32 -0
  130. package/dist/utils/validation.d.ts.map +1 -0
  131. package/dist/utils/validation.js +125 -0
  132. package/dist/utils/validation.js.map +1 -0
  133. package/package.json +33 -16
  134. package/LICENSE +0 -21
  135. package/README.md +0 -1136
  136. package/_conduct/specs/1.v0.spec.md +0 -1041
  137. package/examples/express-api/package.json +0 -22
  138. package/examples/express-api/src/index.ts +0 -16
  139. package/examples/express-api/tsconfig.json +0 -11
  140. package/examples/github-actions-deploy.yml +0 -40
  141. package/examples/monorepo-config.json +0 -76
  142. package/examples/monorepo-multi-server-config.json +0 -74
  143. package/packages/cli/package.json +0 -40
  144. package/turbo.json +0 -24
  145. /package/{packages/cli/src → src}/__tests__/core/backup.test.ts +0 -0
  146. /package/{packages/cli/src → src}/__tests__/core/health.test.ts +0 -0
  147. /package/{packages/cli/src → src}/__tests__/core/lock.test.ts +0 -0
  148. /package/{packages/cli/src → src}/__tests__/core/nginx-multi-domain.test.ts +0 -0
  149. /package/{packages/cli/src → src}/__tests__/runtimes/pm2.test.ts +0 -0
  150. /package/{packages/cli/src → src}/__tests__/utils/validation.test.ts +0 -0
  151. /package/{packages/cli/src → src}/commands/deploy.ts +0 -0
  152. /package/{packages/cli/src → src}/commands/env.ts +0 -0
  153. /package/{packages/cli/src → src}/commands/expose.ts +0 -0
  154. /package/{packages/cli/src → src}/commands/init.ts +0 -0
  155. /package/{packages/cli/src → src}/commands/logs.ts +0 -0
  156. /package/{packages/cli/src → src}/commands/rollback.ts +0 -0
  157. /package/{packages/cli/src → src}/commands/server/info.ts +0 -0
  158. /package/{packages/cli/src → src}/commands/server/setup.ts +0 -0
  159. /package/{packages/cli/src → src}/commands/status.ts +0 -0
  160. /package/{packages/cli/src → src}/config/loader.ts +0 -0
  161. /package/{packages/cli/src → src}/config/schema.ts +0 -0
  162. /package/{packages/cli/src → src}/core/backup.ts +0 -0
  163. /package/{packages/cli/src → src}/core/health.ts +0 -0
  164. /package/{packages/cli/src → src}/core/local.ts +0 -0
  165. /package/{packages/cli/src → src}/core/lock.ts +0 -0
  166. /package/{packages/cli/src → src}/core/nginx.ts +0 -0
  167. /package/{packages/cli/src → src}/core/ssh.ts +0 -0
  168. /package/{packages/cli/src → src}/core/sync.ts +0 -0
  169. /package/{packages/cli/src → src}/core/workspace.ts +0 -0
  170. /package/{packages/cli/src → src}/index.ts +0 -0
  171. /package/{packages/cli/src → src}/runtimes/base.ts +0 -0
  172. /package/{packages/cli/src → src}/runtimes/nodejs/detector.ts +0 -0
  173. /package/{packages/cli/src → src}/runtimes/nodejs/index.ts +0 -0
  174. /package/{packages/cli/src → src}/runtimes/nodejs/pm2.ts +0 -0
  175. /package/{packages/cli/src → src}/runtimes/registry.ts +0 -0
  176. /package/{packages/cli/src → src}/utils/logger.ts +0 -0
  177. /package/{packages/cli/src → src}/utils/validation.ts +0 -0
  178. /package/{packages/cli/tsconfig.json → tsconfig.json} +0 -0
  179. /package/{packages/cli/vitest.config.ts → vitest.config.ts} +0 -0
@@ -1,1041 +0,0 @@
1
- # Specification: hostfn - Universal Application Deployment CLI
2
-
3
- **Spec ID:** 1
4
- **Version:** v0
5
- **Created:** 2025-11-14
6
- **Status:** Draft
7
- **LOE:** Large (8-12 hours)
8
- **Initial Release:** Node.js support
9
- **Future:** Multi-language/runtime support
10
-
11
- ---
12
-
13
- ## Overview
14
-
15
- **hostfn** is a zero-config, cloud-agnostic deployment CLI for server applications. It abstracts away the complexity of server provisioning, SSH configuration, process management, reverse proxy setup, and continuous deployments—allowing developers to deploy any application to any VPS with a single command.
16
-
17
- **Initial Release (v1.0):** Full Node.js support with PM2 process management
18
- **Future Releases:** Python, Go, Ruby, Rust, PHP, and other languages/runtimes
19
-
20
- ### Philosophy
21
-
22
- - **Zero Config, Smart Defaults:** Works out-of-the-box by detecting project structure
23
- - **Cloud Agnostic:** Works on any Linux VPS (Ubuntu, Debian, Amazon Linux, CentOS, etc.)
24
- - **Local & CI/CD:** Single CLI for both local and automated deployments
25
- - **Language Agnostic Architecture:** Pluggable runtime system for any language/framework
26
- - **Production Ready:** Built-in health checks, rollbacks, zero-downtime deploys
27
-
28
- ---
29
-
30
- ## Problem Statement
31
-
32
- Current deployment options fall into two extremes:
33
-
34
- 1. **Platform-as-a-Service (Vercel, Railway, Fly.io):**
35
- - ✅ Simple, one-command deploys
36
- - ❌ Vendor lock-in, limited control, expensive at scale
37
- - ❌ Can't use existing VPS infrastructure
38
-
39
- 2. **Manual VPS Deployment:**
40
- - ✅ Full control, cost-effective
41
- - ❌ Complex bash scripts, manual SSH setup
42
- - ❌ Not CI/CD friendly, hard to maintain
43
-
44
- **hostfn bridges this gap:** PaaS-like simplicity with VPS control and economics.
45
-
46
- ---
47
-
48
- ## Target Users
49
-
50
- 1. **Solo Developers:** Need quick deploys without DevOps complexity
51
- 2. **Startups:** Want to use affordable VPS ($5-20/mo) instead of expensive PaaS
52
- 3. **Teams:** Need consistent deployment process across projects and languages
53
- 4. **Side Projects:** Quick deployment for hackathons, MVPs, experiments
54
-
55
- ## Language/Runtime Support
56
-
57
- ### V1.0 (Initial Release) - Node.js
58
- - ✅ Full support for Node.js applications
59
- - ✅ PM2 process management
60
- - ✅ Framework detection (Express, Hono, Next.js, Fastify, etc.)
61
- - ✅ npm/yarn/pnpm package managers
62
- - ✅ Built-in health checks for HTTP services
63
-
64
- ### Future Releases - Multi-Language Support
65
- - 🔮 **Python:** Flask, FastAPI, Django (systemd/gunicorn/uvicorn)
66
- - 🔮 **Go:** Compiled binaries (systemd service)
67
- - 🔮 **Ruby:** Rails, Sinatra (systemd/puma)
68
- - 🔮 **Rust:** Compiled binaries (systemd service)
69
- - 🔮 **PHP:** Laravel, Symfony (php-fpm + Nginx)
70
- - 🔮 **Java/Kotlin:** Spring Boot (systemd service)
71
- - 🔮 **Docker:** Multi-runtime via containers
72
-
73
- **Architecture Design:** The CLI is built with a pluggable runtime system, making it straightforward to add new language support by implementing runtime adapters.
74
-
75
- ---
76
-
77
- ## Core Features
78
-
79
- ### 1. Server Provisioning (`hostfn server setup`)
80
-
81
- **Command:**
82
- ```bash
83
- hostfn server setup <user@host> [--env production]
84
- ```
85
-
86
- **What it does:**
87
- - Auto-detects OS (Ubuntu/Debian/Amazon Linux/CentOS)
88
- - Installs Node.js via nvm (configurable version)
89
- - Installs PM2 process manager globally
90
- - Configures Nginx as reverse proxy
91
- - Sets up firewall (UFW or firewalld)
92
- - Optionally installs Redis
93
- - Creates deployment directories
94
- - Configures PM2 to auto-start on reboot
95
- - Generates deployment keys for CI/CD
96
-
97
- **Example:**
98
- ```bash
99
- # Setup production server
100
- hostfn server setup ubuntu@123.45.67.89 --env production --node-version 18
101
-
102
- # Setup staging on same server
103
- hostfn server setup ubuntu@123.45.67.89 --env staging --port 3001
104
- ```
105
-
106
- **Output:**
107
- ```
108
- ✅ Server setup complete!
109
- - Node.js v18.19.0 installed
110
- - PM2 v5.3.0 ready
111
- - Nginx configured (port 80 → 3000)
112
- - Firewall enabled (22, 80, 443)
113
-
114
- 🔑 Add this to CI/CD secrets:
115
- DEPLOY_HOST=ubuntu@123.45.67.89
116
- DEPLOY_KEY=<generated-ssh-key>
117
- ```
118
-
119
- ---
120
-
121
- ### 2. Project Initialization (`hostfn init`)
122
-
123
- **Command:**
124
- ```bash
125
- hostfn init
126
- ```
127
-
128
- **What it does:**
129
- - Auto-detects project type from `package.json`
130
- - Creates `hostfn.config.json` with smart defaults
131
- - Prompts for missing configuration
132
- - Sets up deployment scripts
133
- - Configures environment variable templates
134
-
135
- **Auto-Detection Logic:**
136
- - Checks `package.json` for framework dependencies
137
- - Identifies build/start commands
138
- - Detects ports from code or env files
139
- - Determines if monorepo (workspace packages)
140
-
141
- **Example Configuration Generated:**
142
- ```json
143
- {
144
- "name": "my-app",
145
- "runtime": "node",
146
- "version": "18",
147
- "environments": {
148
- "production": {
149
- "server": "ubuntu@prod-server.com",
150
- "port": 3000,
151
- "instances": "max",
152
- "domain": "api.example.com"
153
- },
154
- "staging": {
155
- "server": "ubuntu@staging.example.com",
156
- "port": 3001,
157
- "instances": 2
158
- }
159
- },
160
- "build": {
161
- "command": "npm run build",
162
- "directory": "dist",
163
- "node_modules": "production"
164
- },
165
- "start": {
166
- "command": "npm start",
167
- "entry": "dist/index.js"
168
- },
169
- "health": {
170
- "path": "/health",
171
- "timeout": 60,
172
- "retries": 10
173
- },
174
- "env": {
175
- "required": ["DATABASE_URL", "JWT_SECRET"],
176
- "optional": ["REDIS_URL", "EMAIL_PROVIDER"]
177
- }
178
- }
179
- ```
180
-
181
- ---
182
-
183
- ### 3. Local Deployment (`hostfn deploy`)
184
-
185
- **Command:**
186
- ```bash
187
- hostfn deploy [environment]
188
- ```
189
-
190
- **What it does:**
191
- 1. **Pre-flight checks:**
192
- - Validates `hostfn.config.json`
193
- - Checks SSH connectivity
194
- - Verifies required env vars exist on server
195
-
196
- 2. **File transfer:**
197
- - Syncs source code via rsync (excludes node_modules, .git, etc.)
198
- - Syncs monorepo dependencies if detected
199
-
200
- 3. **Remote build:**
201
- - Runs `npm ci --production` on server
202
- - Executes build command
203
- - Validates build artifacts exist
204
-
205
- 4. **Backup:**
206
- - Creates timestamped backup of current deployment
207
- - Keeps last N backups (configurable)
208
-
209
- 5. **Deploy:**
210
- - Updates PM2 process (reload for zero-downtime)
211
- - Starts new process if first deployment
212
-
213
- 6. **Health check:**
214
- - Polls health endpoint until success
215
- - Auto-rollback on failure
216
-
217
- 7. **Post-deploy:**
218
- - Shows deployment summary
219
- - Outputs logs command
220
- - Displays app URL
221
-
222
- **Example:**
223
- ```bash
224
- # Deploy to production
225
- hostfn deploy production
226
-
227
- # Deploy to staging
228
- hostfn deploy staging
229
-
230
- # Deploy with specific host (override config)
231
- hostfn deploy --host ubuntu@123.45.67.89
232
-
233
- # Dry run (show what would be deployed)
234
- hostfn deploy production --dry-run
235
- ```
236
-
237
- **Output:**
238
- ```
239
- 🚀 Deploying to production...
240
-
241
- ✓ Pre-flight checks passed
242
- ✓ Files synced (245 files, 12.3 MB)
243
- ✓ Dependencies installed (23s)
244
- ✓ Build completed (8s)
245
- ✓ Backup created: /var/www/backups/20251114_143022
246
- ✓ PM2 reloaded: account-service
247
- ✓ Health check passed (3 attempts)
248
-
249
- ✅ Deployment successful!
250
- Environment: production
251
- Server: ubuntu@prod.example.com
252
- Version: v1.2.3 (commit: abc1234)
253
- URL: https://api.example.com
254
- Time: 45s
255
-
256
- View logs: hostfn logs production
257
- ```
258
-
259
- ---
260
-
261
- ### 4. CI/CD Deployment (`hostfn deploy --ci`)
262
-
263
- **GitHub Actions Example:**
264
- ```yaml
265
- name: Deploy to Production
266
-
267
- on:
268
- push:
269
- branches: [main]
270
-
271
- jobs:
272
- deploy:
273
- runs-on: ubuntu-latest
274
- steps:
275
- - uses: actions/checkout@v4
276
-
277
- - name: Setup Node.js
278
- uses: actions/setup-node@v4
279
- with:
280
- node-version: 18
281
-
282
- - name: Install hostfn
283
- run: npm install -g hostfn
284
-
285
- - name: Deploy
286
- run: hostfn deploy production --ci
287
- env:
288
- HOSTFN_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
289
- HOSTFN_HOST: ${{ secrets.DEPLOY_HOST }}
290
- DATABASE_URL: ${{ secrets.DATABASE_URL }}
291
- JWT_SECRET: ${{ secrets.JWT_SECRET }}
292
- ```
293
-
294
- **What `--ci` flag does:**
295
- - Uses environment variables for credentials
296
- - Non-interactive mode (no prompts)
297
- - Enhanced logging for CI logs
298
- - Exits with proper error codes
299
- - Supports GitHub/GitLab/Bitbucket annotations
300
-
301
- ---
302
-
303
- ### 5. Environment Management
304
-
305
- **Commands:**
306
- ```bash
307
- # View environment variables on server
308
- hostfn env list production
309
-
310
- # Add/update environment variable
311
- hostfn env set production DATABASE_URL "postgresql://..."
312
-
313
- # Set from .env file
314
- hostfn env push production .env.production
315
-
316
- # Download environment variables
317
- hostfn env pull production > .env.production
318
-
319
- # Validate required env vars
320
- hostfn env validate production
321
- ```
322
-
323
- **Security Features:**
324
- - Env vars stored in `.env` file on server (not in PM2 config)
325
- - Never logs sensitive values
326
- - Encrypted transfer over SSH
327
- - Local `.env.*` files in `.gitignore` by default
328
-
329
- ---
330
-
331
- ### 6. Logs & Monitoring
332
-
333
- **Commands:**
334
- ```bash
335
- # Stream logs (like pm2 logs)
336
- hostfn logs production
337
-
338
- # Show last N lines
339
- hostfn logs production --lines 100
340
-
341
- # Show only errors
342
- hostfn logs production --errors
343
-
344
- # Export logs to file
345
- hostfn logs production --output logs.txt
346
- ```
347
-
348
- ---
349
-
350
- ### 7. Rollback & Recovery
351
-
352
- **Commands:**
353
- ```bash
354
- # List available backups
355
- hostfn backups list production
356
-
357
- # Rollback to previous deployment
358
- hostfn rollback production
359
-
360
- # Rollback to specific backup
361
- hostfn rollback production --to 20251114_143022
362
-
363
- # Restore from backup (manual)
364
- hostfn restore production 20251114_143022
365
- ```
366
-
367
- **Auto-rollback:**
368
- - Triggered automatically if health checks fail after deployment
369
- - Reverts to last known-good deployment
370
- - Logs rollback reason
371
-
372
- ---
373
-
374
- ### 8. Domain & SSL Setup
375
-
376
- **Commands:**
377
- ```bash
378
- # Configure domain in Nginx
379
- hostfn domain add production api.example.com
380
-
381
- # Setup SSL with Let's Encrypt
382
- hostfn ssl setup production api.example.com --email admin@example.com
383
-
384
- # Renew SSL (auto-renewal setup by default)
385
- hostfn ssl renew production
386
- ```
387
-
388
- ---
389
-
390
- ### 9. Multi-Service Support
391
-
392
- For monorepos or multiple services on one server:
393
-
394
- **Configuration:**
395
- ```json
396
- {
397
- "services": {
398
- "api": {
399
- "port": 3000,
400
- "path": "services/api",
401
- "domain": "api.example.com"
402
- },
403
- "worker": {
404
- "port": 3001,
405
- "path": "services/worker",
406
- "domain": "worker.example.com"
407
- }
408
- }
409
- }
410
- ```
411
-
412
- **Commands:**
413
- ```bash
414
- # Deploy specific service
415
- hostfn deploy production --service api
416
-
417
- # Deploy all services
418
- hostfn deploy production --all
419
-
420
- # Status of all services
421
- hostfn status production
422
- ```
423
-
424
- ---
425
-
426
- ## Technical Architecture
427
-
428
- ### CLI Structure
429
-
430
- ```
431
- hostfn/
432
- ├── packages/
433
- │ ├── cli/ # Main CLI package
434
- │ │ ├── src/
435
- │ │ │ ├── commands/ # Command implementations
436
- │ │ │ │ ├── init.ts
437
- │ │ │ │ ├── deploy.ts
438
- │ │ │ │ ├── server/
439
- │ │ │ │ │ ├── setup.ts
440
- │ │ │ │ │ └── info.ts
441
- │ │ │ │ ├── env.ts
442
- │ │ │ │ ├── logs.ts
443
- │ │ │ │ ├── rollback.ts
444
- │ │ │ │ └── domain.ts
445
- │ │ │ ├── core/ # Core business logic
446
- │ │ │ │ ├── ssh.ts # SSH connection manager
447
- │ │ │ │ ├── rsync.ts # File sync
448
- │ │ │ │ ├── pm2.ts # PM2 manager
449
- │ │ │ │ ├── nginx.ts # Nginx config generator
450
- │ │ │ │ ├── health.ts # Health check
451
- │ │ │ │ └── backup.ts # Backup manager
452
- │ │ │ ├── runtimes/ # Runtime adapters (pluggable)
453
- │ │ │ │ ├── base.ts # Base runtime interface
454
- │ │ │ │ ├── registry.ts # Runtime registry
455
- │ │ │ │ └── nodejs/ # Node.js runtime adapter (v1.0)
456
- │ │ │ │ ├── index.ts
457
- │ │ │ │ ├── detector.ts
458
- │ │ │ │ ├── frameworks/
459
- │ │ │ │ │ ├── express.ts
460
- │ │ │ │ │ ├── hono.ts
461
- │ │ │ │ │ ├── nextjs.ts
462
- │ │ │ │ │ └── generic.ts
463
- │ │ │ │ └── pm2.ts # PM2 manager
464
- │ │ │ ├── config/ # Config management
465
- │ │ │ │ ├── schema.ts # Zod schemas
466
- │ │ │ │ ├── loader.ts
467
- │ │ │ │ └── validator.ts
468
- │ │ │ ├── utils/
469
- │ │ │ │ ├── logger.ts # Pretty console output
470
- │ │ │ │ ├── spinner.ts
471
- │ │ │ │ └── git.ts
472
- │ │ │ └── index.ts # CLI entry point
473
- │ │ ├── templates/ # Config templates
474
- │ │ │ ├── hostfn.config.json
475
- │ │ │ ├── nginx.conf
476
- │ │ │ ├── ecosystem.config.js
477
- │ │ │ └── .github/
478
- │ │ │ └── workflows/
479
- │ │ │ └── deploy.yml
480
- │ │ └── package.json
481
- │ │
482
- │ └── scripts/ # Server-side scripts (optional package)
483
- │ ├── setup-server.sh # Generated dynamically
484
- │ └── deploy-remote.sh
485
-
486
- ├── examples/ # Example projects
487
- │ ├── express-api/
488
- │ ├── hono-api/
489
- │ └── nextjs-app/
490
-
491
- ├── docs/ # Documentation
492
- │ ├── getting-started.md
493
- │ ├── configuration.md
494
- │ ├── ci-cd.md
495
- │ └── examples/
496
-
497
- ├── package.json # Monorepo root
498
- ├── turbo.json # Turborepo config
499
- └── README.md
500
- ```
501
-
502
- ---
503
-
504
- ## Implementation Plan
505
-
506
- ### Phase 1: Core Infrastructure (4-5 hours)
507
-
508
- **1.1 Project Setup**
509
- - [x] Create monorepo structure at `~/dev/functions/hostfn`
510
- - [x] Setup Turborepo with `packages/cli`
511
- - [x] Initialize TypeScript with strict config
512
- - [x] Setup CLI framework (Commander.js or Yargs)
513
- - [x] Add dependencies: ssh2, node-rsync, inquirer, chalk, ora
514
-
515
- **1.2 Config System**
516
- - [ ] Define `hostfn.config.json` Zod schema
517
- - [ ] Implement config loader with validation
518
- - [ ] Create config generator for `hostfn init`
519
- - [ ] Add config override via CLI flags and env vars
520
-
521
- **1.3 SSH Connection Manager**
522
- - [ ] Implement SSH connection pool using ssh2
523
- - [ ] Add SSH key authentication (file-based and agent)
524
- - [ ] Handle connection errors and retries
525
- - [ ] Support for password authentication (fallback)
526
-
527
- **1.4 Project Detectors**
528
- - [ ] Generic Node.js detector (reads package.json)
529
- - [ ] Framework-specific detectors:
530
- - Express.js (detects express dependency)
531
- - Hono (detects hono dependency)
532
- - Next.js (detects next dependency)
533
- - Fastify, Koa, etc.
534
- - [ ] Extract build/start commands from scripts
535
- - [ ] Detect monorepo structure (workspaces)
536
-
537
- ---
538
-
539
- ### Phase 2: Server Setup (2-3 hours)
540
-
541
- **2.1 `hostfn server setup` Command**
542
- - [ ] OS detection script (Ubuntu/Debian/Amazon Linux/CentOS)
543
- - [ ] Runtime-specific installation (pluggable):
544
- - [ ] Node.js via nvm (v1.0 - parametrized version)
545
- - [ ] Runtime installer interface for future languages
546
- - [ ] Process manager installation (runtime-specific):
547
- - [ ] PM2 for Node.js (v1.0)
548
- - [ ] systemd for compiled languages (future)
549
- - [ ] Nginx installation and basic config
550
- - [ ] Firewall setup (ufw or firewalld)
551
- - [ ] Create deployment directories
552
- - [ ] Generate SSH keys for CI/CD
553
- - [ ] Process manager startup configuration
554
-
555
- **2.2 Nginx Configuration Generator**
556
- - [ ] Generate reverse proxy config for service
557
- - [ ] Support multiple services on same server
558
- - [ ] Health check endpoint routing
559
- - [ ] WebSocket support (upgrade headers)
560
- - [ ] Static file serving (if needed)
561
-
562
- **2.3 Server Info Command**
563
- - [ ] `hostfn server info` - Show server details
564
- - [ ] Display installed versions (Node, PM2, Nginx)
565
- - [ ] Show running services
566
- - [ ] Disk space, memory usage
567
-
568
- ---
569
-
570
- ### Phase 3: Deployment Engine (3-4 hours)
571
-
572
- **3.1 `hostfn deploy` Command**
573
- - [ ] Pre-flight validation (SSH, config, health endpoint)
574
- - [ ] File sync with rsync (excludes: node_modules, .git, dist, .env)
575
- - [ ] Remote dependency installation (`npm ci --production`)
576
- - [ ] Remote build execution (npm run build)
577
- - [ ] Backup creation with timestamp
578
- - [ ] PM2 process management:
579
- - [ ] Start new process if not exists
580
- - [ ] Reload existing process (zero-downtime)
581
- - [ ] Handle errors during reload
582
- - [ ] Health check polling (configurable timeout/retries)
583
- - [ ] Auto-rollback on failure
584
- - [ ] Deployment summary output
585
-
586
- **3.2 Environment Variable Management**
587
- - [ ] `hostfn env set` - Add/update env var
588
- - [ ] `hostfn env push` - Upload .env file
589
- - [ ] `hostfn env pull` - Download .env file
590
- - [ ] `hostfn env list` - Show env vars (masked)
591
- - [ ] `hostfn env validate` - Check required vars
592
- - [ ] Secure transfer and storage
593
-
594
- **3.3 CI/CD Mode**
595
- - [ ] `--ci` flag for non-interactive mode
596
- - [ ] Use env vars for credentials:
597
- - HOSTFN_SSH_KEY
598
- - HOSTFN_HOST
599
- - HOSTFN_ENV_*
600
- - [ ] Enhanced logging for CI
601
- - [ ] Exit codes for CI
602
- - [ ] Support GitHub Actions annotations
603
-
604
- ---
605
-
606
- ### Phase 4: Monitoring & Management (1-2 hours)
607
-
608
- **4.1 Logs**
609
- - [ ] `hostfn logs` - Stream logs via PM2
610
- - [ ] `--lines N` - Show last N lines
611
- - [ ] `--errors` - Filter errors only
612
- - [ ] `--output file.txt` - Export logs
613
-
614
- **4.2 Status & Info**
615
- - [ ] `hostfn status` - Show service status
616
- - [ ] Display: uptime, memory, CPU, restart count
617
- - [ ] Show deployment history
618
- - [ ] Show current version/commit
619
-
620
- **4.3 Rollback**
621
- - [ ] `hostfn backups list` - List backups
622
- - [ ] `hostfn rollback` - Rollback to previous
623
- - [ ] `hostfn rollback --to <timestamp>` - Specific backup
624
- - [ ] Auto-cleanup old backups (keep last N)
625
-
626
- ---
627
-
628
- ### Phase 5: Advanced Features (Optional, 2-3 hours)
629
-
630
- **5.1 Domain & SSL**
631
- - [ ] `hostfn domain add` - Configure domain in Nginx
632
- - [ ] `hostfn ssl setup` - Let's Encrypt integration
633
- - [ ] `hostfn ssl renew` - Manual renewal
634
- - [ ] Auto-renewal setup (cron job)
635
-
636
- **5.2 Multi-Service Support**
637
- - [ ] Deploy multiple services from monorepo
638
- - [ ] `--service <name>` flag
639
- - [ ] `--all` flag for all services
640
- - [ ] Service dependency management
641
-
642
- **5.3 Database Migrations**
643
- - [ ] Detect migration commands in package.json
644
- - [ ] `hostfn migrate` - Run migrations
645
- - [ ] Auto-run migrations on deploy (optional)
646
-
647
- **5.4 Health Check Customization**
648
- - [ ] Support custom health check commands
649
- - [ ] TCP-based health checks (non-HTTP)
650
- - [ ] Multiple health check strategies
651
-
652
- ---
653
-
654
- ## Technology Stack
655
-
656
- ### CLI Package
657
- - **CLI Framework:** Commander.js (lightweight, popular)
658
- - **Config Validation:** Zod
659
- - **SSH:** ssh2 (pure JS SSH client)
660
- - **File Sync:** node-rsync (wrapper around rsync command)
661
- - **Prompts:** inquirer
662
- - **Styling:** chalk (colors), ora (spinners), boxen (boxes)
663
- - **Testing:** Vitest
664
- - **Architecture:** Pluggable runtime adapter system
665
-
666
- ### Server-Side (V1.0 - Node.js)
667
- - **Process Manager:** PM2 (Node.js specific)
668
- - **Reverse Proxy:** Nginx (all runtimes)
669
- - **SSL:** Certbot / Let's Encrypt (all runtimes)
670
- - **Runtime Manager:** nvm (Node.js specific)
671
-
672
- ### Future Server-Side Components
673
- - **Process Managers:** systemd (Go, Rust, Python), gunicorn (Python), puma (Ruby)
674
- - **Runtime Managers:** pyenv (Python), rbenv (Ruby), rustup (Rust)
675
-
676
- ---
677
-
678
- ## Configuration Schema
679
-
680
- ### `hostfn.config.json`
681
-
682
- ```typescript
683
- interface HostfnConfig {
684
- name: string;
685
- runtime: 'nodejs' | 'python' | 'go' | 'ruby' | 'rust'; // Extensible
686
- version: string; // Runtime version (e.g., Node 18, Python 3.11)
687
-
688
- environments: {
689
- [env: string]: {
690
- server: string; // user@host
691
- port: number;
692
- instances?: number | 'max';
693
- domain?: string;
694
- sslEmail?: string;
695
- };
696
- };
697
-
698
- build?: {
699
- command: string;
700
- directory: string;
701
- nodeModules: 'all' | 'production' | 'none';
702
- };
703
-
704
- start: {
705
- command: string;
706
- entry?: string;
707
- };
708
-
709
- health?: {
710
- path: string;
711
- timeout: number;
712
- retries: number;
713
- interval?: number;
714
- };
715
-
716
- env: {
717
- required: string[];
718
- optional?: string[];
719
- };
720
-
721
- sync?: {
722
- exclude?: string[];
723
- include?: string[];
724
- };
725
-
726
- backup?: {
727
- keep: number; // Keep last N backups
728
- };
729
-
730
- services?: {
731
- [name: string]: {
732
- port: number;
733
- path: string; // Path in monorepo
734
- domain?: string;
735
- };
736
- };
737
- }
738
- ```
739
-
740
- ---
741
-
742
- ## Example Usage Scenarios
743
-
744
- ### Scenario 1: Fresh VPS Setup
745
-
746
- ```bash
747
- # 1. Setup server (one-time)
748
- hostfn server setup ubuntu@123.45.67.89 --env production
749
-
750
- # 2. Initialize project
751
- cd my-node-app
752
- hostfn init
753
- # Prompts for server details, auto-detects settings
754
-
755
- # 3. Deploy
756
- hostfn deploy production
757
-
758
- # 4. Setup SSL
759
- hostfn ssl setup production api.example.com --email admin@example.com
760
- ```
761
-
762
- ---
763
-
764
- ### Scenario 2: Existing Project Migration
765
-
766
- ```bash
767
- # Already have PM2 running on server
768
- cd existing-app
769
-
770
- # Initialize hostfn config
771
- hostfn init --import-pm2
772
-
773
- # Deploy (will detect existing PM2 process)
774
- hostfn deploy production
775
- ```
776
-
777
- ---
778
-
779
- ### Scenario 3: Monorepo with Multiple Services
780
-
781
- ```bash
782
- # hostfn.config.json
783
- {
784
- "services": {
785
- "api": { "port": 3000, "path": "services/api" },
786
- "worker": { "port": 3001, "path": "services/worker" },
787
- "admin": { "port": 3002, "path": "services/admin" }
788
- }
789
- }
790
-
791
- # Deploy all services
792
- hostfn deploy production --all
793
-
794
- # Deploy only API
795
- hostfn deploy production --service api
796
- ```
797
-
798
- ---
799
-
800
- ### Scenario 4: CI/CD Setup
801
-
802
- ```bash
803
- # Generate GitHub Actions workflow
804
- hostfn init --ci github
805
-
806
- # This creates .github/workflows/deploy.yml
807
- # Add secrets to GitHub repo:
808
- # - DEPLOY_SSH_KEY
809
- # - DEPLOY_HOST
810
- # - DATABASE_URL (and other env vars)
811
-
812
- # Push to main → auto-deploys
813
- git push origin main
814
- ```
815
-
816
- ---
817
-
818
- ## Success Metrics
819
-
820
- 1. **Developer Experience:**
821
- - First deployment in < 5 minutes (after server setup)
822
- - Zero-downtime deployments
823
- - Clear error messages and rollback on failure
824
-
825
- 2. **Reliability:**
826
- - Health checks prevent bad deployments
827
- - Auto-rollback on failure
828
- - Backup system for easy recovery
829
-
830
- 3. **Flexibility:**
831
- - Works with any Node.js framework
832
- - Supports any Linux VPS provider
833
- - Customizable via config file
834
-
835
- 4. **Production Ready:**
836
- - SSL support out-of-the-box
837
- - Environment variable management
838
- - Monitoring and logging
839
-
840
- ---
841
-
842
- ## Future Enhancements (v2+)
843
-
844
- 1. **Multi-Language Support (Priority):**
845
- - Python runtime adapter (Flask, FastAPI, Django)
846
- - Go runtime adapter (compiled binaries + systemd)
847
- - Ruby runtime adapter (Rails, Sinatra + puma)
848
- - Rust runtime adapter (compiled binaries + systemd)
849
- - PHP runtime adapter (Laravel, Symfony + php-fpm)
850
- - Docker runtime adapter (universal container support)
851
-
852
- 2. **Multi-Cloud Support:**
853
- - Auto-provision VPS on AWS Lightsail, DigitalOcean, Linode
854
- - `hostfn provision aws --size 1gb` → creates and configures VPS
855
-
856
- 3. **Load Balancing:**
857
- - Deploy to multiple servers
858
- - Automatic Nginx load balancer setup
859
- - Health-check based routing
860
-
861
- 4. **Database Management:**
862
- - Built-in PostgreSQL/MySQL setup
863
- - Automated backups
864
- - Connection pooling configuration
865
-
866
- 5. **Monitoring Dashboard:**
867
- - Web UI for deployment history
868
- - Real-time logs and metrics
869
- - Alerts on deployment failures
870
-
871
- 6. **Plugin System:**
872
- - Custom deployment hooks
873
- - Runtime-specific optimizations
874
- - Third-party integrations
875
- - Community runtime adapters
876
-
877
- ---
878
-
879
- ## Testing Strategy
880
-
881
- ### Unit Tests
882
- - Config validation
883
- - SSH connection mocking
884
- - Deployment logic (dry-run mode)
885
- - Health check logic
886
-
887
- ### Integration Tests
888
- - Deploy to test VPS
889
- - Multi-service deployment
890
- - Rollback scenarios
891
- - Environment variable management
892
-
893
- ### E2E Tests
894
- - Full deployment flow
895
- - CI/CD workflow simulation
896
- - Multi-environment setup
897
-
898
- ---
899
-
900
- ## Documentation Plan
901
-
902
- 1. **Getting Started Guide:**
903
- - Installation
904
- - First deployment tutorial
905
- - Common use cases
906
-
907
- 2. **Configuration Reference:**
908
- - All config options explained
909
- - Examples for different frameworks
910
-
911
- 3. **CI/CD Integration:**
912
- - GitHub Actions
913
- - GitLab CI
914
- - Bitbucket Pipelines
915
- - Generic CI setup
916
-
917
- 4. **Troubleshooting:**
918
- - Common errors
919
- - SSH issues
920
- - Deployment failures
921
- - Performance tuning
922
-
923
- 5. **API Reference:**
924
- - All CLI commands
925
- - Options and flags
926
- - Exit codes
927
-
928
- ---
929
-
930
- ## Open Questions
931
-
932
- 1. **Runtime Adapter API:** What should the minimal interface be for a runtime adapter?
933
- 2. **Build Optimization:** Should we support building locally and deploying artifacts only?
934
- 3. **Multi-Region:** How to handle multi-region deployments?
935
- 4. **Secrets Management:** Integration with vault services (AWS Secrets Manager, HashiCorp Vault)?
936
- 5. **Monitoring:** Should we integrate with monitoring services (Sentry, DataDog)?
937
- 6. **Polyglot Projects:** How to handle projects with multiple runtimes (e.g., Node.js + Python workers)?
938
-
939
- ---
940
-
941
- ## Dependencies
942
-
943
- ### CLI Package
944
- ```json
945
- {
946
- "dependencies": {
947
- "commander": "^11.0.0",
948
- "chalk": "^5.3.0",
949
- "ora": "^7.0.1",
950
- "inquirer": "^9.2.0",
951
- "zod": "^3.22.0",
952
- "ssh2": "^1.15.0",
953
- "node-rsync": "^0.6.1",
954
- "dotenv": "^16.3.0",
955
- "execa": "^8.0.1"
956
- },
957
- "devDependencies": {
958
- "typescript": "^5.3.0",
959
- "vitest": "^1.0.0",
960
- "@types/node": "^20.0.0",
961
- "@types/ssh2": "^1.15.0",
962
- "@types/inquirer": "^9.0.0"
963
- }
964
- }
965
- ```
966
-
967
- ---
968
-
969
- ## Risks & Mitigations
970
-
971
- | Risk | Impact | Mitigation |
972
- |------|--------|------------|
973
- | SSH authentication failures | High | Support multiple auth methods, clear error messages |
974
- | Network timeouts during deployment | Medium | Configurable timeouts, retry logic |
975
- | PM2 process conflicts | Medium | Detect existing processes, graceful handling |
976
- | Nginx config errors | High | Validate config before applying, backup original |
977
- | Health check false negatives | Medium | Configurable retries, multiple check strategies |
978
- | Rollback failures | High | Keep backups separate, test rollback in CI |
979
-
980
- ---
981
-
982
- ## Success Criteria
983
-
984
- **MVP (Minimum Viable Product):**
985
- - ✅ Can setup fresh server with one command
986
- - ✅ Can deploy Node.js app (Express/Hono) with zero-downtime
987
- - ✅ Health checks prevent bad deployments
988
- - ✅ Auto-rollback on failure
989
- - ✅ Environment variable management
990
- - ✅ CI/CD mode works in GitHub Actions
991
- - ✅ Clear documentation and examples
992
-
993
- **V1.0 Ready:**
994
- - ✅ All MVP features
995
- - ✅ SSL setup with Let's Encrypt
996
- - ✅ Multi-service support (monorepos)
997
- - ✅ Comprehensive logging
998
- - ✅ Tested on Ubuntu, Debian, Amazon Linux
999
- - ✅ 90%+ test coverage
1000
- - ✅ Production-ready documentation
1001
-
1002
- ---
1003
-
1004
- ## Timeline Estimate
1005
-
1006
- - **Phase 1 (Core):** 4-5 hours
1007
- - **Phase 2 (Server Setup):** 2-3 hours
1008
- - **Phase 3 (Deployment):** 3-4 hours
1009
- - **Phase 4 (Monitoring):** 1-2 hours
1010
- - **Phase 5 (Advanced):** 2-3 hours (optional)
1011
- - **Testing & Docs:** 2-3 hours
1012
-
1013
- **Total MVP:** 12-17 hours
1014
- **Total V1.0:** 15-20 hours
1015
-
1016
- ---
1017
-
1018
- ## Conclusion
1019
-
1020
- **hostfn** will democratize VPS deployments by providing PaaS-like simplicity with full control and economics. It fills a critical gap between expensive managed platforms and complex manual deployments, making it accessible for solo developers while being powerful enough for production applications.
1021
-
1022
- The **pluggable runtime adapter architecture** ensures extensibility across languages and frameworks, while maintaining the zero-config philosophy that keeps the initial learning curve minimal. Starting with Node.js support in v1.0, the foundation is built to easily expand to Python, Go, Ruby, Rust, and beyond.
1023
-
1024
- ---
1025
-
1026
- **Next Steps:**
1027
- 1. Review and approve this specification
1028
- 2. Setup monorepo structure at `~/dev/functions/hostfn`
1029
- 3. Begin Phase 1 implementation
1030
- 4. Create example projects for testing
1031
- 5. Write comprehensive documentation
1032
-
1033
- ---
1034
-
1035
- **Questions? Feedback?**
1036
- Please review and provide feedback on:
1037
- - Architecture decisions
1038
- - Command structure
1039
- - Configuration schema
1040
- - Missing features
1041
- - Priority of phases