redeploy 0.1.2__tar.gz → 0.1.4__tar.gz
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.
- redeploy-0.1.4/PKG-INFO +402 -0
- redeploy-0.1.4/README.md +379 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/pyproject.toml +1 -1
- redeploy-0.1.4/redeploy/__init__.py +12 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/apply/executor.py +18 -18
- redeploy-0.1.4/redeploy/cli.py +1184 -0
- redeploy-0.1.4/redeploy/detect/templates.py +459 -0
- redeploy-0.1.4/redeploy/detect/workflow.py +418 -0
- redeploy-0.1.4/redeploy/discovery.py +665 -0
- redeploy-0.1.4/redeploy/fleet.py +257 -0
- redeploy-0.1.4/redeploy/models.py +560 -0
- redeploy-0.1.4/redeploy/parse.py +169 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/plan/planner.py +185 -10
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/ssh.py +28 -0
- redeploy-0.1.4/redeploy/steps.py +294 -0
- redeploy-0.1.4/redeploy/tests/test_data_sync.py +117 -0
- redeploy-0.1.4/redeploy/tests/test_discovery.py +231 -0
- redeploy-0.1.4/redeploy/tests/test_examples.py +489 -0
- redeploy-0.1.4/redeploy/tests/test_executor.py +478 -0
- redeploy-0.1.4/redeploy/tests/test_fleet.py +271 -0
- redeploy-0.1.4/redeploy/tests/test_manifest.py +338 -0
- redeploy-0.1.4/redeploy/tests/test_parse.py +268 -0
- redeploy-0.1.4/redeploy/tests/test_planner_edge.py +350 -0
- redeploy-0.1.4/redeploy/tests/test_probes.py +346 -0
- redeploy-0.1.4/redeploy/tests/test_templates.py +424 -0
- redeploy-0.1.4/redeploy/tests/test_verify.py +218 -0
- redeploy-0.1.4/redeploy/tests/test_version.py +219 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/version.py +3 -2
- redeploy-0.1.4/redeploy.egg-info/PKG-INFO +402 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy.egg-info/SOURCES.txt +19 -0
- redeploy-0.1.4/tests/test_parse.py +157 -0
- redeploy-0.1.2/PKG-INFO +0 -168
- redeploy-0.1.2/README.md +0 -145
- redeploy-0.1.2/redeploy/__init__.py +0 -2
- redeploy-0.1.2/redeploy/cli.py +0 -383
- redeploy-0.1.2/redeploy/models.py +0 -271
- redeploy-0.1.2/redeploy.egg-info/PKG-INFO +0 -168
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/apply/__init__.py +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/data_sync.py +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/detect/__init__.py +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/detect/detector.py +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/detect/probes.py +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/detect/remote.py +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/plan/__init__.py +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/tests/__init__.py +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/tests/test_models.py +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/tests/test_ssh.py +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy/verify.py +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy.egg-info/dependency_links.txt +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy.egg-info/entry_points.txt +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy.egg-info/requires.txt +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/redeploy.egg-info/top_level.txt +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/setup.cfg +0 -0
- {redeploy-0.1.2 → redeploy-0.1.4}/tests/test_redeploy.py +0 -0
redeploy-0.1.4/PKG-INFO
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: redeploy
|
|
3
|
+
Version: 0.1.4
|
|
4
|
+
Summary: Infrastructure migration toolkit: detect → plan → apply
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: pydantic>=2.0
|
|
8
|
+
Requires-Dist: pyyaml>=6.0
|
|
9
|
+
Requires-Dist: click>=8.0
|
|
10
|
+
Requires-Dist: loguru>=0.7
|
|
11
|
+
Requires-Dist: paramiko>=3.0
|
|
12
|
+
Requires-Dist: httpx>=0.25
|
|
13
|
+
Requires-Dist: rich>=13.0
|
|
14
|
+
Requires-Dist: goal>=2.1.0
|
|
15
|
+
Requires-Dist: costs>=0.1.20
|
|
16
|
+
Requires-Dist: pfix>=0.1.60
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
19
|
+
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
20
|
+
Requires-Dist: goal>=2.1.0; extra == "dev"
|
|
21
|
+
Requires-Dist: costs>=0.1.20; extra == "dev"
|
|
22
|
+
Requires-Dist: pfix>=0.1.60; extra == "dev"
|
|
23
|
+
|
|
24
|
+
# redeploy
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## AI Cost Tracking
|
|
28
|
+
|
|
29
|
+
   
|
|
30
|
+
  
|
|
31
|
+
|
|
32
|
+
- 🤖 **LLM usage:** $1.6500 (11 commits)
|
|
33
|
+
- 👤 **Human dev:** ~$326 (3.3h @ $100/h, 30min dedup)
|
|
34
|
+
|
|
35
|
+
Generated on 2026-04-20 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
   
|
|
40
|
+
|
|
41
|
+
Infrastructure migration and device deploy toolkit — VPS, Raspberry Pi kiosk, Podman Quadlet, k3s.
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
redeploy detect → live probe host (what is there now)
|
|
45
|
+
redeploy plan → migration-plan.yaml (what to do)
|
|
46
|
+
redeploy apply → execute plan (do it)
|
|
47
|
+
redeploy run → detect + plan + apply (all at once from spec)
|
|
48
|
+
redeploy scan → find devices on LAN (device registry)
|
|
49
|
+
redeploy target → deploy to named device (fleet)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Install
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Recommended — installs CLI globally (no venv conflicts)
|
|
56
|
+
pipx install redeploy
|
|
57
|
+
|
|
58
|
+
# Or inside a venv
|
|
59
|
+
pip install redeploy
|
|
60
|
+
|
|
61
|
+
# With doql integration (generates migration.yaml from app.doql):
|
|
62
|
+
pip install doql[deploy]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Quick start — VPS production deploy
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# 1. Create spec file
|
|
69
|
+
cat > migration.yaml << 'EOF'
|
|
70
|
+
name: "myapp deploy 1.0.19 → 1.0.20"
|
|
71
|
+
source:
|
|
72
|
+
strategy: docker_full
|
|
73
|
+
host: root@YOUR_VPS_IP
|
|
74
|
+
app: myapp
|
|
75
|
+
version: "1.0.19"
|
|
76
|
+
target:
|
|
77
|
+
strategy: docker_full
|
|
78
|
+
host: root@YOUR_VPS_IP
|
|
79
|
+
app: myapp
|
|
80
|
+
version: "1.0.20"
|
|
81
|
+
domain: myapp.example.com
|
|
82
|
+
env_file: envs/prod.env
|
|
83
|
+
compose_files:
|
|
84
|
+
- docker-compose.prod.yml
|
|
85
|
+
verify_url: https://myapp.example.com/api/v1/health
|
|
86
|
+
verify_version: "1.0.20"
|
|
87
|
+
EOF
|
|
88
|
+
|
|
89
|
+
# 2. Preview steps (no SSH needed)
|
|
90
|
+
redeploy run migration.yaml --plan-only
|
|
91
|
+
|
|
92
|
+
# 3. Dry run (connects via SSH, makes no changes)
|
|
93
|
+
redeploy run migration.yaml --dry-run
|
|
94
|
+
|
|
95
|
+
# 4. Full deploy (live detect → plan → apply)
|
|
96
|
+
redeploy run migration.yaml --detect
|
|
97
|
+
|
|
98
|
+
# Or without --detect (faster, uses spec source as-is)
|
|
99
|
+
redeploy run migration.yaml
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Quick start — Raspberry Pi kiosk
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Register the RPi in the device registry
|
|
106
|
+
redeploy device-add pi@192.168.1.42 \
|
|
107
|
+
--tag kiosk --tag rpi4 \
|
|
108
|
+
--strategy native_kiosk \
|
|
109
|
+
--app kiosk-app \
|
|
110
|
+
--name "Workshop kiosk #1"
|
|
111
|
+
|
|
112
|
+
# Preview deploy plan
|
|
113
|
+
redeploy target pi@192.168.1.42 migration.yaml --plan-only
|
|
114
|
+
|
|
115
|
+
# Dry run
|
|
116
|
+
redeploy target pi@192.168.1.42 migration.yaml --dry-run
|
|
117
|
+
|
|
118
|
+
# Deploy
|
|
119
|
+
redeploy target pi@192.168.1.42 migration.yaml --detect
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Device registry — find and manage devices
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Discover SSH-accessible devices on local network (passive: known_hosts + ARP + mDNS)
|
|
126
|
+
redeploy scan
|
|
127
|
+
|
|
128
|
+
# Active ICMP ping sweep (sends packets)
|
|
129
|
+
redeploy scan --ping --subnet 192.168.1.0/24
|
|
130
|
+
|
|
131
|
+
# Try specific SSH users
|
|
132
|
+
redeploy scan --user pi --user ubuntu --timeout 8
|
|
133
|
+
|
|
134
|
+
# List all known devices
|
|
135
|
+
redeploy devices
|
|
136
|
+
|
|
137
|
+
# Filter by tag or strategy
|
|
138
|
+
redeploy devices --tag kiosk
|
|
139
|
+
redeploy devices --strategy native_kiosk
|
|
140
|
+
redeploy devices --reachable # seen in last 5 minutes
|
|
141
|
+
|
|
142
|
+
# JSON output for scripting
|
|
143
|
+
redeploy devices --json | jq '.[] | select(.tags | index("prod"))'
|
|
144
|
+
|
|
145
|
+
# Add device manually
|
|
146
|
+
redeploy device-add root@10.0.0.5 --tag prod --strategy docker_full --app myapp
|
|
147
|
+
|
|
148
|
+
# Remove device
|
|
149
|
+
redeploy device-rm root@10.0.0.5
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Registry is stored at `~/.config/redeploy/devices.yaml` (chmod 600 — safe for SSH key paths).
|
|
153
|
+
|
|
154
|
+
## CLI reference
|
|
155
|
+
|
|
156
|
+
### `redeploy run SPEC [options]`
|
|
157
|
+
|
|
158
|
+
Execute deploy from a YAML spec file (or `redeploy.yaml` project manifest if no arg).
|
|
159
|
+
|
|
160
|
+
| Option | Description |
|
|
161
|
+
|--------|-------------|
|
|
162
|
+
| `--plan-only` | Show steps without connecting via SSH |
|
|
163
|
+
| `--dry-run` | Connect, show steps, make no changes |
|
|
164
|
+
| `--detect` | Live-probe host before planning (recommended for prod) |
|
|
165
|
+
| `--plan-out FILE` | Save generated plan to file |
|
|
166
|
+
|
|
167
|
+
### `redeploy scan [options]`
|
|
168
|
+
|
|
169
|
+
Discover SSH-accessible devices on the local network.
|
|
170
|
+
|
|
171
|
+
| Source | Network activity | Requires |
|
|
172
|
+
|--------|-----------------|---------|
|
|
173
|
+
| `known_hosts` | none | `~/.ssh/known_hosts` |
|
|
174
|
+
| `arp` | none | `ip neigh` / `arp -a` |
|
|
175
|
+
| `mdns` | passive listen | `avahi-browse` |
|
|
176
|
+
| `ping_sweep` | ICMP — **active** | `--ping` flag |
|
|
177
|
+
|
|
178
|
+
All SSH-reachable devices are saved to registry. Existing entries updated (last_seen, mac, hostname). Old entries never deleted.
|
|
179
|
+
|
|
180
|
+
### `redeploy target DEVICE_ID [SPEC] [options]`
|
|
181
|
+
|
|
182
|
+
Deploy a spec to a registered device. Device's `host`, `strategy`, `app`, `domain` are overlaid onto the spec.
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
redeploy target pi@192.168.1.42 # uses migration.yaml in cwd
|
|
186
|
+
redeploy target pi@192.168.1.42 custom.yaml --dry-run
|
|
187
|
+
redeploy target prod-vps --detect --plan-only
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
After successful deploy, a `DeployRecord` is saved to the device in registry (timestamp, strategy, version, ok/fail).
|
|
191
|
+
|
|
192
|
+
### `redeploy detect / plan / apply / migrate / init / status`
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
redeploy detect --host root@VPS_IP --app myapp -o infra.yaml
|
|
196
|
+
redeploy plan --infra infra.yaml --target target.yaml -o plan.yaml
|
|
197
|
+
redeploy apply --plan plan.yaml
|
|
198
|
+
redeploy migrate --host root@VPS_IP --app myapp --target target.yaml # all in one
|
|
199
|
+
redeploy init # scaffold migration.yaml + redeploy.yaml
|
|
200
|
+
redeploy status # show project manifest summary
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Deployment strategies
|
|
204
|
+
|
|
205
|
+
| Strategy | Description | Use case |
|
|
206
|
+
|----------|-------------|----------|
|
|
207
|
+
| `docker_full` | Docker Compose — build + up | VPS production |
|
|
208
|
+
| `podman_quadlet` | Rootless Podman systemd units | Quadlet/rootless VPS |
|
|
209
|
+
| `native_kiosk` | systemd + Chromium Openbox | RPi kiosk (no Docker) |
|
|
210
|
+
| `docker_kiosk` | Podman Quadlet in kiosk mode | RPi kiosk with container |
|
|
211
|
+
| `k3s` | Kubernetes/k3s | K3s cluster |
|
|
212
|
+
| `systemd` | Native systemd service | Bare metal |
|
|
213
|
+
|
|
214
|
+
### `native_kiosk` plan steps
|
|
215
|
+
|
|
216
|
+
Generated automatically when `strategy: native_kiosk`:
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
rsync_build → sync build/ to device
|
|
220
|
+
run_kiosk_installer → bash build/infra/install-kiosk.sh
|
|
221
|
+
install_kiosk_service → scp kiosk.service → /etc/systemd/system/
|
|
222
|
+
enable_kiosk_service → systemctl enable --now
|
|
223
|
+
wait_kiosk_start → 20s
|
|
224
|
+
http_health_check → curl http://localhost:8080
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### `docker_kiosk` plan steps
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
rsync_build → sync build/ to device
|
|
231
|
+
install_kiosk_quadlet → cp *.container → ~/.config/containers/systemd/ + daemon-reload
|
|
232
|
+
start_kiosk_container → systemctl --user restart app.service
|
|
233
|
+
wait_kiosk_start → 20s
|
|
234
|
+
http_health_check → curl http://localhost:8080
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### `podman_quadlet` plan steps
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
sync_env → scp .env to remote
|
|
241
|
+
install_quadlet_files → cp *.container *.network *.volume → ~/.config/containers/systemd/
|
|
242
|
+
podman_daemon_reload → systemctl --user daemon-reload
|
|
243
|
+
stop_<app> → systemctl --user stop <app>.service
|
|
244
|
+
start_<app> → systemctl --user start <app>.service
|
|
245
|
+
wait_startup → 15s
|
|
246
|
+
http_health_check → verify_url health endpoint
|
|
247
|
+
version_check → verify_version match
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
For system (root) mode, set `stop_services: true` in `target` — switches to `systemctl` (no `--user`) and `/etc/containers/systemd/`.
|
|
251
|
+
|
|
252
|
+
### `docker_full` plan steps
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
sync_env → scp env_file → remote_dir/.env
|
|
256
|
+
docker_build_pull → docker compose build (on remote)
|
|
257
|
+
docker_compose_up → docker compose up -d --build
|
|
258
|
+
wait_startup → 30s
|
|
259
|
+
http_health_check → verify_url health endpoint
|
|
260
|
+
version_check → verify_version match
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## `migration.yaml` spec format
|
|
264
|
+
|
|
265
|
+
```yaml
|
|
266
|
+
name: "myapp deploy 1.0.19 → 1.0.20"
|
|
267
|
+
description: "Production VPS version bump"
|
|
268
|
+
|
|
269
|
+
source:
|
|
270
|
+
strategy: docker_full # docker_full | podman_quadlet | native_kiosk | docker_kiosk | k3s | systemd
|
|
271
|
+
host: root@87.106.87.183 # SSH target (user@ip) or "local"
|
|
272
|
+
app: myapp
|
|
273
|
+
version: "1.0.19"
|
|
274
|
+
domain: myapp.example.com
|
|
275
|
+
remote_dir: ~/myapp
|
|
276
|
+
|
|
277
|
+
target:
|
|
278
|
+
strategy: docker_full
|
|
279
|
+
host: root@87.106.87.183
|
|
280
|
+
app: myapp
|
|
281
|
+
version: "1.0.20"
|
|
282
|
+
domain: myapp.example.com
|
|
283
|
+
remote_dir: ~/myapp
|
|
284
|
+
compose_files:
|
|
285
|
+
- docker-compose.vps.yml
|
|
286
|
+
env_file: envs/vps.env
|
|
287
|
+
verify_url: https://myapp.example.com/api/v1/health
|
|
288
|
+
verify_version: "1.0.20"
|
|
289
|
+
|
|
290
|
+
extra_steps: # optional — appended or inserted
|
|
291
|
+
- id: flush_k3s_iptables # StepLibrary name — no action needed
|
|
292
|
+
insert_before: docker_build_pull # inject before specific step
|
|
293
|
+
- id: docker_prune # StepLibrary: prune unused images
|
|
294
|
+
- id: notify_slack # custom step (needs action:)
|
|
295
|
+
action: ssh_cmd
|
|
296
|
+
description: "Send deploy notification"
|
|
297
|
+
command: "curl -s -X POST $SLACK_WEBHOOK -d '{\"text\":\"deployed 1.0.20\"}'"
|
|
298
|
+
risk: low
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## StepLibrary — reusable named steps
|
|
302
|
+
|
|
303
|
+
Reference any step by `id` alone — no `action` needed. Fields can be overridden:
|
|
304
|
+
|
|
305
|
+
```yaml
|
|
306
|
+
extra_steps:
|
|
307
|
+
- id: flush_k3s_iptables # use as-is
|
|
308
|
+
- id: stop_k3s
|
|
309
|
+
- id: http_health_check
|
|
310
|
+
url: https://myapp.example.com/health # override url
|
|
311
|
+
- id: wait_startup_long # 60s instead of 30s
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
| ID | Action | Description |
|
|
315
|
+
|----|--------|-------------|
|
|
316
|
+
| `flush_k3s_iptables` | `ssh_cmd` | Flush CNI-HOSTPORT-DNAT + KUBE-* chains (stale k3s rules block Docker-proxy on 80/443) |
|
|
317
|
+
| `delete_k3s_ingresses` | `kubectl_delete` | Delete all k3s ingresses |
|
|
318
|
+
| `stop_k3s` | `systemctl_stop` | Stop k3s service |
|
|
319
|
+
| `disable_k3s` | `systemctl_disable` | Disable k3s on boot |
|
|
320
|
+
| `stop_nginx` | `systemctl_stop` | Stop host nginx (port 80 conflict) |
|
|
321
|
+
| `restart_traefik` | `ssh_cmd` | Restart Traefik container |
|
|
322
|
+
| `docker_prune` | `ssh_cmd` | Prune unused images + build cache |
|
|
323
|
+
| `docker_compose_down` | `docker_compose_down` | Stop Docker Compose stack |
|
|
324
|
+
| `wait_startup` | `wait` | Wait 30s |
|
|
325
|
+
| `wait_startup_long` | `wait` | Wait 60s |
|
|
326
|
+
| `http_health_check` | `http_check` | Verify health endpoint (`expect: healthy`) |
|
|
327
|
+
| `version_check` | `version_check` | Verify deployed version |
|
|
328
|
+
| `sync_env` | `scp` | Copy .env to remote |
|
|
329
|
+
| `podman_daemon_reload` | `systemctl_start` | `systemctl --user daemon-reload` |
|
|
330
|
+
|
|
331
|
+
### `insert_before`
|
|
332
|
+
|
|
333
|
+
By default extra steps are appended after all generated steps. Use `insert_before: <step_id>` to inject at a specific position:
|
|
334
|
+
|
|
335
|
+
```yaml
|
|
336
|
+
extra_steps:
|
|
337
|
+
- id: flush_k3s_iptables
|
|
338
|
+
insert_before: docker_build_pull # runs before build, not after verify
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## `redeploy.yaml` project manifest
|
|
342
|
+
|
|
343
|
+
Place in project root — `redeploy run` (no args) uses it automatically:
|
|
344
|
+
|
|
345
|
+
```yaml
|
|
346
|
+
spec: migration.yaml # default spec file
|
|
347
|
+
host: root@87.106.87.183
|
|
348
|
+
app: myapp
|
|
349
|
+
domain: myapp.example.com
|
|
350
|
+
ssh_port: 22
|
|
351
|
+
env_file: envs/vps.env
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## doql integration
|
|
355
|
+
|
|
356
|
+
redeploy is the deploy engine for [doql](https://github.com/softreck/doql) declarative apps.
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
# Install with doql integration
|
|
360
|
+
pip install doql[deploy]
|
|
361
|
+
|
|
362
|
+
# doql build generates build/infra/migration.yaml automatically
|
|
363
|
+
DEPLOY_HOST=root@YOUR_VPS doql build
|
|
364
|
+
|
|
365
|
+
# Then deploy — no args needed
|
|
366
|
+
doql deploy # calls redeploy API internally
|
|
367
|
+
doql deploy --plan-only
|
|
368
|
+
doql deploy --dry-run
|
|
369
|
+
doql quadlet --install # installs Quadlet units via redeploy
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
doql `DEPLOY.target` → redeploy `strategy` mapping:
|
|
373
|
+
|
|
374
|
+
| doql | redeploy |
|
|
375
|
+
|------|---------|
|
|
376
|
+
| `docker-compose` | `docker_full` |
|
|
377
|
+
| `quadlet` | `podman_quadlet` |
|
|
378
|
+
| `kiosk-appliance` | `native_kiosk` |
|
|
379
|
+
| `kubernetes` | `k3s` |
|
|
380
|
+
|
|
381
|
+
## Examples
|
|
382
|
+
|
|
383
|
+
| Directory | Scenario | Strategy |
|
|
384
|
+
|-----------|----------|----------|
|
|
385
|
+
| `01-vps-version-bump` | VPS Docker version bump | `docker_full → docker_full` |
|
|
386
|
+
| `02-k3s-to-docker` | Migrate off k3s | `k3s → docker_full` |
|
|
387
|
+
| `03-docker-to-podman-quadlet` | Move to rootless Podman | `docker_full → podman_quadlet` |
|
|
388
|
+
| `04-rpi-kiosk` | Raspberry Pi kiosk update | `native_kiosk → native_kiosk` |
|
|
389
|
+
| `05-iot-fleet-ota` | IoT fleet OTA update | `docker_full → docker_full` |
|
|
390
|
+
| `09-fleet-yaml` | Fleet with stages + scan | fleet + `redeploy target` |
|
|
391
|
+
| `11-traefik-tls` | Traefik + Let's Encrypt | `docker_full → podman_quadlet` |
|
|
392
|
+
| `12-ci-pipeline` | GitHub Actions / GitLab CI | CI-triggered `docker_full` |
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
# Run any example in dry-run mode (no SSH required):
|
|
396
|
+
redeploy run examples/01-vps-version-bump/migration.yaml --plan-only
|
|
397
|
+
redeploy run examples/04-rpi-kiosk/migration.yaml --plan-only
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
## License
|
|
401
|
+
|
|
402
|
+
Licensed under Apache-2.0.
|