kdeploy 1.1.9 → 1.2.0
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.
- checksums.yaml +4 -4
- data/README.md +852 -75
- data/exe/kdeploy +11 -11
- data/lib/kdeploy/banner.rb +1 -1
- data/lib/kdeploy/cli.rb +6 -1
- data/lib/kdeploy/command_executor.rb +88 -0
- data/lib/kdeploy/command_grouper.rb +38 -0
- data/lib/kdeploy/configuration.rb +25 -0
- data/lib/kdeploy/dsl.rb +2 -0
- data/lib/kdeploy/errors.rb +64 -0
- data/lib/kdeploy/executor.rb +5 -5
- data/lib/kdeploy/output.rb +69 -0
- data/lib/kdeploy/runner.rb +48 -71
- data/lib/kdeploy/version.rb +1 -1
- data/lib/kdeploy.rb +5 -1
- metadata +7 -2
data/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# Kdeploy
|
|
2
|
+
|
|
2
3
|
```
|
|
3
4
|
_ _
|
|
4
5
|
/\ /\__| | ___ _ __ | | ___ _ _
|
|
@@ -9,29 +10,72 @@
|
|
|
9
10
|
|
|
10
11
|
⚡ Lightweight Agentless Deployment Tool
|
|
11
12
|
🚀 Deploy with confidence, scale with ease
|
|
12
|
-
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
A lightweight agentless deployment automation tool written in Ruby.
|
|
15
|
+
A lightweight, agentless deployment automation tool written in Ruby. Kdeploy enables you to deploy applications, manage configurations, and execute tasks across multiple servers using SSH, without requiring any agents or daemons on target machines.
|
|
16
16
|
|
|
17
17
|
[](https://rubygems.org/gems/kdeploy)
|
|
18
18
|
[](https://github.com/kevin197011/kdeploy/actions/workflows/gem-push.yml)
|
|
19
|
+
[](https://opensource.org/licenses/MIT)
|
|
20
|
+
|
|
21
|
+
## Table of Contents
|
|
22
|
+
|
|
23
|
+
- [Features](#-features)
|
|
24
|
+
- [Installation](#-installation)
|
|
25
|
+
- [Quick Start](#-quick-start)
|
|
26
|
+
- [Usage Guide](#-usage-guide)
|
|
27
|
+
- [Configuration](#-configuration)
|
|
28
|
+
- [Advanced Usage](#-advanced-usage)
|
|
29
|
+
- [Error Handling](#-error-handling)
|
|
30
|
+
- [Best Practices](#-best-practices)
|
|
31
|
+
- [Troubleshooting](#-troubleshooting)
|
|
32
|
+
- [Architecture](#-architecture)
|
|
33
|
+
- [Development](#-development)
|
|
34
|
+
- [Contributing](#-contributing)
|
|
35
|
+
- [License](#-license)
|
|
19
36
|
|
|
20
37
|
## 🌟 Features
|
|
21
38
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
39
|
+
### Core Features
|
|
40
|
+
|
|
41
|
+
- 🔑 **Agentless Remote Deployment**: Uses SSH for secure remote execution, no agents required
|
|
42
|
+
- 📝 **Elegant Ruby DSL**: Simple and expressive task definition syntax
|
|
43
|
+
- 🚀 **Concurrent Execution**: Efficient parallel task processing across multiple hosts
|
|
44
|
+
- 📤 **File Upload Support**: Easy file and template deployment via SCP
|
|
45
|
+
- 📊 **Task Status Tracking**: Real-time execution monitoring with detailed output
|
|
46
|
+
- 🔄 **ERB Template Support**: Dynamic configuration generation with variable substitution
|
|
47
|
+
- 🎯 **Role-based Deployment**: Target specific server roles for organized deployments
|
|
48
|
+
- 🔍 **Dry Run Mode**: Preview tasks before execution without making changes
|
|
49
|
+
- 🎨 **Color-coded Output**: Intuitive color scheme (Green: success, Red: errors, Yellow: warnings)
|
|
50
|
+
- ⚙️ **Flexible Host Targeting**: Execute tasks on specific hosts, roles, or all hosts
|
|
51
|
+
- 🔐 **Multiple Authentication Methods**: Support for SSH keys and password authentication
|
|
52
|
+
- 📈 **Execution Time Tracking**: Monitor task execution duration for performance analysis
|
|
53
|
+
|
|
54
|
+
### Technical Features
|
|
55
|
+
|
|
56
|
+
- **Thread-safe Execution**: Built on `concurrent-ruby` for reliable parallel processing
|
|
57
|
+
- **Custom Error Handling**: Detailed error types for better debugging
|
|
58
|
+
- **Configuration Management**: Centralized configuration with sensible defaults
|
|
59
|
+
- **Extensible Architecture**: Modular design for easy extension
|
|
60
|
+
- **Shell Completion**: Auto-completion support for Bash and Zsh
|
|
31
61
|
|
|
32
62
|
## 📦 Installation
|
|
33
63
|
|
|
34
|
-
|
|
64
|
+
### Requirements
|
|
65
|
+
|
|
66
|
+
- Ruby >= 2.7.0
|
|
67
|
+
- SSH access to target servers
|
|
68
|
+
- SSH keys or password authentication configured
|
|
69
|
+
|
|
70
|
+
### Install via RubyGems
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
gem install kdeploy
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Install via Bundler
|
|
77
|
+
|
|
78
|
+
Add this line to your application's `Gemfile`:
|
|
35
79
|
|
|
36
80
|
```ruby
|
|
37
81
|
gem 'kdeploy'
|
|
@@ -43,22 +87,24 @@ And then execute:
|
|
|
43
87
|
bundle install
|
|
44
88
|
```
|
|
45
89
|
|
|
46
|
-
|
|
90
|
+
### Verify Installation
|
|
47
91
|
|
|
48
92
|
```bash
|
|
49
|
-
|
|
93
|
+
kdeploy version
|
|
50
94
|
```
|
|
51
95
|
|
|
96
|
+
You should see the version information and banner.
|
|
97
|
+
|
|
52
98
|
### Shell Completion
|
|
53
99
|
|
|
54
|
-
|
|
100
|
+
Kdeploy automatically configures shell completion during installation. If needed, manually add to your shell config:
|
|
55
101
|
|
|
56
|
-
For Bash (`~/.bashrc`):
|
|
102
|
+
**For Bash** (`~/.bashrc`):
|
|
57
103
|
```bash
|
|
58
104
|
source "$(gem contents kdeploy | grep kdeploy.bash)"
|
|
59
105
|
```
|
|
60
106
|
|
|
61
|
-
For Zsh (`~/.zshrc`):
|
|
107
|
+
**For Zsh** (`~/.zshrc`):
|
|
62
108
|
```bash
|
|
63
109
|
source "$(gem contents kdeploy | grep kdeploy.zsh)"
|
|
64
110
|
autoload -Uz compinit && compinit
|
|
@@ -75,17 +121,22 @@ Now you can use Tab completion for:
|
|
|
75
121
|
|
|
76
122
|
## 🚀 Quick Start
|
|
77
123
|
|
|
78
|
-
1. Initialize a
|
|
124
|
+
### 1. Initialize a New Project
|
|
79
125
|
|
|
80
126
|
```bash
|
|
81
127
|
kdeploy init my-deployment
|
|
82
128
|
```
|
|
83
129
|
|
|
84
|
-
|
|
130
|
+
This creates a new directory with:
|
|
131
|
+
- `deploy.rb` - Main deployment configuration file
|
|
132
|
+
- `config/` - Directory for configuration files and templates
|
|
133
|
+
- `README.md` - Project documentation
|
|
85
134
|
|
|
86
|
-
|
|
87
|
-
|
|
135
|
+
### 2. Configure Hosts and Tasks
|
|
136
|
+
|
|
137
|
+
Edit `deploy.rb`:
|
|
88
138
|
|
|
139
|
+
```ruby
|
|
89
140
|
# Define hosts
|
|
90
141
|
host "web01", user: "ubuntu", ip: "10.0.0.1", key: "~/.ssh/id_rsa"
|
|
91
142
|
host "web02", user: "ubuntu", ip: "10.0.0.2", key: "~/.ssh/id_rsa"
|
|
@@ -93,160 +144,886 @@ host "web02", user: "ubuntu", ip: "10.0.0.2", key: "~/.ssh/id_rsa"
|
|
|
93
144
|
# Define roles
|
|
94
145
|
role :web, %w[web01 web02]
|
|
95
146
|
|
|
96
|
-
# Define
|
|
97
|
-
# 推荐多行命令用 heredoc(run <<~SHELL)
|
|
147
|
+
# Define deployment task
|
|
98
148
|
task :deploy, roles: :web do
|
|
99
149
|
run <<~SHELL
|
|
100
150
|
sudo systemctl stop nginx
|
|
101
|
-
echo "Deploying..."
|
|
102
|
-
sudo systemctl start nginx
|
|
151
|
+
echo "Deploying application..."
|
|
103
152
|
SHELL
|
|
153
|
+
|
|
104
154
|
upload_template "./config/nginx.conf.erb", "/etc/nginx/nginx.conf",
|
|
105
155
|
domain_name: "example.com",
|
|
106
156
|
port: 3000
|
|
157
|
+
|
|
158
|
+
run "sudo systemctl start nginx"
|
|
107
159
|
end
|
|
108
160
|
```
|
|
109
161
|
|
|
110
|
-
3. Run
|
|
162
|
+
### 3. Run Deployment
|
|
111
163
|
|
|
112
164
|
```bash
|
|
113
|
-
kdeploy execute deploy.rb
|
|
165
|
+
kdeploy execute deploy.rb deploy
|
|
114
166
|
```
|
|
115
167
|
|
|
116
|
-
|
|
168
|
+
## 📖 Usage Guide
|
|
169
|
+
|
|
170
|
+
### Command Reference
|
|
171
|
+
|
|
172
|
+
#### `kdeploy init [DIR]`
|
|
173
|
+
|
|
174
|
+
Initialize a new deployment project.
|
|
117
175
|
|
|
118
176
|
```bash
|
|
119
|
-
|
|
177
|
+
# Initialize in current directory
|
|
178
|
+
kdeploy init .
|
|
179
|
+
|
|
180
|
+
# Initialize in named directory
|
|
181
|
+
kdeploy init my-deployment
|
|
120
182
|
```
|
|
121
183
|
|
|
122
|
-
|
|
184
|
+
#### `kdeploy execute TASK_FILE [TASK]`
|
|
123
185
|
|
|
124
|
-
|
|
186
|
+
Execute deployment tasks from a configuration file.
|
|
125
187
|
|
|
188
|
+
**Basic Usage:**
|
|
126
189
|
```bash
|
|
127
190
|
# Execute all tasks in the file
|
|
128
191
|
kdeploy execute deploy.rb
|
|
129
192
|
|
|
130
193
|
# Execute a specific task
|
|
131
194
|
kdeploy execute deploy.rb deploy_web
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Options:**
|
|
198
|
+
- `--limit HOSTS`: Limit execution to specific hosts (comma-separated)
|
|
199
|
+
- `--parallel NUM`: Number of parallel executions (default: 10)
|
|
200
|
+
- `--dry-run`: Preview mode - show what would be done without executing
|
|
201
|
+
|
|
202
|
+
**Examples:**
|
|
203
|
+
```bash
|
|
204
|
+
# Preview deployment without executing
|
|
205
|
+
kdeploy execute deploy.rb deploy_web --dry-run
|
|
206
|
+
|
|
207
|
+
# Execute on specific hosts only
|
|
208
|
+
kdeploy execute deploy.rb deploy_web --limit web01,web02
|
|
132
209
|
|
|
133
|
-
#
|
|
134
|
-
kdeploy execute deploy.rb --
|
|
210
|
+
# Use custom parallel count
|
|
211
|
+
kdeploy execute deploy.rb deploy_web --parallel 5
|
|
135
212
|
|
|
136
|
-
#
|
|
137
|
-
kdeploy execute deploy.rb --limit web01
|
|
213
|
+
# Combine options
|
|
214
|
+
kdeploy execute deploy.rb deploy_web --limit web01 --parallel 3 --dry-run
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### `kdeploy version`
|
|
218
|
+
|
|
219
|
+
Show version information.
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
kdeploy version
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
#### `kdeploy help [COMMAND]`
|
|
226
|
+
|
|
227
|
+
Show help information.
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Show general help
|
|
231
|
+
kdeploy help
|
|
138
232
|
|
|
139
|
-
#
|
|
140
|
-
kdeploy execute
|
|
233
|
+
# Show help for specific command
|
|
234
|
+
kdeploy help execute
|
|
141
235
|
```
|
|
142
236
|
|
|
143
237
|
### Host Definition
|
|
144
238
|
|
|
239
|
+
#### Basic Host Configuration
|
|
240
|
+
|
|
145
241
|
```ruby
|
|
146
|
-
# Single host
|
|
242
|
+
# Single host with SSH key
|
|
147
243
|
host "web01",
|
|
148
244
|
user: "ubuntu",
|
|
149
245
|
ip: "10.0.0.1",
|
|
150
246
|
key: "~/.ssh/id_rsa"
|
|
151
247
|
|
|
152
|
-
#
|
|
248
|
+
# Host with password authentication
|
|
249
|
+
host "web02",
|
|
250
|
+
user: "admin",
|
|
251
|
+
ip: "10.0.0.2",
|
|
252
|
+
password: "your-password"
|
|
253
|
+
|
|
254
|
+
# Host with custom SSH port
|
|
255
|
+
host "web03",
|
|
256
|
+
user: "ubuntu",
|
|
257
|
+
ip: "10.0.0.3",
|
|
258
|
+
key: "~/.ssh/id_rsa",
|
|
259
|
+
port: 2222
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
#### Host Configuration Options
|
|
263
|
+
|
|
264
|
+
| Option | Type | Required | Description |
|
|
265
|
+
|--------|------|----------|-------------|
|
|
266
|
+
| `user` | String | Yes | SSH username |
|
|
267
|
+
| `ip` | String | Yes | Server IP address or hostname |
|
|
268
|
+
| `key` | String | No* | Path to SSH private key file |
|
|
269
|
+
| `password` | String | No* | SSH password |
|
|
270
|
+
| `port` | Integer | No | SSH port (default: 22) |
|
|
271
|
+
|
|
272
|
+
\* Either `key` or `password` is required for authentication.
|
|
273
|
+
|
|
274
|
+
#### Dynamic Host Definition
|
|
275
|
+
|
|
276
|
+
```ruby
|
|
277
|
+
# Define multiple hosts programmatically
|
|
153
278
|
%w[web01 web02 web03].each do |name|
|
|
154
279
|
host name,
|
|
155
280
|
user: "ubuntu",
|
|
156
281
|
ip: "10.0.0.#{name[-1]}",
|
|
157
282
|
key: "~/.ssh/id_rsa"
|
|
158
283
|
end
|
|
284
|
+
|
|
285
|
+
# Define hosts from external source
|
|
286
|
+
require 'yaml'
|
|
287
|
+
hosts_config = YAML.load_file('hosts.yml')
|
|
288
|
+
hosts_config.each do |name, config|
|
|
289
|
+
host name, **config
|
|
290
|
+
end
|
|
159
291
|
```
|
|
160
292
|
|
|
161
293
|
### Role Management
|
|
162
294
|
|
|
295
|
+
Roles allow you to group hosts and target them collectively in tasks.
|
|
296
|
+
|
|
163
297
|
```ruby
|
|
164
298
|
# Define roles
|
|
165
|
-
role :web, %w[web01 web02]
|
|
299
|
+
role :web, %w[web01 web02 web03]
|
|
166
300
|
role :db, %w[db01 db02]
|
|
167
|
-
role :
|
|
301
|
+
role :cache, %w[cache01]
|
|
302
|
+
role :all, %w[web01 web02 web03 db01 db02 cache01]
|
|
168
303
|
|
|
169
304
|
# Use roles in tasks
|
|
170
305
|
task :deploy_web, roles: :web do
|
|
171
|
-
#
|
|
306
|
+
# Executes on all web servers
|
|
172
307
|
end
|
|
173
308
|
|
|
174
309
|
task :backup_db, roles: :db do
|
|
175
|
-
#
|
|
310
|
+
# Executes on all database servers
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# Multiple roles
|
|
314
|
+
task :deploy_all, roles: [:web, :cache] do
|
|
315
|
+
# Executes on web and cache servers
|
|
176
316
|
end
|
|
177
317
|
```
|
|
178
318
|
|
|
179
319
|
### Task Definition
|
|
180
320
|
|
|
321
|
+
#### Basic Task
|
|
322
|
+
|
|
181
323
|
```ruby
|
|
182
|
-
|
|
183
|
-
task :simple do
|
|
324
|
+
task :hello do
|
|
184
325
|
run "echo 'Hello, World!'"
|
|
185
326
|
end
|
|
327
|
+
```
|
|
186
328
|
|
|
187
|
-
|
|
188
|
-
|
|
329
|
+
#### Role-based Task
|
|
330
|
+
|
|
331
|
+
```ruby
|
|
332
|
+
task :deploy_web, roles: :web do
|
|
333
|
+
run "sudo systemctl restart nginx"
|
|
334
|
+
end
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
#### Host-specific Task
|
|
338
|
+
|
|
339
|
+
```ruby
|
|
340
|
+
task :maintenance, on: %w[web01] do
|
|
189
341
|
run <<~SHELL
|
|
190
342
|
sudo systemctl stop nginx
|
|
343
|
+
sudo apt-get update && sudo apt-get upgrade -y
|
|
191
344
|
sudo systemctl start nginx
|
|
192
345
|
SHELL
|
|
193
|
-
upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
|
|
194
346
|
end
|
|
347
|
+
```
|
|
195
348
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
349
|
+
#### Task with Multiple Commands
|
|
350
|
+
|
|
351
|
+
```ruby
|
|
352
|
+
task :deploy, roles: :web do
|
|
353
|
+
# Stop service
|
|
354
|
+
run "sudo systemctl stop nginx"
|
|
355
|
+
|
|
356
|
+
# Upload configuration
|
|
357
|
+
upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
|
|
358
|
+
|
|
359
|
+
# Start service
|
|
360
|
+
run "sudo systemctl start nginx"
|
|
361
|
+
|
|
362
|
+
# Verify status
|
|
363
|
+
run "sudo systemctl status nginx"
|
|
202
364
|
end
|
|
203
365
|
```
|
|
204
366
|
|
|
367
|
+
#### Task Options
|
|
368
|
+
|
|
369
|
+
| Option | Type | Description |
|
|
370
|
+
|-------|------|-------------|
|
|
371
|
+
| `roles` | Symbol/Array | Execute on hosts with specified role(s) |
|
|
372
|
+
| `on` | Array | Execute on specific host(s) |
|
|
373
|
+
|
|
374
|
+
**Note**: If neither `roles` nor `on` is specified, the task executes on all defined hosts.
|
|
375
|
+
|
|
376
|
+
### Command Types
|
|
377
|
+
|
|
378
|
+
#### `run` - Execute Shell Commands
|
|
379
|
+
|
|
380
|
+
Execute commands on remote servers.
|
|
381
|
+
|
|
382
|
+
```ruby
|
|
383
|
+
# Single line command
|
|
384
|
+
run "sudo systemctl restart nginx"
|
|
385
|
+
|
|
386
|
+
# Multi-line command (recommended for complex commands)
|
|
387
|
+
run <<~SHELL
|
|
388
|
+
cd /var/www/app
|
|
389
|
+
git pull origin main
|
|
390
|
+
bundle install
|
|
391
|
+
sudo systemctl restart puma
|
|
392
|
+
SHELL
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
**Best Practice**: Use heredoc (`<<~SHELL`) for multi-line commands to improve readability.
|
|
396
|
+
|
|
397
|
+
#### `upload` - Upload Files
|
|
398
|
+
|
|
399
|
+
Upload files to remote servers.
|
|
400
|
+
|
|
401
|
+
```ruby
|
|
402
|
+
upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
|
|
403
|
+
upload "./scripts/deploy.sh", "/tmp/deploy.sh"
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
**Parameters:**
|
|
407
|
+
- `source`: Local file path
|
|
408
|
+
- `destination`: Remote file path
|
|
409
|
+
|
|
410
|
+
#### `upload_template` - Upload ERB Templates
|
|
411
|
+
|
|
412
|
+
Upload and render ERB templates with variable substitution.
|
|
413
|
+
|
|
414
|
+
```ruby
|
|
415
|
+
upload_template "./config/nginx.conf.erb", "/etc/nginx/nginx.conf",
|
|
416
|
+
domain_name: "example.com",
|
|
417
|
+
port: 3000,
|
|
418
|
+
worker_processes: 4
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
**Parameters:**
|
|
422
|
+
- `source`: Local ERB template file path
|
|
423
|
+
- `destination`: Remote file path
|
|
424
|
+
- `variables`: Hash of variables for template rendering
|
|
425
|
+
|
|
205
426
|
### Template Support
|
|
206
427
|
|
|
207
|
-
|
|
428
|
+
Kdeploy supports ERB (Embedded Ruby) templates for dynamic configuration generation.
|
|
429
|
+
|
|
430
|
+
#### Creating Templates
|
|
431
|
+
|
|
432
|
+
Create an ERB template file (e.g., `config/nginx.conf.erb`):
|
|
208
433
|
|
|
209
434
|
```erb
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
435
|
+
user nginx;
|
|
436
|
+
worker_processes <%= worker_processes %>;
|
|
437
|
+
error_log /var/log/nginx/error.log;
|
|
438
|
+
pid /run/nginx.pid;
|
|
439
|
+
|
|
440
|
+
events {
|
|
441
|
+
worker_connections <%= worker_connections %>;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
http {
|
|
445
|
+
include /etc/nginx/mime.types;
|
|
446
|
+
default_type application/octet-stream;
|
|
447
|
+
|
|
448
|
+
upstream app_servers {
|
|
449
|
+
server 127.0.0.1:<%= port %>;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
server {
|
|
453
|
+
listen 80;
|
|
454
|
+
server_name <%= domain_name %>;
|
|
455
|
+
|
|
456
|
+
location / {
|
|
457
|
+
proxy_pass http://app_servers;
|
|
458
|
+
proxy_http_version 1.1;
|
|
459
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
460
|
+
proxy_set_header Connection 'upgrade';
|
|
461
|
+
proxy_set_header Host $host;
|
|
462
|
+
proxy_cache_bypass $http_upgrade;
|
|
463
|
+
}
|
|
218
464
|
}
|
|
219
465
|
}
|
|
220
466
|
```
|
|
221
467
|
|
|
222
|
-
|
|
468
|
+
#### Using Templates
|
|
223
469
|
|
|
224
470
|
```ruby
|
|
225
471
|
task :deploy_config do
|
|
226
|
-
upload_template "./config/nginx.conf.erb", "/etc/nginx/
|
|
472
|
+
upload_template "./config/nginx.conf.erb", "/etc/nginx/nginx.conf",
|
|
227
473
|
domain_name: "example.com",
|
|
228
|
-
port: 3000
|
|
474
|
+
port: 3000,
|
|
475
|
+
worker_processes: 4,
|
|
476
|
+
worker_connections: 2048
|
|
477
|
+
end
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
#### Template Features
|
|
481
|
+
|
|
482
|
+
- Full ERB syntax support
|
|
483
|
+
- Variable substitution
|
|
484
|
+
- Conditional logic
|
|
485
|
+
- Loops and iterations
|
|
486
|
+
- Ruby code execution
|
|
487
|
+
|
|
488
|
+
### Inventory Block
|
|
489
|
+
|
|
490
|
+
Use the `inventory` block to organize host definitions:
|
|
491
|
+
|
|
492
|
+
```ruby
|
|
493
|
+
inventory do
|
|
494
|
+
host 'web01', user: 'ubuntu', ip: '10.0.0.1', key: '~/.ssh/id_rsa'
|
|
495
|
+
host 'web02', user: 'ubuntu', ip: '10.0.0.2', key: '~/.ssh/id_rsa'
|
|
496
|
+
host 'db01', user: 'root', ip: '10.0.0.3', key: '~/.ssh/id_rsa'
|
|
497
|
+
end
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
## ⚙️ Configuration
|
|
501
|
+
|
|
502
|
+
### Default Configuration
|
|
503
|
+
|
|
504
|
+
Kdeploy uses sensible defaults that can be customized:
|
|
505
|
+
|
|
506
|
+
- **Default Parallel Count**: 10 concurrent executions
|
|
507
|
+
- **SSH Timeout**: 30 seconds
|
|
508
|
+
- **Host Key Verification**: Disabled (for convenience, enable in production)
|
|
509
|
+
|
|
510
|
+
### Environment Variables
|
|
511
|
+
|
|
512
|
+
You can override defaults using environment variables:
|
|
513
|
+
|
|
514
|
+
```bash
|
|
515
|
+
export KDEPLOY_PARALLEL=5
|
|
516
|
+
export KDEPLOY_SSH_TIMEOUT=60
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### Configuration File
|
|
520
|
+
|
|
521
|
+
For project-specific configuration, create a `.kdeploy.yml`:
|
|
522
|
+
|
|
523
|
+
```yaml
|
|
524
|
+
parallel: 5
|
|
525
|
+
ssh_timeout: 60
|
|
526
|
+
verify_host_key: true
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
## 🔧 Advanced Usage
|
|
530
|
+
|
|
531
|
+
### Conditional Execution
|
|
532
|
+
|
|
533
|
+
Use Ruby conditionals in your deployment files:
|
|
534
|
+
|
|
535
|
+
```ruby
|
|
536
|
+
task :deploy do
|
|
537
|
+
if ENV['ENVIRONMENT'] == 'production'
|
|
538
|
+
run "sudo systemctl stop nginx"
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
|
|
542
|
+
|
|
543
|
+
if ENV['ENVIRONMENT'] == 'production'
|
|
544
|
+
run "sudo systemctl start nginx"
|
|
545
|
+
end
|
|
546
|
+
end
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### Looping Over Hosts
|
|
550
|
+
|
|
551
|
+
```ruby
|
|
552
|
+
# Execute different commands based on host
|
|
553
|
+
task :custom_setup do
|
|
554
|
+
@hosts.each do |name, config|
|
|
555
|
+
if name.start_with?('web')
|
|
556
|
+
run "echo 'Web server: #{name}'"
|
|
557
|
+
elsif name.start_with?('db')
|
|
558
|
+
run "echo 'Database server: #{name}'"
|
|
559
|
+
end
|
|
560
|
+
end
|
|
561
|
+
end
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### Error Handling in Tasks
|
|
565
|
+
|
|
566
|
+
```ruby
|
|
567
|
+
task :deploy do
|
|
568
|
+
run "sudo systemctl stop nginx" || raise "Failed to stop nginx"
|
|
569
|
+
upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
|
|
570
|
+
run "sudo systemctl start nginx" || raise "Failed to start nginx"
|
|
571
|
+
end
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### Using External Libraries
|
|
575
|
+
|
|
576
|
+
```ruby
|
|
577
|
+
require 'yaml'
|
|
578
|
+
require 'json'
|
|
579
|
+
|
|
580
|
+
# Load configuration from external files
|
|
581
|
+
config = YAML.load_file('config.yml')
|
|
582
|
+
|
|
583
|
+
task :deploy do
|
|
584
|
+
config['commands'].each do |cmd|
|
|
585
|
+
run cmd
|
|
586
|
+
end
|
|
229
587
|
end
|
|
230
588
|
```
|
|
231
589
|
|
|
590
|
+
### Task Dependencies
|
|
591
|
+
|
|
592
|
+
While Kdeploy doesn't have built-in task dependencies, you can achieve this with Ruby:
|
|
593
|
+
|
|
594
|
+
```ruby
|
|
595
|
+
task :setup do
|
|
596
|
+
run "echo 'Setting up...'"
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
task :deploy do
|
|
600
|
+
# Manually call setup task
|
|
601
|
+
self.class.kdeploy_tasks[:setup][:block].call.each do |cmd|
|
|
602
|
+
case cmd[:type]
|
|
603
|
+
when :run
|
|
604
|
+
run cmd[:command]
|
|
605
|
+
when :upload
|
|
606
|
+
upload cmd[:source], cmd[:destination]
|
|
607
|
+
end
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
run "echo 'Deploying...'"
|
|
611
|
+
end
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
## 🚨 Error Handling
|
|
615
|
+
|
|
616
|
+
### Error Types
|
|
617
|
+
|
|
618
|
+
Kdeploy provides specific error types for better debugging:
|
|
619
|
+
|
|
620
|
+
- `Kdeploy::TaskNotFoundError` - Task not found
|
|
621
|
+
- `Kdeploy::HostNotFoundError` - Host not found
|
|
622
|
+
- `Kdeploy::SSHError` - SSH operation failed
|
|
623
|
+
- `Kdeploy::SCPError` - SCP upload failed
|
|
624
|
+
- `Kdeploy::TemplateError` - Template rendering failed
|
|
625
|
+
- `Kdeploy::ConfigurationError` - Configuration error
|
|
626
|
+
- `Kdeploy::FileNotFoundError` - File not found
|
|
627
|
+
|
|
628
|
+
### Error Output
|
|
629
|
+
|
|
630
|
+
Errors are displayed with:
|
|
631
|
+
- Red color coding
|
|
632
|
+
- Detailed error messages
|
|
633
|
+
- Host information
|
|
634
|
+
- Original error context
|
|
635
|
+
|
|
636
|
+
### Handling Errors
|
|
637
|
+
|
|
638
|
+
```ruby
|
|
639
|
+
# In your deployment file
|
|
640
|
+
begin
|
|
641
|
+
task :deploy do
|
|
642
|
+
run "risky-command"
|
|
643
|
+
end
|
|
644
|
+
rescue Kdeploy::SSHError => e
|
|
645
|
+
puts "SSH Error: #{e.message}"
|
|
646
|
+
# Handle error
|
|
647
|
+
end
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
## 💡 Best Practices
|
|
651
|
+
|
|
652
|
+
### 1. Use Heredoc for Multi-line Commands
|
|
653
|
+
|
|
654
|
+
```ruby
|
|
655
|
+
# ✅ Good
|
|
656
|
+
run <<~SHELL
|
|
657
|
+
cd /var/www/app
|
|
658
|
+
git pull origin main
|
|
659
|
+
bundle install
|
|
660
|
+
SHELL
|
|
661
|
+
|
|
662
|
+
# ❌ Avoid
|
|
663
|
+
run "cd /var/www/app && git pull origin main && bundle install"
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
### 2. Organize with Roles
|
|
667
|
+
|
|
668
|
+
```ruby
|
|
669
|
+
# ✅ Good - Use roles for organization
|
|
670
|
+
role :web, %w[web01 web02]
|
|
671
|
+
role :db, %w[db01 db02]
|
|
672
|
+
|
|
673
|
+
task :deploy_web, roles: :web do
|
|
674
|
+
# ...
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
# ❌ Avoid - Hardcoding host names
|
|
678
|
+
task :deploy do
|
|
679
|
+
# Hard to maintain
|
|
680
|
+
end
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
### 3. Use Templates for Dynamic Configuration
|
|
684
|
+
|
|
685
|
+
```ruby
|
|
686
|
+
# ✅ Good - Use templates
|
|
687
|
+
upload_template "./config/nginx.conf.erb", "/etc/nginx/nginx.conf",
|
|
688
|
+
domain_name: "example.com",
|
|
689
|
+
port: 3000
|
|
690
|
+
|
|
691
|
+
# ❌ Avoid - Hardcoding values
|
|
692
|
+
run "echo 'server_name example.com;' > /etc/nginx/nginx.conf"
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### 4. Validate Before Deployment
|
|
696
|
+
|
|
697
|
+
```ruby
|
|
698
|
+
task :deploy do
|
|
699
|
+
# Validate configuration
|
|
700
|
+
run "nginx -t" || raise "Nginx configuration is invalid"
|
|
701
|
+
|
|
702
|
+
# Deploy
|
|
703
|
+
upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
|
|
704
|
+
run "sudo systemctl reload nginx"
|
|
705
|
+
end
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
### 5. Use Dry Run for Testing
|
|
709
|
+
|
|
710
|
+
Always test with `--dry-run` before actual deployment:
|
|
711
|
+
|
|
712
|
+
```bash
|
|
713
|
+
kdeploy execute deploy.rb deploy_web --dry-run
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
### 6. Organize Files Properly
|
|
717
|
+
|
|
718
|
+
```
|
|
719
|
+
project/
|
|
720
|
+
├── deploy.rb # Main deployment file
|
|
721
|
+
├── config/ # Configuration files
|
|
722
|
+
│ ├── nginx.conf.erb # Templates
|
|
723
|
+
│ └── app.conf # Static configs
|
|
724
|
+
└── scripts/ # Helper scripts
|
|
725
|
+
└── deploy.sh
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
### 7. Version Control
|
|
729
|
+
|
|
730
|
+
- Commit `deploy.rb` and templates
|
|
731
|
+
- Use `.gitignore` for sensitive files
|
|
732
|
+
- Store secrets in environment variables
|
|
733
|
+
|
|
734
|
+
### 8. Parallel Execution
|
|
735
|
+
|
|
736
|
+
Adjust parallel count based on your infrastructure:
|
|
737
|
+
|
|
738
|
+
```bash
|
|
739
|
+
# For many hosts, increase parallel count
|
|
740
|
+
kdeploy execute deploy.rb deploy --parallel 20
|
|
741
|
+
|
|
742
|
+
# For limited resources, decrease
|
|
743
|
+
kdeploy execute deploy.rb deploy --parallel 3
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
## 🔍 Troubleshooting
|
|
747
|
+
|
|
748
|
+
### Common Issues
|
|
749
|
+
|
|
750
|
+
#### SSH Authentication Failed
|
|
751
|
+
|
|
752
|
+
**Problem**: `SSH authentication failed`
|
|
753
|
+
|
|
754
|
+
**Solutions**:
|
|
755
|
+
1. Verify SSH key path is correct
|
|
756
|
+
2. Check key permissions: `chmod 600 ~/.ssh/id_rsa`
|
|
757
|
+
3. Test SSH connection manually: `ssh user@host`
|
|
758
|
+
4. Verify username and IP address
|
|
759
|
+
|
|
760
|
+
#### Host Not Found
|
|
761
|
+
|
|
762
|
+
**Problem**: `No hosts found for task`
|
|
763
|
+
|
|
764
|
+
**Solutions**:
|
|
765
|
+
1. Verify host names in task match defined hosts
|
|
766
|
+
2. Check role definitions
|
|
767
|
+
3. Verify `--limit` option if used
|
|
768
|
+
|
|
769
|
+
#### Command Execution Failed
|
|
770
|
+
|
|
771
|
+
**Problem**: Commands fail on remote server
|
|
772
|
+
|
|
773
|
+
**Solutions**:
|
|
774
|
+
1. Test commands manually on target server
|
|
775
|
+
2. Check user permissions (may need sudo)
|
|
776
|
+
3. Verify command syntax
|
|
777
|
+
4. Check server logs
|
|
778
|
+
|
|
779
|
+
#### Template Rendering Error
|
|
780
|
+
|
|
781
|
+
**Problem**: Template upload fails
|
|
782
|
+
|
|
783
|
+
**Solutions**:
|
|
784
|
+
1. Verify ERB syntax in template
|
|
785
|
+
2. Check all required variables are provided
|
|
786
|
+
3. Validate template file exists
|
|
787
|
+
4. Test template rendering locally
|
|
788
|
+
|
|
789
|
+
#### Connection Timeout
|
|
790
|
+
|
|
791
|
+
**Problem**: SSH connection times out
|
|
792
|
+
|
|
793
|
+
**Solutions**:
|
|
794
|
+
1. Check network connectivity
|
|
795
|
+
2. Verify firewall rules
|
|
796
|
+
3. Increase timeout in configuration
|
|
797
|
+
4. Check SSH service on target server
|
|
798
|
+
|
|
799
|
+
### Debug Mode
|
|
800
|
+
|
|
801
|
+
Enable verbose output by checking the execution output. Kdeploy provides detailed information about:
|
|
802
|
+
- Task execution status
|
|
803
|
+
- Command output
|
|
804
|
+
- Error messages
|
|
805
|
+
- Execution duration
|
|
806
|
+
|
|
807
|
+
### Getting Help
|
|
808
|
+
|
|
809
|
+
- Check [GitHub Issues](https://github.com/kevin197011/kdeploy/issues)
|
|
810
|
+
- Review example projects
|
|
811
|
+
- Read the documentation
|
|
812
|
+
- Ask in discussions
|
|
813
|
+
|
|
814
|
+
## 🏗️ Architecture
|
|
815
|
+
|
|
816
|
+
### Core Components
|
|
817
|
+
|
|
818
|
+
- **CLI** (`cli.rb`): Command-line interface using Thor
|
|
819
|
+
- **DSL** (`dsl.rb`): Domain-specific language for task definition
|
|
820
|
+
- **Executor** (`executor.rb`): SSH/SCP execution engine
|
|
821
|
+
- **Runner** (`runner.rb`): Concurrent task execution coordinator
|
|
822
|
+
- **CommandExecutor** (`command_executor.rb`): Individual command execution
|
|
823
|
+
- **CommandGrouper** (`command_grouper.rb`): Command grouping logic
|
|
824
|
+
- **Template** (`template.rb`): ERB template rendering
|
|
825
|
+
- **Output** (`output.rb`): Output formatting and display
|
|
826
|
+
- **Configuration** (`configuration.rb`): Configuration management
|
|
827
|
+
- **Errors** (`errors.rb`): Custom error types
|
|
828
|
+
|
|
829
|
+
### Execution Flow
|
|
830
|
+
|
|
831
|
+
1. **Parse Configuration**: Load and parse `deploy.rb`
|
|
832
|
+
2. **Resolve Hosts**: Determine target hosts based on task definition
|
|
833
|
+
3. **Group Commands**: Group commands by type for efficient execution
|
|
834
|
+
4. **Execute Concurrently**: Run tasks in parallel across hosts
|
|
835
|
+
5. **Collect Results**: Gather execution results and status
|
|
836
|
+
6. **Display Output**: Format and display results to user
|
|
837
|
+
|
|
838
|
+
### Concurrency Model
|
|
839
|
+
|
|
840
|
+
Kdeploy uses `concurrent-ruby` with a fixed thread pool:
|
|
841
|
+
- Default: 10 concurrent executions
|
|
842
|
+
- Configurable via `--parallel` option
|
|
843
|
+
- Thread-safe result collection
|
|
844
|
+
- Automatic resource cleanup
|
|
845
|
+
|
|
232
846
|
## 🔧 Development
|
|
233
847
|
|
|
234
|
-
|
|
848
|
+
### Setup Development Environment
|
|
849
|
+
|
|
850
|
+
```bash
|
|
851
|
+
# Clone repository
|
|
852
|
+
git clone https://github.com/kevin197011/kdeploy.git
|
|
853
|
+
cd kdeploy
|
|
854
|
+
|
|
855
|
+
# Install dependencies
|
|
856
|
+
bundle install
|
|
857
|
+
|
|
858
|
+
# Run tests
|
|
859
|
+
bundle exec rspec
|
|
860
|
+
|
|
861
|
+
# Run console
|
|
862
|
+
bin/console
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
### Project Structure
|
|
235
866
|
|
|
236
|
-
|
|
867
|
+
```
|
|
868
|
+
kdeploy/
|
|
869
|
+
├── lib/
|
|
870
|
+
│ └── kdeploy/
|
|
871
|
+
│ ├── cli.rb # CLI interface
|
|
872
|
+
│ ├── dsl.rb # DSL definition
|
|
873
|
+
│ ├── executor.rb # SSH/SCP executor
|
|
874
|
+
│ ├── runner.rb # Task runner
|
|
875
|
+
│ ├── command_executor.rb # Command executor
|
|
876
|
+
│ ├── command_grouper.rb # Command grouper
|
|
877
|
+
│ ├── template.rb # Template handler
|
|
878
|
+
│ ├── output.rb # Output interface
|
|
879
|
+
│ ├── configuration.rb # Configuration
|
|
880
|
+
│ ├── errors.rb # Error types
|
|
881
|
+
│ └── ...
|
|
882
|
+
├── spec/ # Tests
|
|
883
|
+
├── exe/ # Executables
|
|
884
|
+
├── sample/ # Example projects
|
|
885
|
+
└── README.md # This file
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
### Running Tests
|
|
889
|
+
|
|
890
|
+
```bash
|
|
891
|
+
# Run all tests
|
|
892
|
+
bundle exec rspec
|
|
893
|
+
|
|
894
|
+
# Run specific test file
|
|
895
|
+
bundle exec rspec spec/kdeploy_spec.rb
|
|
896
|
+
|
|
897
|
+
# Run with coverage
|
|
898
|
+
COVERAGE=true bundle exec rspec
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
### Building the Gem
|
|
902
|
+
|
|
903
|
+
```bash
|
|
904
|
+
# Build gem
|
|
905
|
+
gem build kdeploy.gemspec
|
|
906
|
+
|
|
907
|
+
# Install locally
|
|
908
|
+
gem install ./kdeploy-*.gem
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
### Code Style
|
|
912
|
+
|
|
913
|
+
The project uses RuboCop for code style:
|
|
914
|
+
|
|
915
|
+
```bash
|
|
916
|
+
# Check style
|
|
917
|
+
bundle exec rubocop
|
|
918
|
+
|
|
919
|
+
# Auto-fix issues
|
|
920
|
+
bundle exec rubocop -a
|
|
921
|
+
```
|
|
237
922
|
|
|
238
923
|
## 🤝 Contributing
|
|
239
924
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
925
|
+
Contributions are welcome! Please follow these steps:
|
|
926
|
+
|
|
927
|
+
1. **Fork the repository**
|
|
928
|
+
2. **Create a feature branch**: `git checkout -b feature/my-new-feature`
|
|
929
|
+
3. **Make your changes**: Follow the code style and add tests
|
|
930
|
+
4. **Commit your changes**: Use conventional commit messages
|
|
931
|
+
5. **Push to the branch**: `git push origin feature/my-new-feature`
|
|
932
|
+
6. **Create a Pull Request**: Provide a clear description of changes
|
|
933
|
+
|
|
934
|
+
### Contribution Guidelines
|
|
935
|
+
|
|
936
|
+
- Follow existing code style
|
|
937
|
+
- Add tests for new features
|
|
938
|
+
- Update documentation
|
|
939
|
+
- Ensure all tests pass
|
|
940
|
+
- Follow conventional commit format
|
|
941
|
+
|
|
942
|
+
### Commit Message Format
|
|
943
|
+
|
|
944
|
+
Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
945
|
+
|
|
946
|
+
```
|
|
947
|
+
<type>(<scope>): <subject>
|
|
948
|
+
|
|
949
|
+
<body>
|
|
950
|
+
|
|
951
|
+
<footer>
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
|
|
955
|
+
|
|
956
|
+
## 📚 Examples
|
|
957
|
+
|
|
958
|
+
### Example Projects
|
|
959
|
+
|
|
960
|
+
Check out the [example project](https://github.com/kevin197011/kdeploy-app) for a complete deployment setup.
|
|
961
|
+
|
|
962
|
+
### Common Deployment Scenarios
|
|
963
|
+
|
|
964
|
+
#### Web Application Deployment
|
|
965
|
+
|
|
966
|
+
```ruby
|
|
967
|
+
host "web01", user: "deploy", ip: "10.0.0.1", key: "~/.ssh/id_rsa"
|
|
968
|
+
role :web, %w[web01]
|
|
969
|
+
|
|
970
|
+
task :deploy_app, roles: :web do
|
|
971
|
+
run <<~SHELL
|
|
972
|
+
cd /var/www/app
|
|
973
|
+
git pull origin main
|
|
974
|
+
bundle install
|
|
975
|
+
rake db:migrate
|
|
976
|
+
sudo systemctl restart puma
|
|
977
|
+
SHELL
|
|
978
|
+
end
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
#### Database Backup
|
|
982
|
+
|
|
983
|
+
```ruby
|
|
984
|
+
host "db01", user: "postgres", ip: "10.0.0.10", key: "~/.ssh/id_rsa"
|
|
985
|
+
role :db, %w[db01]
|
|
986
|
+
|
|
987
|
+
task :backup, roles: :db do
|
|
988
|
+
run <<~SHELL
|
|
989
|
+
pg_dump mydb > /tmp/backup_$(date +%Y%m%d).sql
|
|
990
|
+
gzip /tmp/backup_*.sql
|
|
991
|
+
aws s3 cp /tmp/backup_*.sql.gz s3://backups/
|
|
992
|
+
rm /tmp/backup_*.sql.gz
|
|
993
|
+
SHELL
|
|
994
|
+
end
|
|
995
|
+
```
|
|
996
|
+
|
|
997
|
+
#### Configuration Management
|
|
998
|
+
|
|
999
|
+
```ruby
|
|
1000
|
+
task :update_config, roles: :web do
|
|
1001
|
+
upload_template "./config/app.yml.erb", "/etc/app/config.yml",
|
|
1002
|
+
environment: "production",
|
|
1003
|
+
database_url: ENV['DATABASE_URL'],
|
|
1004
|
+
redis_url: ENV['REDIS_URL']
|
|
1005
|
+
|
|
1006
|
+
run "sudo systemctl reload app"
|
|
1007
|
+
end
|
|
1008
|
+
```
|
|
245
1009
|
|
|
246
1010
|
## 📝 License
|
|
247
1011
|
|
|
248
1012
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
249
1013
|
|
|
250
|
-
##
|
|
1014
|
+
## 🔗 Links
|
|
1015
|
+
|
|
1016
|
+
- **GitHub**: https://github.com/kevin197011/kdeploy
|
|
1017
|
+
- **RubyGems**: https://rubygems.org/gems/kdeploy
|
|
1018
|
+
- **Issues**: https://github.com/kevin197011/kdeploy/issues
|
|
1019
|
+
- **Example Project**: https://github.com/kevin197011/kdeploy-app
|
|
1020
|
+
|
|
1021
|
+
## 🙏 Acknowledgments
|
|
1022
|
+
|
|
1023
|
+
- Built with [Thor](https://github.com/rails/thor) for CLI
|
|
1024
|
+
- Uses [net-ssh](https://github.com/net-ssh/net-ssh) for SSH operations
|
|
1025
|
+
- Powered by [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby) for concurrency
|
|
1026
|
+
|
|
1027
|
+
---
|
|
251
1028
|
|
|
252
|
-
|
|
1029
|
+
**Made with ❤️ for the DevOps community**
|