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
package/README.md
DELETED
|
@@ -1,1136 +0,0 @@
|
|
|
1
|
-
# hostfn
|
|
2
|
-
|
|
3
|
-
**Universal application deployment CLI** - Deploy Node.js applications to any VPS.
|
|
4
|
-
|
|
5
|
-
> Zero-downtime deployments • Health checks • Auto-rollback • PM2 integration • Nginx setup and SSL support
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Quick Start
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
# Initialize configuration
|
|
13
|
-
cd your-project
|
|
14
|
-
hostfn init
|
|
15
|
-
|
|
16
|
-
# Setup server (Requires ssh keys pre-configured)
|
|
17
|
-
hostfn server setup username@your-server.com
|
|
18
|
-
|
|
19
|
-
# Deploy to production
|
|
20
|
-
hostfn deploy production
|
|
21
|
-
|
|
22
|
-
# Expose via Nginx, provision SSL certificate(s)
|
|
23
|
-
hostfn expose production
|
|
24
|
-
|
|
25
|
-
# Monitor your app
|
|
26
|
-
hostfn status production
|
|
27
|
-
hostfn logs production
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## Table of Contents
|
|
33
|
-
|
|
34
|
-
- [Installation](#installation)
|
|
35
|
-
- [Getting Started](#getting-started)
|
|
36
|
-
- [Configuration](#configuration)
|
|
37
|
-
- [Single Application](#single-application)
|
|
38
|
-
- [Monorepo / Multi-Service](#monorepo--multi-service)
|
|
39
|
-
- [Commands Reference](#commands-reference)
|
|
40
|
-
- [Deployment Strategies](#deployment-strategies)
|
|
41
|
-
- [Advanced Topics](#advanced-topics)
|
|
42
|
-
- [Examples](#examples)
|
|
43
|
-
- [Architecture](#architecture)
|
|
44
|
-
- [Development](#development)
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
## Installation
|
|
48
|
-
|
|
49
|
-
### via npm
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
npm install -g hostfn
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### via source
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
# Clone repository
|
|
59
|
-
cd hostfn/
|
|
60
|
-
# Install dependencies
|
|
61
|
-
npm install
|
|
62
|
-
# Build the project
|
|
63
|
-
npm run build
|
|
64
|
-
cd packages/cli
|
|
65
|
-
npm link
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Using the CLI
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
# After linking
|
|
72
|
-
hostfn --version
|
|
73
|
-
hostfn --help
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Getting Started
|
|
79
|
-
|
|
80
|
-
### 1. Initialize Your Project
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
cd your-project
|
|
84
|
-
hostfn init
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
This creates `hostfn.config.json` with smart defaults detected from your project.
|
|
88
|
-
|
|
89
|
-
### 2. Setup Your Server
|
|
90
|
-
|
|
91
|
-
For the next steps to work, the ssh keys should configured on the machine where hostfn CLI is being used.
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
eval "$(ssh-agent -s)"
|
|
95
|
-
ssh-add ~/.ssh/your-private-key
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
If ssh-agent or default ssh config is not available, you can set the SSH key and passphrase manually:
|
|
99
|
-
```bash
|
|
100
|
-
export HOSTFN_SSH_PASSPHRASE="your-passphrase"
|
|
101
|
-
export HOSTFN_SSH_KEY=$(cat ~/.ssh/your-private-key.pem | base64)
|
|
102
|
-
hostfn <command> <environment>
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
hostfn server setup ubuntu@your-server.com
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
This installs:
|
|
110
|
-
- Node.js (via nvm)
|
|
111
|
-
- PM2 (process manager)
|
|
112
|
-
- Required system dependencies
|
|
113
|
-
|
|
114
|
-
### 3. Setup environment variables and deploy
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
hostfn env push production .env.production
|
|
118
|
-
```
|
|
119
|
-
This uploads your local `.env.production` file to the server.
|
|
120
|
-
To update an individual env value, use `hostfn env set <environment> <key> <value>` instead.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
hostfn deploy <environment>
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
Deploy command will run the application with:
|
|
128
|
-
- PM2 managing the process
|
|
129
|
-
- Automatic restarts on crashes
|
|
130
|
-
- Health checks ensuring readiness
|
|
131
|
-
- Backup created for rollback
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
### 4. Expose the application
|
|
135
|
-
|
|
136
|
-
```bash
|
|
137
|
-
hostfn expose <environment>
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
This will expose the application via Nginx, provision SSL certificate(s) and create a DNS record.
|
|
141
|
-
|
|
142
|
-
### 5. Monitor the application
|
|
143
|
-
|
|
144
|
-
```bash
|
|
145
|
-
hostfn status <environment>
|
|
146
|
-
hostfn logs <environment>
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## Configuration
|
|
152
|
-
|
|
153
|
-
### Single Application
|
|
154
|
-
|
|
155
|
-
Create `hostfn.config.json` in your project root:
|
|
156
|
-
|
|
157
|
-
```json
|
|
158
|
-
{
|
|
159
|
-
"name": "my-app",
|
|
160
|
-
"runtime": "nodejs",
|
|
161
|
-
"version": "18",
|
|
162
|
-
"environments": {
|
|
163
|
-
"production": {
|
|
164
|
-
"server": "ubuntu@prod.example.com",
|
|
165
|
-
"port": 3000,
|
|
166
|
-
"instances": "max",
|
|
167
|
-
"domain": "api.example.com",
|
|
168
|
-
"sslEmail": "admin@example.com"
|
|
169
|
-
},
|
|
170
|
-
"staging": {
|
|
171
|
-
"server": "ubuntu@staging.example.com",
|
|
172
|
-
"port": 3000,
|
|
173
|
-
"instances": 2,
|
|
174
|
-
"sslEmail": "admin@example.com",
|
|
175
|
-
"domain": ["domain1.example.com", "domain2.example.com"]
|
|
176
|
-
}
|
|
177
|
-
},
|
|
178
|
-
"build": {
|
|
179
|
-
"command": "npm run build",
|
|
180
|
-
"directory": "dist",
|
|
181
|
-
"nodeModules": "production"
|
|
182
|
-
},
|
|
183
|
-
"start": {
|
|
184
|
-
"command": "npm start",
|
|
185
|
-
"entry": "dist/index.js"
|
|
186
|
-
},
|
|
187
|
-
"health": {
|
|
188
|
-
"path": "/health",
|
|
189
|
-
"timeout": 60,
|
|
190
|
-
"retries": 10,
|
|
191
|
-
"interval": 3
|
|
192
|
-
},
|
|
193
|
-
"env": {
|
|
194
|
-
"required": ["NODE_ENV", "DATABASE_URL"],
|
|
195
|
-
"optional": ["REDIS_URL", "LOG_LEVEL"]
|
|
196
|
-
},
|
|
197
|
-
"sync": {
|
|
198
|
-
"exclude": [
|
|
199
|
-
"node_modules",
|
|
200
|
-
".git",
|
|
201
|
-
"dist",
|
|
202
|
-
".env",
|
|
203
|
-
"*.log"
|
|
204
|
-
]
|
|
205
|
-
},
|
|
206
|
-
"backup": {
|
|
207
|
-
"keep": 5
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### Monorepo / Multi-Service
|
|
213
|
-
|
|
214
|
-
Perfect for microservices architectures where each service lives in its own directory.
|
|
215
|
-
|
|
216
|
-
#### Strategy 1: All Services on Same Server
|
|
217
|
-
|
|
218
|
-
```json
|
|
219
|
-
{
|
|
220
|
-
"name": "my-monorepo",
|
|
221
|
-
"runtime": "nodejs",
|
|
222
|
-
"version": "18",
|
|
223
|
-
"environments": {
|
|
224
|
-
"production": {
|
|
225
|
-
"server": "ubuntu@shared-server.com",
|
|
226
|
-
"port": 3000,
|
|
227
|
-
"instances": "max"
|
|
228
|
-
}
|
|
229
|
-
},
|
|
230
|
-
"build": {
|
|
231
|
-
"command": "npm run build",
|
|
232
|
-
"directory": "dist"
|
|
233
|
-
},
|
|
234
|
-
"start": {
|
|
235
|
-
"command": "npm start"
|
|
236
|
-
},
|
|
237
|
-
"services": {
|
|
238
|
-
"account": {
|
|
239
|
-
"port": 3001,
|
|
240
|
-
"path": "services/account",
|
|
241
|
-
"domain": "account.example.com",
|
|
242
|
-
"instances": "max"
|
|
243
|
-
},
|
|
244
|
-
"auth": {
|
|
245
|
-
"port": 3002,
|
|
246
|
-
"path": "services/auth",
|
|
247
|
-
"domain": "auth.example.com",
|
|
248
|
-
"instances": 4
|
|
249
|
-
},
|
|
250
|
-
"notification": {
|
|
251
|
-
"port": 3003,
|
|
252
|
-
"path": "services/notification"
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
**Result**: All 3 services deploy to `ubuntu@shared-server.com`:
|
|
259
|
-
- `my-monorepo-account-production` on port 3001
|
|
260
|
-
- `my-monorepo-auth-production` on port 3002
|
|
261
|
-
- `my-monorepo-notification-production` on port 3003
|
|
262
|
-
|
|
263
|
-
#### Strategy 2: Services on Different Servers
|
|
264
|
-
|
|
265
|
-
```json
|
|
266
|
-
{
|
|
267
|
-
"name": "my-monorepo",
|
|
268
|
-
"runtime": "nodejs",
|
|
269
|
-
"version": "18",
|
|
270
|
-
"environments": {
|
|
271
|
-
"production": {
|
|
272
|
-
"server": "ubuntu@default-server.com",
|
|
273
|
-
"port": 3000,
|
|
274
|
-
"instances": "max"
|
|
275
|
-
}
|
|
276
|
-
},
|
|
277
|
-
"build": {
|
|
278
|
-
"command": "npm run build",
|
|
279
|
-
"directory": "dist"
|
|
280
|
-
},
|
|
281
|
-
"start": {
|
|
282
|
-
"command": "npm start"
|
|
283
|
-
},
|
|
284
|
-
"services": {
|
|
285
|
-
"account": {
|
|
286
|
-
"port": 3001,
|
|
287
|
-
"path": "services/account",
|
|
288
|
-
"server": "ubuntu@account-dedicated.com",
|
|
289
|
-
"instances": "max"
|
|
290
|
-
},
|
|
291
|
-
"auth": {
|
|
292
|
-
"port": 3002,
|
|
293
|
-
"path": "services/auth",
|
|
294
|
-
"server": "ubuntu@auth-dedicated.com",
|
|
295
|
-
"instances": 4
|
|
296
|
-
},
|
|
297
|
-
"notification": {
|
|
298
|
-
"port": 3003,
|
|
299
|
-
"path": "services/notification"
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
**Result**:
|
|
306
|
-
- `account` → `ubuntu@account-dedicated.com`
|
|
307
|
-
- `auth` → `ubuntu@auth-dedicated.com`
|
|
308
|
-
- `notification` → `ubuntu@default-server.com` (fallback)
|
|
309
|
-
|
|
310
|
-
**Perfect for:**
|
|
311
|
-
- Isolating critical services (auth, payments)
|
|
312
|
-
- Dedicated resources for high-traffic services
|
|
313
|
-
- Geographic distribution
|
|
314
|
-
- Security/compliance requirements
|
|
315
|
-
|
|
316
|
-
### Configuration Schema
|
|
317
|
-
|
|
318
|
-
#### Root Fields
|
|
319
|
-
|
|
320
|
-
| Field | Type | Required | Description |
|
|
321
|
-
|-------|------|----------|-------------|
|
|
322
|
-
| `name` | `string` | ✅ | Application name |
|
|
323
|
-
| `runtime` | `'nodejs' \| 'python' \| 'go' \| 'ruby' \| 'rust' \| 'docker'` | ✅ | Runtime (only nodejs supported currently) |
|
|
324
|
-
| `version` | `string` | ✅ | Runtime version |
|
|
325
|
-
| `environments` | `object` | ✅ | Environment configurations |
|
|
326
|
-
| `build` | `object` | ❌ | Build configuration |
|
|
327
|
-
| `start` | `object` | ✅ | Start configuration |
|
|
328
|
-
| `health` | `object` | ❌ | Health check configuration |
|
|
329
|
-
| `env` | `object` | ❌ | Environment variable requirements |
|
|
330
|
-
| `sync` | `object` | ❌ | File sync configuration |
|
|
331
|
-
| `backup` | `object` | ❌ | Backup retention configuration |
|
|
332
|
-
| `services` | `object` | ❌ | Multi-service configuration (monorepo) |
|
|
333
|
-
|
|
334
|
-
#### Environment Configuration
|
|
335
|
-
|
|
336
|
-
```typescript
|
|
337
|
-
{
|
|
338
|
-
server: string; // SSH connection (user@host)
|
|
339
|
-
port: number; // Service port
|
|
340
|
-
instances: number | 'max'; // PM2 instances (default: 1)
|
|
341
|
-
domain?: string; // Domain name
|
|
342
|
-
sslEmail?: string; // Email for SSL certificate
|
|
343
|
-
}
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
#### Service Configuration (Monorepo)
|
|
347
|
-
|
|
348
|
-
```typescript
|
|
349
|
-
{
|
|
350
|
-
port: number; // Service port (required)
|
|
351
|
-
path: string; // Path in monorepo (required)
|
|
352
|
-
domain?: string; // Custom domain
|
|
353
|
-
server?: string; // Override environment server
|
|
354
|
-
instances?: number | 'max'; // Override PM2 instances
|
|
355
|
-
}
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
---
|
|
359
|
-
|
|
360
|
-
## Commands Reference
|
|
361
|
-
|
|
362
|
-
### Initialize
|
|
363
|
-
|
|
364
|
-
```bash
|
|
365
|
-
hostfn init
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
Interactive setup that:
|
|
369
|
-
- Detects your project runtime
|
|
370
|
-
- Prompts for configuration
|
|
371
|
-
- Creates `hostfn.config.json`
|
|
372
|
-
|
|
373
|
-
### Server Management
|
|
374
|
-
|
|
375
|
-
```bash
|
|
376
|
-
# Setup a new server
|
|
377
|
-
hostfn server setup ubuntu@your-server.com [options]
|
|
378
|
-
--env <environment> Environment name (default: production)
|
|
379
|
-
--node-version <version> Node.js version (default: 18)
|
|
380
|
-
--port <port> Service port (default: 3000)
|
|
381
|
-
--redis Install Redis
|
|
382
|
-
--password <password> SSH password (if not using key auth)
|
|
383
|
-
|
|
384
|
-
# View server information
|
|
385
|
-
hostfn server info ubuntu@your-server.com
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
### Deployment
|
|
389
|
-
|
|
390
|
-
```bash
|
|
391
|
-
# Deploy to an environment
|
|
392
|
-
hostfn deploy [environment] [options]
|
|
393
|
-
[environment] Environment to deploy to (default: production)
|
|
394
|
-
--host <host> Override server host
|
|
395
|
-
--ci CI/CD mode (non-interactive)
|
|
396
|
-
--dry-run Show what would be deployed
|
|
397
|
-
--service <name> Deploy specific service (monorepo)
|
|
398
|
-
--all Deploy all services (monorepo)
|
|
399
|
-
|
|
400
|
-
# Examples
|
|
401
|
-
hostfn deploy production
|
|
402
|
-
hostfn deploy staging --dry-run
|
|
403
|
-
hostfn deploy prod --ci
|
|
404
|
-
hostfn deploy production --service account
|
|
405
|
-
hostfn deploy production --all
|
|
406
|
-
hostfn deploy production --local --ci # Self-hosted runner
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
### Monitoring
|
|
410
|
-
|
|
411
|
-
```bash
|
|
412
|
-
# View application status
|
|
413
|
-
hostfn status [environment] [options]
|
|
414
|
-
[environment] Environment (default: production)
|
|
415
|
-
--service <name> Show specific service status (monorepo)
|
|
416
|
-
|
|
417
|
-
# View logs
|
|
418
|
-
hostfn logs [environment] [options]
|
|
419
|
-
[environment] Environment (default: production)
|
|
420
|
-
--lines <n> Number of lines (default: 100)
|
|
421
|
-
--errors Show only errors
|
|
422
|
-
--output <file> Save logs to file
|
|
423
|
-
--service <name> View specific service logs (monorepo)
|
|
424
|
-
|
|
425
|
-
# Examples
|
|
426
|
-
hostfn status production
|
|
427
|
-
hostfn status prod --service account
|
|
428
|
-
hostfn logs production --lines 500
|
|
429
|
-
hostfn logs prod --service auth --errors
|
|
430
|
-
hostfn logs production --output debug.log
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
### Rollback
|
|
434
|
-
|
|
435
|
-
```bash
|
|
436
|
-
# Rollback to previous deployment
|
|
437
|
-
hostfn rollback [environment] [options]
|
|
438
|
-
[environment] Environment (default: production)
|
|
439
|
-
--to <timestamp> Rollback to specific backup
|
|
440
|
-
|
|
441
|
-
# Examples
|
|
442
|
-
hostfn rollback production # Interactive selection
|
|
443
|
-
hostfn rollback prod --to 20240115-120000
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
### Environment Variables
|
|
447
|
-
|
|
448
|
-
```bash
|
|
449
|
-
# List environment variables (masked)
|
|
450
|
-
hostfn env list <environment>
|
|
451
|
-
|
|
452
|
-
# Set a variable
|
|
453
|
-
hostfn env set <environment> <key> <value>
|
|
454
|
-
|
|
455
|
-
# Upload .env file
|
|
456
|
-
hostfn env push <environment> <file>
|
|
457
|
-
|
|
458
|
-
# Download .env file
|
|
459
|
-
hostfn env pull <environment> <file>
|
|
460
|
-
|
|
461
|
-
# Validate required variables
|
|
462
|
-
hostfn env validate <environment>
|
|
463
|
-
|
|
464
|
-
# Examples
|
|
465
|
-
hostfn env list production
|
|
466
|
-
hostfn env set prod DATABASE_URL "postgresql://..."
|
|
467
|
-
hostfn env push production .env.production
|
|
468
|
-
hostfn env pull production .env.backup
|
|
469
|
-
hostfn env validate production
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
---
|
|
473
|
-
|
|
474
|
-
## CI/CD Integration
|
|
475
|
-
|
|
476
|
-
### GitHub Actions
|
|
477
|
-
|
|
478
|
-
#### Remote Deployment (Standard CI/CD)
|
|
479
|
-
|
|
480
|
-
For deploying from GitHub Actions to a remote server:
|
|
481
|
-
|
|
482
|
-
```yaml
|
|
483
|
-
name: Deploy
|
|
484
|
-
|
|
485
|
-
on:
|
|
486
|
-
push:
|
|
487
|
-
branches: [main]
|
|
488
|
-
|
|
489
|
-
jobs:
|
|
490
|
-
deploy:
|
|
491
|
-
runs-on: ubuntu-latest
|
|
492
|
-
|
|
493
|
-
steps:
|
|
494
|
-
- uses: actions/checkout@v4
|
|
495
|
-
|
|
496
|
-
- name: Setup Node.js
|
|
497
|
-
uses: actions/setup-node@v4
|
|
498
|
-
with:
|
|
499
|
-
node-version: '20'
|
|
500
|
-
|
|
501
|
-
- name: Install hostfn
|
|
502
|
-
run: npm install -g hostfn
|
|
503
|
-
|
|
504
|
-
- name: Deploy
|
|
505
|
-
env:
|
|
506
|
-
HOSTFN_SSH_KEY: ${{ secrets.HOSTFN_SSH_KEY }}
|
|
507
|
-
HOSTFN_SSH_PASSPHRASE: ${{ secrets.HOSTFN_SSH_PASSPHRASE }}
|
|
508
|
-
run: hostfn deploy production --ci
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
**Setup GitHub Secrets:**
|
|
512
|
-
|
|
513
|
-
1. Generate base64-encoded SSH key:
|
|
514
|
-
```bash
|
|
515
|
-
cat ~/.ssh/your_key | base64
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
2. Add to GitHub repository secrets:
|
|
519
|
-
- `HOSTFN_SSH_KEY`: Base64-encoded private key
|
|
520
|
-
- `HOSTFN_SSH_PASSPHRASE`: SSH key passphrase (if any)
|
|
521
|
-
|
|
522
|
-
#### Self-Hosted Runner (Local Deployment)
|
|
523
|
-
|
|
524
|
-
For deploying on a self-hosted GitHub Actions runner running on your deployment server:
|
|
525
|
-
|
|
526
|
-
```yaml
|
|
527
|
-
name: Deploy
|
|
528
|
-
|
|
529
|
-
on:
|
|
530
|
-
push:
|
|
531
|
-
branches: [main]
|
|
532
|
-
|
|
533
|
-
jobs:
|
|
534
|
-
deploy:
|
|
535
|
-
runs-on: self-hosted
|
|
536
|
-
|
|
537
|
-
steps:
|
|
538
|
-
- uses: actions/checkout@v4
|
|
539
|
-
|
|
540
|
-
- name: Deploy locally
|
|
541
|
-
run: hostfn deploy production --local --ci
|
|
542
|
-
```
|
|
543
|
-
|
|
544
|
-
**Why `--local` mode?**
|
|
545
|
-
- No SSH needed (already on the server)
|
|
546
|
-
- Faster deployment (no network transfer)
|
|
547
|
-
- Uses local file operations instead of rsync
|
|
548
|
-
- Perfect for self-hosted runners
|
|
549
|
-
|
|
550
|
-
### Environment Variables
|
|
551
|
-
|
|
552
|
-
**For CI/CD:**
|
|
553
|
-
- `HOSTFN_SSH_KEY`: Base64-encoded SSH private key
|
|
554
|
-
- `HOSTFN_SSH_PASSPHRASE`: SSH key passphrase (optional)
|
|
555
|
-
- `HOSTFN_HOST`: Override server host
|
|
556
|
-
|
|
557
|
-
**In GitHub Actions, these are set automatically from secrets:**
|
|
558
|
-
```yaml
|
|
559
|
-
env:
|
|
560
|
-
HOSTFN_SSH_KEY: ${{ secrets.HOSTFN_SSH_KEY }}
|
|
561
|
-
HOSTFN_SSH_PASSPHRASE: ${{ secrets.HOSTFN_SSH_PASSPHRASE }}
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
**For local testing or other CI platforms:**
|
|
565
|
-
```bash
|
|
566
|
-
# Encode SSH key for GitHub secrets
|
|
567
|
-
cat ~/.ssh/id_rsa | base64
|
|
568
|
-
|
|
569
|
-
# Then add to GitHub secrets via repository settings
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
### Other CI/CD Platforms
|
|
573
|
-
|
|
574
|
-
**GitLab CI:**
|
|
575
|
-
```yaml
|
|
576
|
-
deploy:
|
|
577
|
-
stage: deploy
|
|
578
|
-
script:
|
|
579
|
-
- npm install -g hostfn
|
|
580
|
-
- hostfn deploy production --ci
|
|
581
|
-
variables:
|
|
582
|
-
HOSTFN_SSH_KEY: $CI_SSH_KEY
|
|
583
|
-
HOSTFN_SSH_PASSPHRASE: $CI_SSH_PASSPHRASE
|
|
584
|
-
only:
|
|
585
|
-
- main
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
**CircleCI:**
|
|
589
|
-
```yaml
|
|
590
|
-
deploy:
|
|
591
|
-
docker:
|
|
592
|
-
- image: node:20
|
|
593
|
-
steps:
|
|
594
|
-
- checkout
|
|
595
|
-
- run: npm install -g hostfn
|
|
596
|
-
- run: hostfn deploy production --ci
|
|
597
|
-
environment:
|
|
598
|
-
HOSTFN_SSH_KEY: $HOSTFN_SSH_KEY
|
|
599
|
-
HOSTFN_SSH_PASSPHRASE: $HOSTFN_SSH_PASSPHRASE
|
|
600
|
-
```
|
|
601
|
-
|
|
602
|
-
---
|
|
603
|
-
|
|
604
|
-
## Deployment Strategies
|
|
605
|
-
|
|
606
|
-
### Single Application
|
|
607
|
-
|
|
608
|
-
Perfect for:
|
|
609
|
-
- Simple APIs or web apps
|
|
610
|
-
- Monolithic applications
|
|
611
|
-
- Single-service projects
|
|
612
|
-
|
|
613
|
-
```json
|
|
614
|
-
{
|
|
615
|
-
"name": "my-api",
|
|
616
|
-
"runtime": "nodejs",
|
|
617
|
-
"version": "18",
|
|
618
|
-
"environments": {
|
|
619
|
-
"production": {
|
|
620
|
-
"server": "ubuntu@prod.com",
|
|
621
|
-
"port": 3000,
|
|
622
|
-
"instances": "max"
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
### Monorepo: All Services on Same Server
|
|
629
|
-
|
|
630
|
-
Perfect for:
|
|
631
|
-
- Development/staging environments
|
|
632
|
-
- Small to medium applications
|
|
633
|
-
- Cost-effective deployments
|
|
634
|
-
- Services that don't need isolation
|
|
635
|
-
|
|
636
|
-
```json
|
|
637
|
-
{
|
|
638
|
-
"environments": {
|
|
639
|
-
"production": {
|
|
640
|
-
"server": "ubuntu@shared.com"
|
|
641
|
-
}
|
|
642
|
-
},
|
|
643
|
-
"services": {
|
|
644
|
-
"api": { "port": 3001, "path": "services/api" },
|
|
645
|
-
"worker": { "port": 3002, "path": "services/worker" },
|
|
646
|
-
"admin": { "port": 3003, "path": "services/admin" }
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
```
|
|
650
|
-
|
|
651
|
-
**Deployment:**
|
|
652
|
-
```bash
|
|
653
|
-
hostfn deploy production # Deploys all 3 services
|
|
654
|
-
hostfn deploy production --service api # Deploys just api
|
|
655
|
-
```
|
|
656
|
-
|
|
657
|
-
### Monorepo: Services on Different Servers
|
|
658
|
-
|
|
659
|
-
Perfect for:
|
|
660
|
-
- Production environments
|
|
661
|
-
- High-traffic services needing dedicated resources
|
|
662
|
-
- Critical service isolation (auth, payments)
|
|
663
|
-
- Geographic distribution
|
|
664
|
-
- Security/compliance requirements
|
|
665
|
-
|
|
666
|
-
```json
|
|
667
|
-
{
|
|
668
|
-
"environments": {
|
|
669
|
-
"production": {
|
|
670
|
-
"server": "ubuntu@default.com"
|
|
671
|
-
}
|
|
672
|
-
},
|
|
673
|
-
"services": {
|
|
674
|
-
"api": {
|
|
675
|
-
"port": 3001,
|
|
676
|
-
"path": "services/api",
|
|
677
|
-
"instances": "max"
|
|
678
|
-
},
|
|
679
|
-
"auth": {
|
|
680
|
-
"port": 3002,
|
|
681
|
-
"path": "services/auth",
|
|
682
|
-
"server": "ubuntu@auth-dedicated.com",
|
|
683
|
-
"instances": 4
|
|
684
|
-
},
|
|
685
|
-
"payment": {
|
|
686
|
-
"port": 3003,
|
|
687
|
-
"path": "services/payment",
|
|
688
|
-
"server": "ubuntu@pci-compliant.com",
|
|
689
|
-
"instances": 2
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
```
|
|
694
|
-
|
|
695
|
-
**Result:**
|
|
696
|
-
- `api` → `ubuntu@default.com` (shared server)
|
|
697
|
-
- `auth` → `ubuntu@auth-dedicated.com` (dedicated)
|
|
698
|
-
- `payment` → `ubuntu@pci-compliant.com` (isolated for compliance)
|
|
699
|
-
|
|
700
|
-
### Hybrid Approach
|
|
701
|
-
|
|
702
|
-
Mix shared and dedicated servers based on needs:
|
|
703
|
-
|
|
704
|
-
```json
|
|
705
|
-
{
|
|
706
|
-
"services": {
|
|
707
|
-
"public-api": {
|
|
708
|
-
"port": 3001,
|
|
709
|
-
"path": "services/api",
|
|
710
|
-
"server": "ubuntu@public-edge.com",
|
|
711
|
-
"instances": "max"
|
|
712
|
-
},
|
|
713
|
-
"internal-api": {
|
|
714
|
-
"port": 3002,
|
|
715
|
-
"path": "services/internal"
|
|
716
|
-
},
|
|
717
|
-
"worker": {
|
|
718
|
-
"port": 3003,
|
|
719
|
-
"path": "services/worker",
|
|
720
|
-
"instances": 2
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
```
|
|
725
|
-
|
|
726
|
-
---
|
|
727
|
-
|
|
728
|
-
## Advanced Topics
|
|
729
|
-
|
|
730
|
-
### Deployment Flow
|
|
731
|
-
|
|
732
|
-
1. **Pre-flight Checks**
|
|
733
|
-
- Verify rsync availability
|
|
734
|
-
- Connect to server via SSH
|
|
735
|
-
- Check/create remote directory
|
|
736
|
-
- Acquire deployment lock
|
|
737
|
-
|
|
738
|
-
2. **File Sync**
|
|
739
|
-
- Sync files with rsync (respects `.exclude` patterns)
|
|
740
|
-
- Fast incremental transfers
|
|
741
|
-
|
|
742
|
-
3. **Remote Build**
|
|
743
|
-
- Install dependencies (`npm ci --production`)
|
|
744
|
-
- Run build command if specified
|
|
745
|
-
- Build output in configured directory
|
|
746
|
-
|
|
747
|
-
4. **Backup**
|
|
748
|
-
- Create timestamped backup of current deployment
|
|
749
|
-
- Keep N most recent backups (configurable)
|
|
750
|
-
|
|
751
|
-
5. **PM2 Deployment**
|
|
752
|
-
- Generate PM2 ecosystem config
|
|
753
|
-
- Start new process or reload existing (zero-downtime)
|
|
754
|
-
- Save PM2 configuration
|
|
755
|
-
|
|
756
|
-
6. **Health Check**
|
|
757
|
-
- Poll health endpoint with retries
|
|
758
|
-
- Configurable timeout and interval
|
|
759
|
-
- Fail deployment if unhealthy
|
|
760
|
-
|
|
761
|
-
7. **Auto-Rollback** (on failure)
|
|
762
|
-
- Restore previous deployment from backup
|
|
763
|
-
- Reload PM2 with old version
|
|
764
|
-
- Report rollback status
|
|
765
|
-
|
|
766
|
-
### Directory Structure on Server
|
|
767
|
-
|
|
768
|
-
Single application:
|
|
769
|
-
```
|
|
770
|
-
/var/www/
|
|
771
|
-
└── my-app-production/
|
|
772
|
-
├── .env
|
|
773
|
-
├── package.json
|
|
774
|
-
├── node_modules/
|
|
775
|
-
├── dist/
|
|
776
|
-
└── ecosystem.config.cjs
|
|
777
|
-
```
|
|
778
|
-
|
|
779
|
-
Monorepo (multi-service):
|
|
780
|
-
```
|
|
781
|
-
/var/www/
|
|
782
|
-
├── my-monorepo-account-production/
|
|
783
|
-
│ ├── .env
|
|
784
|
-
│ ├── package.json
|
|
785
|
-
│ ├── node_modules/
|
|
786
|
-
│ └── dist/
|
|
787
|
-
├── my-monorepo-auth-production/
|
|
788
|
-
│ ├── .env
|
|
789
|
-
│ ├── package.json
|
|
790
|
-
│ ├── node_modules/
|
|
791
|
-
│ └── dist/
|
|
792
|
-
└── my-monorepo-notification-production/
|
|
793
|
-
├── .env
|
|
794
|
-
├── package.json
|
|
795
|
-
├── node_modules/
|
|
796
|
-
└── dist/
|
|
797
|
-
```
|
|
798
|
-
|
|
799
|
-
### Service Naming Convention
|
|
800
|
-
|
|
801
|
-
- **Single app**: `{name}-{environment}`
|
|
802
|
-
- Example: `my-app-production`
|
|
803
|
-
|
|
804
|
-
- **Monorepo**: `{name}-{serviceName}-{environment}`
|
|
805
|
-
- Example: `21n-account-production`
|
|
806
|
-
|
|
807
|
-
### Health Check Implementation
|
|
808
|
-
|
|
809
|
-
Your application should expose a health endpoint:
|
|
810
|
-
|
|
811
|
-
```javascript
|
|
812
|
-
// Express example
|
|
813
|
-
app.get('/health', (req, res) => {
|
|
814
|
-
res.json({ status: 'ok' });
|
|
815
|
-
});
|
|
816
|
-
|
|
817
|
-
// Fastify example
|
|
818
|
-
fastify.get('/health', async (request, reply) => {
|
|
819
|
-
return { status: 'ok' };
|
|
820
|
-
});
|
|
821
|
-
```
|
|
822
|
-
|
|
823
|
-
Configure in `hostfn.config.json`:
|
|
824
|
-
```json
|
|
825
|
-
{
|
|
826
|
-
"health": {
|
|
827
|
-
"path": "/health",
|
|
828
|
-
"timeout": 60,
|
|
829
|
-
"retries": 10,
|
|
830
|
-
"interval": 3
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
```
|
|
834
|
-
|
|
835
|
-
### Environment Variables
|
|
836
|
-
|
|
837
|
-
hostfn automatically loads environment variables from a `.env` file on your server. The PM2 process manager is configured to read from `.env` in the deployment directory.
|
|
838
|
-
|
|
839
|
-
#### Option 1: Push .env file (Recommended)
|
|
840
|
-
```bash
|
|
841
|
-
hostfn env push production .env.production
|
|
842
|
-
```
|
|
843
|
-
|
|
844
|
-
This uploads your local `.env` file to the server. After deployment, PM2 will automatically load these variables.
|
|
845
|
-
|
|
846
|
-
#### Option 2: Set individual variables
|
|
847
|
-
```bash
|
|
848
|
-
hostfn env set production DATABASE_URL "postgresql://..."
|
|
849
|
-
hostfn env set production REDIS_URL "redis://..."
|
|
850
|
-
```
|
|
851
|
-
|
|
852
|
-
Note: After setting variables, redeploy to reload the PM2 process with updated env vars.
|
|
853
|
-
|
|
854
|
-
#### Option 3: Validate requirements
|
|
855
|
-
```json
|
|
856
|
-
{
|
|
857
|
-
"env": {
|
|
858
|
-
"required": ["DATABASE_URL", "API_KEY"],
|
|
859
|
-
"optional": ["REDIS_URL", "LOG_LEVEL"]
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
```
|
|
863
|
-
|
|
864
|
-
```bash
|
|
865
|
-
hostfn env validate production
|
|
866
|
-
```
|
|
867
|
-
|
|
868
|
-
### CI/CD Integration
|
|
869
|
-
|
|
870
|
-
```yaml
|
|
871
|
-
# GitHub Actions example
|
|
872
|
-
name: Deploy
|
|
873
|
-
on:
|
|
874
|
-
push:
|
|
875
|
-
branches: [main]
|
|
876
|
-
|
|
877
|
-
jobs:
|
|
878
|
-
deploy:
|
|
879
|
-
runs-on: ubuntu-latest
|
|
880
|
-
steps:
|
|
881
|
-
- uses: actions/checkout@v3
|
|
882
|
-
|
|
883
|
-
- name: Setup Node.js
|
|
884
|
-
uses: actions/setup-node@v3
|
|
885
|
-
with:
|
|
886
|
-
node-version: '18'
|
|
887
|
-
|
|
888
|
-
- name: Install hostfn
|
|
889
|
-
run: npm install -g hostfn
|
|
890
|
-
|
|
891
|
-
- name: Setup SSH Key
|
|
892
|
-
run: |
|
|
893
|
-
mkdir -p ~/.ssh
|
|
894
|
-
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
|
|
895
|
-
chmod 600 ~/.ssh/id_rsa
|
|
896
|
-
|
|
897
|
-
- name: Deploy to Production
|
|
898
|
-
run: hostfn deploy production --ci
|
|
899
|
-
env:
|
|
900
|
-
HOSTFN_HOST: ${{ secrets.PRODUCTION_HOST }}
|
|
901
|
-
```
|
|
902
|
-
|
|
903
|
-
For monorepo, deploy only changed services:
|
|
904
|
-
```yaml
|
|
905
|
-
- name: Deploy Changed Services
|
|
906
|
-
run: |
|
|
907
|
-
if [[ $(git diff --name-only HEAD~1 | grep '^services/account/') ]]; then
|
|
908
|
-
hostfn deploy production --ci --service account
|
|
909
|
-
fi
|
|
910
|
-
if [[ $(git diff --name-only HEAD~1 | grep '^services/auth/') ]]; then
|
|
911
|
-
hostfn deploy production --ci --service auth
|
|
912
|
-
fi
|
|
913
|
-
```
|
|
914
|
-
|
|
915
|
-
---
|
|
916
|
-
|
|
917
|
-
## 📚 Examples
|
|
918
|
-
|
|
919
|
-
### Example 1: Simple Express API
|
|
920
|
-
|
|
921
|
-
```json
|
|
922
|
-
{
|
|
923
|
-
"name": "express-api",
|
|
924
|
-
"runtime": "nodejs",
|
|
925
|
-
"version": "18",
|
|
926
|
-
"environments": {
|
|
927
|
-
"production": {
|
|
928
|
-
"server": "ubuntu@api.example.com",
|
|
929
|
-
"port": 3000,
|
|
930
|
-
"instances": "max"
|
|
931
|
-
}
|
|
932
|
-
},
|
|
933
|
-
"build": {
|
|
934
|
-
"command": "npm run build",
|
|
935
|
-
"directory": "dist"
|
|
936
|
-
},
|
|
937
|
-
"start": {
|
|
938
|
-
"command": "npm start",
|
|
939
|
-
"entry": "dist/server.js"
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
```
|
|
943
|
-
|
|
944
|
-
### Example 2: Microservices Monorepo
|
|
945
|
-
|
|
946
|
-
```json
|
|
947
|
-
{
|
|
948
|
-
"name": "21n",
|
|
949
|
-
"runtime": "nodejs",
|
|
950
|
-
"version": "18",
|
|
951
|
-
"environments": {
|
|
952
|
-
"production": {
|
|
953
|
-
"server": "ubuntu@shared.21n.com",
|
|
954
|
-
"port": 3000,
|
|
955
|
-
"instances": "max"
|
|
956
|
-
}
|
|
957
|
-
},
|
|
958
|
-
"build": {
|
|
959
|
-
"command": "npm run build",
|
|
960
|
-
"directory": "dist"
|
|
961
|
-
},
|
|
962
|
-
"start": {
|
|
963
|
-
"command": "npm start"
|
|
964
|
-
},
|
|
965
|
-
"services": {
|
|
966
|
-
"account": {
|
|
967
|
-
"port": 3001,
|
|
968
|
-
"path": "services/account",
|
|
969
|
-
"domain": "account.21n.com",
|
|
970
|
-
"instances": "max"
|
|
971
|
-
},
|
|
972
|
-
"auth": {
|
|
973
|
-
"port": 3002,
|
|
974
|
-
"path": "services/auth",
|
|
975
|
-
"domain": "auth.21n.com",
|
|
976
|
-
"server": "ubuntu@auth.21n.com",
|
|
977
|
-
"instances": 4
|
|
978
|
-
},
|
|
979
|
-
"notification": {
|
|
980
|
-
"port": 3003,
|
|
981
|
-
"path": "services/notification",
|
|
982
|
-
"domain": "notification.21n.com",
|
|
983
|
-
"instances": 2
|
|
984
|
-
},
|
|
985
|
-
"analytics": {
|
|
986
|
-
"port": 3004,
|
|
987
|
-
"path": "services/analytics",
|
|
988
|
-
"instances": 1
|
|
989
|
-
}
|
|
990
|
-
},
|
|
991
|
-
"health": {
|
|
992
|
-
"path": "/health",
|
|
993
|
-
"timeout": 60,
|
|
994
|
-
"retries": 10,
|
|
995
|
-
"interval": 3
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
```
|
|
999
|
-
|
|
1000
|
-
See `examples/` directory for more complete examples.
|
|
1001
|
-
|
|
1002
|
-
---
|
|
1003
|
-
|
|
1004
|
-
## Architecture
|
|
1005
|
-
|
|
1006
|
-
```
|
|
1007
|
-
hostfn/
|
|
1008
|
-
├── packages/
|
|
1009
|
-
│ └── cli/ # Main CLI package
|
|
1010
|
-
│ ├── src/
|
|
1011
|
-
│ │ ├── commands/ # Command implementations
|
|
1012
|
-
│ │ │ ├── deploy.ts # Deployment engine
|
|
1013
|
-
│ │ │ ├── status.ts # Status monitoring
|
|
1014
|
-
│ │ │ ├── logs.ts # Log streaming
|
|
1015
|
-
│ │ │ ├── rollback.ts # Rollback system
|
|
1016
|
-
│ │ │ ├── env.ts # Environment variables
|
|
1017
|
-
│ │ │ ├── init.ts # Project initialization
|
|
1018
|
-
│ │ │ └── server/ # Server management
|
|
1019
|
-
│ │ ├── config/ # Config schema & loader
|
|
1020
|
-
│ │ │ ├── schema.ts # Zod schema
|
|
1021
|
-
│ │ │ └── loader.ts # Config loading
|
|
1022
|
-
│ │ ├── runtimes/ # Runtime adapters
|
|
1023
|
-
│ │ │ ├── base.ts # Base adapter interface
|
|
1024
|
-
│ │ │ ├── registry.ts # Runtime registry
|
|
1025
|
-
│ │ │ └── nodejs/ # Node.js adapter (PM2)
|
|
1026
|
-
│ │ ├── core/ # Core business logic
|
|
1027
|
-
│ │ │ ├── ssh.ts # SSH connection manager
|
|
1028
|
-
│ │ │ ├── sync.ts # File sync (rsync)
|
|
1029
|
-
│ │ │ ├── health.ts # Health checking
|
|
1030
|
-
│ │ │ ├── backup.ts # Backup management
|
|
1031
|
-
│ │ │ └── lock.ts # Deployment locking
|
|
1032
|
-
│ │ └── utils/ # Utilities
|
|
1033
|
-
│ │ ├── logger.ts # Pretty logging
|
|
1034
|
-
│ │ └── validation.ts
|
|
1035
|
-
│ └── package.json
|
|
1036
|
-
├── examples/ # Example configurations
|
|
1037
|
-
│ ├── monorepo-config.json
|
|
1038
|
-
│ └── monorepo-multi-server-config.json
|
|
1039
|
-
├── _conduct/
|
|
1040
|
-
│ ├── specs/ # Project specifications
|
|
1041
|
-
│ └── .meta/ # Additional documentation
|
|
1042
|
-
│ ├── MONOREPO_GUIDE.md
|
|
1043
|
-
│ ├── QUICK_START_MONOREPO.md
|
|
1044
|
-
│ ├── CHANGELOG_MONOREPO.md
|
|
1045
|
-
│ └── MULTI_SERVER_SUMMARY.md
|
|
1046
|
-
└── README.md
|
|
1047
|
-
```
|
|
1048
|
-
|
|
1049
|
-
### Design Principles
|
|
1050
|
-
|
|
1051
|
-
1. **Pluggable Runtime System**
|
|
1052
|
-
- Base adapter interface
|
|
1053
|
-
- Runtime-specific implementations
|
|
1054
|
-
- Easy to add new languages
|
|
1055
|
-
|
|
1056
|
-
2. **Type Safety**
|
|
1057
|
-
- Zod for runtime validation
|
|
1058
|
-
- TypeScript for compile-time safety
|
|
1059
|
-
- Schema-driven configuration
|
|
1060
|
-
|
|
1061
|
-
3. **Production Ready**
|
|
1062
|
-
- Health checks
|
|
1063
|
-
- Auto-rollback on failure
|
|
1064
|
-
- Zero-downtime deployments
|
|
1065
|
-
- Deployment locking
|
|
1066
|
-
|
|
1067
|
-
4. **Developer Experience**
|
|
1068
|
-
- Interactive CLI
|
|
1069
|
-
- Smart defaults
|
|
1070
|
-
- Clear error messages
|
|
1071
|
-
- Dry-run mode
|
|
1072
|
-
|
|
1073
|
-
---
|
|
1074
|
-
|
|
1075
|
-
## Development
|
|
1076
|
-
|
|
1077
|
-
```bash
|
|
1078
|
-
# Clone and setup
|
|
1079
|
-
git clone <repo>
|
|
1080
|
-
cd hostfn
|
|
1081
|
-
npm install
|
|
1082
|
-
|
|
1083
|
-
# Build
|
|
1084
|
-
npm run build
|
|
1085
|
-
|
|
1086
|
-
# Watch mode (development)
|
|
1087
|
-
npm run dev
|
|
1088
|
-
|
|
1089
|
-
# Lint
|
|
1090
|
-
npm run lint
|
|
1091
|
-
|
|
1092
|
-
# Test
|
|
1093
|
-
npm run test
|
|
1094
|
-
|
|
1095
|
-
# Link for local testing
|
|
1096
|
-
cd packages/cli
|
|
1097
|
-
npm link
|
|
1098
|
-
|
|
1099
|
-
# Use globally
|
|
1100
|
-
hostfn --help
|
|
1101
|
-
```
|
|
1102
|
-
|
|
1103
|
-
### Project Structure
|
|
1104
|
-
|
|
1105
|
-
- **Monorepo**: Managed with Turborepo
|
|
1106
|
-
- **TypeScript**: Strict mode enabled
|
|
1107
|
-
- **Package Manager**: npm
|
|
1108
|
-
- **Node Version**: >=18.0.0
|
|
1109
|
-
|
|
1110
|
-
---
|
|
1111
|
-
|
|
1112
|
-
## Contributing
|
|
1113
|
-
|
|
1114
|
-
1. Fork the repository
|
|
1115
|
-
2. Create a feature branch
|
|
1116
|
-
3. Make your changes
|
|
1117
|
-
4. Run tests and linting
|
|
1118
|
-
5. Submit a pull request
|
|
1119
|
-
|
|
1120
|
-
---
|
|
1121
|
-
### Roadmap
|
|
1122
|
-
- Additional runtime adapters (Python, Go, Ruby, Rust)
|
|
1123
|
-
- Parallel service deployments
|
|
1124
|
-
- Service dependency graphs
|
|
1125
|
-
- Web dashboard
|
|
1126
|
-
- Metrics collection
|
|
1127
|
-
- CI/CD templates
|
|
1128
|
-
---
|
|
1129
|
-
|
|
1130
|
-
## License
|
|
1131
|
-
|
|
1132
|
-
MIT
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|