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.
- package/dist/__tests__/core/backup.test.d.ts +2 -0
- package/dist/__tests__/core/backup.test.d.ts.map +1 -0
- package/dist/__tests__/core/backup.test.js +108 -0
- package/dist/__tests__/core/backup.test.js.map +1 -0
- package/dist/__tests__/core/health.test.d.ts +2 -0
- package/dist/__tests__/core/health.test.d.ts.map +1 -0
- package/dist/__tests__/core/health.test.js +97 -0
- package/dist/__tests__/core/health.test.js.map +1 -0
- package/dist/__tests__/core/lock.test.d.ts +2 -0
- package/dist/__tests__/core/lock.test.d.ts.map +1 -0
- package/dist/__tests__/core/lock.test.js +136 -0
- package/dist/__tests__/core/lock.test.js.map +1 -0
- package/dist/__tests__/core/nginx-multi-domain.test.d.ts +2 -0
- package/dist/__tests__/core/nginx-multi-domain.test.d.ts.map +1 -0
- package/dist/__tests__/core/nginx-multi-domain.test.js +158 -0
- package/dist/__tests__/core/nginx-multi-domain.test.js.map +1 -0
- package/dist/__tests__/runtimes/pm2.test.d.ts +2 -0
- package/dist/__tests__/runtimes/pm2.test.d.ts.map +1 -0
- package/dist/__tests__/runtimes/pm2.test.js +111 -0
- package/dist/__tests__/runtimes/pm2.test.js.map +1 -0
- package/dist/__tests__/utils/validation.test.d.ts +2 -0
- package/dist/__tests__/utils/validation.test.d.ts.map +1 -0
- package/dist/__tests__/utils/validation.test.js +136 -0
- package/dist/__tests__/utils/validation.test.js.map +1 -0
- package/dist/commands/deploy.d.ts +11 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +636 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/env.d.ts +21 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +317 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/expose.d.ts +6 -0
- package/dist/commands/expose.d.ts.map +1 -0
- package/dist/commands/expose.js +379 -0
- package/dist/commands/expose.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +175 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logs.d.ts +10 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +75 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/rollback.d.ts +6 -0
- package/dist/commands/rollback.d.ts.map +1 -0
- package/dist/commands/rollback.js +113 -0
- package/dist/commands/rollback.js.map +1 -0
- package/dist/commands/server/info.d.ts +2 -0
- package/dist/commands/server/info.d.ts.map +1 -0
- package/dist/commands/server/info.js +104 -0
- package/dist/commands/server/info.js.map +1 -0
- package/dist/commands/server/setup.d.ts +11 -0
- package/dist/commands/server/setup.d.ts.map +1 -0
- package/dist/commands/server/setup.js +161 -0
- package/dist/commands/server/setup.js.map +1 -0
- package/dist/commands/status.d.ts +6 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +120 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/config/loader.d.ts +21 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +54 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +323 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +108 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/backup.d.ts +34 -0
- package/dist/core/backup.d.ts.map +1 -0
- package/dist/core/backup.js +95 -0
- package/dist/core/backup.js.map +1 -0
- package/dist/core/health.d.ts +31 -0
- package/dist/core/health.d.ts.map +1 -0
- package/dist/core/health.js +78 -0
- package/dist/core/health.js.map +1 -0
- package/dist/core/local.d.ts +19 -0
- package/dist/core/local.d.ts.map +1 -0
- package/dist/core/local.js +50 -0
- package/dist/core/local.js.map +1 -0
- package/dist/core/lock.d.ts +28 -0
- package/dist/core/lock.d.ts.map +1 -0
- package/dist/core/lock.js +89 -0
- package/dist/core/lock.js.map +1 -0
- package/dist/core/nginx.d.ts +43 -0
- package/dist/core/nginx.d.ts.map +1 -0
- package/dist/core/nginx.js +131 -0
- package/dist/core/nginx.js.map +1 -0
- package/dist/core/ssh.d.ts +79 -0
- package/dist/core/ssh.d.ts.map +1 -0
- package/dist/core/ssh.js +264 -0
- package/dist/core/ssh.js.map +1 -0
- package/dist/core/sync.d.ts +25 -0
- package/dist/core/sync.d.ts.map +1 -0
- package/dist/core/sync.js +117 -0
- package/dist/core/sync.js.map +1 -0
- package/dist/core/workspace.d.ts +13 -0
- package/dist/core/workspace.d.ts.map +1 -0
- package/dist/core/workspace.js +141 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +232 -0
- package/dist/index.js.map +1 -0
- package/dist/runtimes/base.d.ts +115 -0
- package/dist/runtimes/base.d.ts.map +1 -0
- package/dist/runtimes/base.js +16 -0
- package/dist/runtimes/base.js.map +1 -0
- package/dist/runtimes/nodejs/detector.d.ts +47 -0
- package/dist/runtimes/nodejs/detector.d.ts.map +1 -0
- package/dist/runtimes/nodejs/detector.js +143 -0
- package/dist/runtimes/nodejs/detector.js.map +1 -0
- package/dist/runtimes/nodejs/index.d.ts +14 -0
- package/dist/runtimes/nodejs/index.d.ts.map +1 -0
- package/dist/runtimes/nodejs/index.js +213 -0
- package/dist/runtimes/nodejs/index.js.map +1 -0
- package/dist/runtimes/nodejs/pm2.d.ts +17 -0
- package/dist/runtimes/nodejs/pm2.d.ts.map +1 -0
- package/dist/runtimes/nodejs/pm2.js +60 -0
- package/dist/runtimes/nodejs/pm2.js.map +1 -0
- package/dist/runtimes/registry.d.ts +34 -0
- package/dist/runtimes/registry.d.ts.map +1 -0
- package/dist/runtimes/registry.js +58 -0
- package/dist/runtimes/registry.js.map +1 -0
- package/dist/utils/logger.d.ts +47 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +76 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/validation.d.ts +32 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +125 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +33 -16
- package/LICENSE +0 -21
- package/README.md +0 -1136
- package/_conduct/specs/1.v0.spec.md +0 -1041
- package/examples/express-api/package.json +0 -22
- package/examples/express-api/src/index.ts +0 -16
- package/examples/express-api/tsconfig.json +0 -11
- package/examples/github-actions-deploy.yml +0 -40
- package/examples/monorepo-config.json +0 -76
- package/examples/monorepo-multi-server-config.json +0 -74
- package/packages/cli/package.json +0 -40
- package/turbo.json +0 -24
- /package/{packages/cli/src → src}/__tests__/core/backup.test.ts +0 -0
- /package/{packages/cli/src → src}/__tests__/core/health.test.ts +0 -0
- /package/{packages/cli/src → src}/__tests__/core/lock.test.ts +0 -0
- /package/{packages/cli/src → src}/__tests__/core/nginx-multi-domain.test.ts +0 -0
- /package/{packages/cli/src → src}/__tests__/runtimes/pm2.test.ts +0 -0
- /package/{packages/cli/src → src}/__tests__/utils/validation.test.ts +0 -0
- /package/{packages/cli/src → src}/commands/deploy.ts +0 -0
- /package/{packages/cli/src → src}/commands/env.ts +0 -0
- /package/{packages/cli/src → src}/commands/expose.ts +0 -0
- /package/{packages/cli/src → src}/commands/init.ts +0 -0
- /package/{packages/cli/src → src}/commands/logs.ts +0 -0
- /package/{packages/cli/src → src}/commands/rollback.ts +0 -0
- /package/{packages/cli/src → src}/commands/server/info.ts +0 -0
- /package/{packages/cli/src → src}/commands/server/setup.ts +0 -0
- /package/{packages/cli/src → src}/commands/status.ts +0 -0
- /package/{packages/cli/src → src}/config/loader.ts +0 -0
- /package/{packages/cli/src → src}/config/schema.ts +0 -0
- /package/{packages/cli/src → src}/core/backup.ts +0 -0
- /package/{packages/cli/src → src}/core/health.ts +0 -0
- /package/{packages/cli/src → src}/core/local.ts +0 -0
- /package/{packages/cli/src → src}/core/lock.ts +0 -0
- /package/{packages/cli/src → src}/core/nginx.ts +0 -0
- /package/{packages/cli/src → src}/core/ssh.ts +0 -0
- /package/{packages/cli/src → src}/core/sync.ts +0 -0
- /package/{packages/cli/src → src}/core/workspace.ts +0 -0
- /package/{packages/cli/src → src}/index.ts +0 -0
- /package/{packages/cli/src → src}/runtimes/base.ts +0 -0
- /package/{packages/cli/src → src}/runtimes/nodejs/detector.ts +0 -0
- /package/{packages/cli/src → src}/runtimes/nodejs/index.ts +0 -0
- /package/{packages/cli/src → src}/runtimes/nodejs/pm2.ts +0 -0
- /package/{packages/cli/src → src}/runtimes/registry.ts +0 -0
- /package/{packages/cli/src → src}/utils/logger.ts +0 -0
- /package/{packages/cli/src → src}/utils/validation.ts +0 -0
- /package/{packages/cli/tsconfig.json → tsconfig.json} +0 -0
- /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
|