vibed-infra 0.10.0 → 0.12.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.
package/README.md CHANGED
@@ -19,6 +19,8 @@ git add dist && git commit && git push
19
19
 
20
20
  ## Operator flow (VPS)
21
21
 
22
+ Non-root agent prep (SSH, Docker group, one-time uid-1000 operator or ~/services ACL): [`skills/agent-vps-prep/SKILL.md`](skills/agent-vps-prep/SKILL.md).
23
+
22
24
  ```bash
23
25
  # 1) DNS — paste dist/DNS-SKILL.md into AU browser agent
24
26
  # 2) App roles
@@ -62,7 +64,7 @@ See [`skills/infra-update-agent/SKILL.md`](skills/infra-update-agent/SKILL.md).
62
64
  | `templates/update-agent/` | Queue agent + webhook |
63
65
  | `templates/persist-logs/` | Shipper install |
64
66
  | `lib/persistlog/` | Python append / seal / replay |
65
- | `skills/` | system-gateway, infra-update-agent, infra-cicd, infra-packager, persist-logs, dns-configure |
67
+ | `skills/` | system-gateway, agent-vps-prep, infra-update-agent, infra-cicd, infra-packager, persist-logs, dns-configure |
66
68
 
67
69
  ## Environment
68
70
 
@@ -220,7 +220,16 @@ def dump_yaml(data: Any, indent: int = 0) -> str:
220
220
  else:
221
221
  lines.append(f"{sp}{pref}{k}: {v}")
222
222
  else:
223
- lines.append(f"{sp}- {item}")
223
+ s = str(item)
224
+ if isinstance(item, bool):
225
+ s = "true" if item else "false"
226
+ elif item is None:
227
+ s = ""
228
+ elif any(c in s for c in ":{}[]#&*!|>'\"%@`") or s == "" or s.lower() in (
229
+ "null", "true", "false", "yes", "no", "on", "off",
230
+ ):
231
+ s = json.dumps(s)
232
+ lines.append(f"{sp}- {s}")
224
233
  return "\n".join(lines) + ("\n" if lines else "")
225
234
  return f"{sp}{data}\n"
226
235
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibed-infra",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Product-agnostic VPS packager: wget install, Docker Compose, TLS/nginx, auto-update",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: agent-vps-prep
3
+ description: >-
4
+ Prepare a fresh VPS for vibed-infra installs run by an automation agent
5
+ (cloud_agent): SSH key, sudoers, Docker group, one-time uid-1000/ACL ownership, firewall.
6
+ ---
7
+
8
+ # Prepare a VPS for vibed-infra (agent operator)
9
+
10
+ ## Who this is for
11
+
12
+ Non-root user (e.g. `cloud_agent`) that will run `wget …/dist/install-*.sh | bash`,
13
+ `setup-tls.sh` (docker certbot), and `start-*.sh` without interactive sudo.
14
+
15
+ ## 1. Create the operator user
16
+
17
+ **Preferred (configure once):** create the operator as **uid/gid 1000** so bind mounts match typical `USER node` images — no chown, no ACL, no per-app commands forever.
18
+
19
+ (as root — only if uid/gid 1000 are free: `getent passwd 1000`; `getent group 1000`)
20
+
21
+ ```bash
22
+ adduser --disabled-password --gecos "" --uid 1000 cloud_agent
23
+ # if group 1000 already named "node", either:
24
+ # adduser --uid 1000 --gid 1000 ...
25
+ # or rename/reuse that group carefully
26
+ groupmod -n cloud_agent node 2>/dev/null || true # only if appropriate on that host
27
+
28
+ mkdir -p /home/cloud_agent/.ssh
29
+ chmod 700 /home/cloud_agent/.ssh
30
+ # paste agent public key:
31
+ echo 'ssh-ed25519 AAAA… cloud_agent' >> /home/cloud_agent/.ssh/authorized_keys
32
+ chmod 600 /home/cloud_agent/.ssh/authorized_keys
33
+ chown -R cloud_agent:cloud_agent /home/cloud_agent/.ssh
34
+ ```
35
+
36
+ If `adduser --uid 1000` fails because 1000 is taken by a `node` user from a package:
37
+
38
+ - **Option A:** use that existing uid-1000 user as the agent (add docker group + SSH key to it)
39
+ - **Option B:** create `cloud_agent` with a different uid and use the **ACL fallback** in §5
40
+
41
+ ## 2. SSH from the agent machine
42
+
43
+ Generate a key if needed, then connect with `StrictHostKeyChecking=accept-new`:
44
+
45
+ ```bash
46
+ ssh-keygen -t ed25519 -f ~/.ssh/cloud_agent_vps -N ""
47
+ ssh -o StrictHostKeyChecking=accept-new -i ~/.ssh/cloud_agent_vps cloud_agent@VPS_IP
48
+ ```
49
+
50
+ ## 3. Install Docker + add user to docker group
51
+
52
+ ```bash
53
+ # as root — use distro docs or https://get.docker.com
54
+ usermod -aG docker cloud_agent
55
+ # cloud_agent must re-login for group to apply
56
+ ```
57
+
58
+ Verify as `cloud_agent`: `docker ps` (no sudo).
59
+
60
+ ## 4. Home ownership
61
+
62
+ If home was created oddly (root-owned `$HOME`):
63
+
64
+ ```bash
65
+ sudo chown -R cloud_agent:cloud_agent /home/cloud_agent
66
+ ```
67
+
68
+ vibed-infra defaults: `~/services/gateway`, `~/services/vibed-infra`, product dirs under `~/services/<app>/`.
69
+
70
+ ## 5. Bind-mount ownership (uid 1000) — configure once
71
+
72
+ Product images often run as `node` (uid/gid **1000**). If the operator creates `./data` / `./logs` as a *different* uid, containers hit `SQLITE_CANTOPEN` / `EACCES`. Fix this **once on the host**, not after every product install.
73
+
74
+ ### Preferred: operator is already uid 1000
75
+
76
+ If §1 created `cloud_agent` as uid/gid 1000, new trees under `~/services` are already writable by the container user. Nothing else to do.
77
+
78
+ ### Fallback (configure once on `~/services`): default ACL
79
+
80
+ When the operator is **not** uid 1000, grant uid 1000 rwx on every new file under services regardless of who creates it. Requires the `acl` package.
81
+
82
+ ```bash
83
+ # as root, once after creating cloud_agent (any uid)
84
+ apt-get install -y acl
85
+ install -d -o cloud_agent -g cloud_agent /home/cloud_agent/services
86
+ setfacl -m u:1000:rwx /home/cloud_agent/services
87
+ setfacl -d -m u:1000:rwx /home/cloud_agent/services
88
+ # also grant the operator full access via ACL defaults
89
+ setfacl -m u:cloud_agent:rwx /home/cloud_agent/services
90
+ setfacl -d -m u:cloud_agent:rwx /home/cloud_agent/services
91
+ ```
92
+
93
+ ### Recovery only
94
+
95
+ If someone already created wrong-owned dirs **before** uid-1000 or ACL setup:
96
+
97
+ ```bash
98
+ sudo chown -R 1000:1000 \
99
+ /home/cloud_agent/services/*/api/data \
100
+ /home/cloud_agent/services/*/api/persist-logs \
101
+ /home/cloud_agent/services/*/nodes/logs
102
+ ```
103
+
104
+ Do not rely on per-product `chown` as ongoing ops. Prefer fixing the host model above.
105
+
106
+ ## 6. Ports + DNS
107
+
108
+ - Free **80/443** for the host gateway (only vps-gateway binds them)
109
+ - Point DNS A records at `gateway.publicIp` before `setup-tls.sh` (Let’s Encrypt)
110
+
111
+ ## 7. TLS (no host certbot required)
112
+
113
+ With Docker, `setup-tls.sh` uses `certbot/certbot` and writes PEMs under `~/services/gateway/certs/`. No sudo needed for LE when docker works. See [system-gateway](../system-gateway/SKILL.md).
114
+
115
+ ## 8. First product install
116
+
117
+ ```bash
118
+ export INSTALL_DIR=$HOME/services/myapp/api
119
+ mkdir -p "$INSTALL_DIR"
120
+ wget -qO- https://raw.githubusercontent.com/ORG/REPO/main/deploy/.../dist/install-api.sh | bash
121
+ # edit .env, then ./start-api.sh
122
+ # repeat ui, nodes, gateway
123
+ ```
124
+
125
+ **Important:** `export INSTALL_DIR=...` before the pipe — `INSTALL_DIR=... wget | bash` does **not** pass the var into bash.
126
+
127
+ ## 9. Checklist
128
+
129
+ - [ ] `ssh cloud_agent@VPS` works with key only
130
+ - [ ] `docker ps` works without sudo
131
+ - [ ] `$HOME` owned by `cloud_agent`
132
+ - [ ] operator uid is 1000 **OR** `~/services` has default ACL for `u:1000` (and `u:cloud_agent` if needed)
133
+ - [ ] DNS → VPS IP
134
+ - [ ] install-gateway + setup-tls + start-gateway
@@ -7,6 +7,8 @@ description: >-
7
7
 
8
8
  # System-wide host gateway (multi-app)
9
9
 
10
+ Fresh VPS as non-root agent: see [agent-vps-prep](../agent-vps-prep/SKILL.md).
11
+
10
12
  ## Model
11
13
 
12
14
  ```
@@ -64,6 +66,7 @@ Host `00-default.conf` (HTTP) and each app `sites.conf` (HTTPS) proxy `/_vibed/h
64
66
 
65
67
  ## Pitfalls
66
68
 
69
+ - Operator user / Docker / one-time uid-1000 or ACL (not per-app chown): [agent-vps-prep](../agent-vps-prep/SKILL.md).
67
70
  - Do not run a second standalone nginx on 80/443.
68
71
  - Container names in `sites.conf` must match running API/UI names on `vps-edge`.
69
72
  - After cert renewal or `setup-tls.sh`, reload happens automatically when the gateway container is already running.