@iamken/cloudtunnel 0.2.0 → 0.4.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 +76 -75
- package/dist/index.js +465 -517
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,21 +16,21 @@ Instant, self-owned tunnel sharing — the tunnel and DNS live in **your** Cloud
|
|
|
16
16
|
```bash
|
|
17
17
|
npm i -g @iamken/cloudtunnel
|
|
18
18
|
|
|
19
|
-
cloudtunnel login
|
|
20
|
-
cloudtunnel
|
|
19
|
+
cloudtunnel login # once — paste a Cloudflare token; account + domain auto-resolved
|
|
20
|
+
cloudtunnel 8080 # → https://brave-otter-1a2b.example.com is live ✨
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
> 💨 Prefer less typing? **`ctun`** is a built-in short alias — `ctun
|
|
23
|
+
> 💨 Prefer less typing? **`ctun`** is a built-in short alias — `ctun 8080`, `ctun ls`, `ctun delete 1`.
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
27
|
## ✨ Why cloudtunnel
|
|
28
28
|
|
|
29
29
|
- 🔗 **Your domains, real subdomains** — routes through native Cloudflare Tunnel to `*.your-domain.com`, not a shared third-party host.
|
|
30
|
-
- ⚡ **One command** — `cloudtunnel
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
- 🌙 **Background
|
|
30
|
+
- ⚡ **One command, one or many** — `cloudtunnel api:8080 web:5173` brings up several tunnels at once, each a live HTTPS URL.
|
|
31
|
+
- 🎯 **Spec-driven** — a tunnel is just `[subdomain:]port[@host]`. No profiles to define, nothing to save.
|
|
32
|
+
- 🧭 **Two states** — `up` brings subdomains online; `delete` (or Ctrl-C) releases them (removes the tunnel + DNS). Re-running `up` always starts clean.
|
|
33
|
+
- 🌙 **Background & boot** — `--detach` keeps connectors running after you close the terminal; `--service` registers a systemd unit that survives reboots.
|
|
34
34
|
- 🔒 **Secure by default** — token passed via env (never argv), stored `0600`, destructive ops are ownership-gated and re-verified.
|
|
35
35
|
|
|
36
36
|
---
|
|
@@ -38,31 +38,25 @@ cloudtunnel 3000 # → https://brave-otter-1a2b.example.com is live ✨
|
|
|
38
38
|
## 🚀 Quickstart
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
cloudtunnel login
|
|
42
|
-
cloudtunnel
|
|
43
|
-
cloudtunnel
|
|
44
|
-
cloudtunnel
|
|
45
|
-
cloudtunnel
|
|
46
|
-
cloudtunnel
|
|
41
|
+
cloudtunnel login # authenticate once
|
|
42
|
+
cloudtunnel 8080 # asks for a subdomain (+ domain), then goes live
|
|
43
|
+
cloudtunnel api:8080 # api.<your-domain> → localhost:8080
|
|
44
|
+
cloudtunnel api:8080@192.168.1.20 # forward to another host/IP (IPv4/IPv6)
|
|
45
|
+
cloudtunnel api:8080 web:5173 -d foo.io # several tunnels at once, under foo.io
|
|
46
|
+
cloudtunnel api:8080 --detach # run in the background
|
|
47
|
+
cloudtunnel api:8080 --service # register a systemd boot service
|
|
47
48
|
```
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
A **spec** is `[subdomain:]port[@host]`:
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
| Spec | Means |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| `8080` | random subdomain → `localhost:8080` |
|
|
55
|
+
| `api:8080` | `api.<domain>` → `localhost:8080` |
|
|
56
|
+
| `api:8080@192.168.1.20` | `api.<domain>` → `192.168.1.20:8080` (a LAN device, container, another server) |
|
|
57
|
+
| `@:8080` | the root/apex domain itself |
|
|
52
58
|
|
|
53
|
-
|
|
54
|
-
┌ cloudtunnel
|
|
55
|
-
◇ Choose a domain
|
|
56
|
-
│ ● example.com ○ foo.io
|
|
57
|
-
◇ Subdomain
|
|
58
|
-
│ api (leave blank for a random name)
|
|
59
|
-
◇ Connected
|
|
60
|
-
│
|
|
61
|
-
◇ Live ─────────────────────────────────────────╮
|
|
62
|
-
│ https://api.example.com → http://localhost:3000
|
|
63
|
-
│ Ctrl-C stops and releases this subdomain
|
|
64
|
-
╰─────────────────────────────────────────────────╯
|
|
65
|
-
```
|
|
59
|
+
Run `cloudtunnel` with no arguments and it guides you (port → subdomain → domain). A missing subdomain becomes a friendly random name; a missing host is `localhost`. The local-service protocol is `--proto http|https` (default `http`); replacing an existing DNS record asks first — pass `-y` to skip, `-f` to also replace a non-tunnel record.
|
|
66
60
|
|
|
67
61
|
---
|
|
68
62
|
|
|
@@ -71,42 +65,24 @@ Run `cloudtunnel 3000` with no flags and it guides you:
|
|
|
71
65
|
| Command | What it does |
|
|
72
66
|
| --- | --- |
|
|
73
67
|
| `cloudtunnel login` | Authenticate; resolve account + list your domains. `--status` to inspect. |
|
|
74
|
-
| `cloudtunnel <
|
|
75
|
-
| `cloudtunnel ls` · `ps` | List
|
|
76
|
-
| `cloudtunnel
|
|
68
|
+
| `cloudtunnel <spec…>` · `up` | Bring one or more tunnels online. `-d/--domain`, `--proto`, `--protocol`, `--detach`, `--service`, `-f/--force`, `-y/--yes`. |
|
|
69
|
+
| `cloudtunnel ls` · `ps` | List tunnels — `# · URL · TARGET · STATE · SERVICE · PID`. `--all` scans the whole account. |
|
|
70
|
+
| `cloudtunnel delete <target…>` | Release tunnel(s) — stop connector + delete tunnel + DNS + any systemd service. `--all`, `--dry-run`, `-f`. |
|
|
77
71
|
| `cloudtunnel logs <target>` | Show a connector's log. `-f` to follow, `-n` for line count. |
|
|
78
|
-
| `cloudtunnel zones` | List the domains in your account. |
|
|
79
|
-
| `cloudtunnel save <profile> <svc…>` | Save a group of services. `svc` = `name:port[:proto]`, `-d/--domain`, `--protocol`, or `--from-running`. |
|
|
80
|
-
| `cloudtunnel run <profile> [--detach]` | Bring up every service in a profile at once. `--protocol` overrides the saved transport. |
|
|
81
|
-
| `cloudtunnel profiles [--rm <name>]` | List saved profiles — `PROFILE · SERVICES · DOMAIN · PROTOCOL · SERVICE`. |
|
|
82
|
-
| `cloudtunnel service enable\|disable\|status <profile>` | Register a profile as a systemd boot service (Linux, needs sudo). |
|
|
83
72
|
|
|
84
|
-
> A **`<target>`** is a `#` number, a subdomain name, a full hostname, or a tunnel-id prefix — all shown in `ls`.
|
|
73
|
+
> A **`<target>`** is a `#` number, a subdomain name, a full hostname/URL, or a tunnel-id prefix — all shown in `ls`.
|
|
85
74
|
|
|
86
75
|
```
|
|
87
76
|
$ cloudtunnel ls
|
|
88
|
-
|
|
89
|
-
│ # │
|
|
90
|
-
|
|
91
|
-
│ 1 │ api.example.com
|
|
92
|
-
│ 2 │ web.example.com
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
$ cloudtunnel
|
|
96
|
-
$ cloudtunnel
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
---
|
|
100
|
-
|
|
101
|
-
## 🗂️ Profiles
|
|
102
|
-
|
|
103
|
-
Expose a whole project's services with one command:
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
cloudtunnel save mb api:3000 web:5173:https # define the group (or: save mb --from-running)
|
|
107
|
-
cloudtunnel run mb --detach # backend + frontend live in the background
|
|
108
|
-
cloudtunnel logs api -f # follow one service's log
|
|
109
|
-
cloudtunnel down --all # release them all
|
|
77
|
+
┌───┬────────────────────────────┬────────────────────────┬───────┬─────────┬───────┐
|
|
78
|
+
│ # │ URL │ TARGET │ STATE │ SERVICE │ PID │
|
|
79
|
+
├───┼────────────────────────────┼────────────────────────┼───────┼─────────┼───────┤
|
|
80
|
+
│ 1 │ https://api.example.com │ http://localhost:8080 │ up │ active │ 48213 │
|
|
81
|
+
│ 2 │ https://web.example.com │ https://localhost:5173 │ down │ - │ - │
|
|
82
|
+
└───┴────────────────────────────┴────────────────────────┴───────┴─────────┴───────┘
|
|
83
|
+
|
|
84
|
+
$ cloudtunnel delete 1 # release by number
|
|
85
|
+
$ cloudtunnel delete --all # release everything
|
|
110
86
|
```
|
|
111
87
|
|
|
112
88
|
---
|
|
@@ -119,34 +95,41 @@ errors. Force **`http2`** (TCP) there:
|
|
|
119
95
|
|
|
120
96
|
```bash
|
|
121
97
|
cloudtunnel up 8080 --protocol http2
|
|
122
|
-
cloudtunnel save mb api:3000 web:5173 --protocol http2 # persist per profile
|
|
123
|
-
cloudtunnel run mb --protocol http2 # or override per run
|
|
124
98
|
```
|
|
125
99
|
|
|
126
100
|
Values: `auto` (default) · `http2` · `quic`.
|
|
127
101
|
|
|
128
102
|
---
|
|
129
103
|
|
|
130
|
-
## 🔁 Run on boot (
|
|
104
|
+
## 🔁 Run on boot (`--service`)
|
|
131
105
|
|
|
132
|
-
|
|
133
|
-
reboot (Linux + systemd; installs to
|
|
106
|
+
Add **`--service`** to register each subdomain as a **systemd service** so it comes
|
|
107
|
+
back automatically after a reboot (Linux + systemd; installs to
|
|
108
|
+
`/etc/systemd/system`, so it needs sudo):
|
|
134
109
|
|
|
135
110
|
```bash
|
|
136
|
-
cloudtunnel service
|
|
137
|
-
cloudtunnel
|
|
138
|
-
cloudtunnel
|
|
111
|
+
cloudtunnel api:8080 --service --protocol http2 # install + enable + start now
|
|
112
|
+
cloudtunnel api:8080 web:5173 --service # one unit per subdomain
|
|
113
|
+
cloudtunnel ls # the SERVICE column shows each unit's state
|
|
114
|
+
cloudtunnel delete api # stops + removes the tunnel and its unit
|
|
139
115
|
```
|
|
140
116
|
|
|
141
|
-
|
|
117
|
+
Each subdomain gets its own unit, so deleting one never touches the others. The
|
|
118
|
+
concrete subdomain is baked into the unit, so the URL stays stable across reboots.
|
|
142
119
|
|
|
143
120
|
---
|
|
144
121
|
|
|
145
|
-
## 🧭 Two states: up &
|
|
122
|
+
## 🧭 Two states: up & delete
|
|
146
123
|
|
|
147
|
-
There are only two states. **`up`** brings
|
|
124
|
+
There are only two states. **`up`** brings subdomains online (creating the tunnel
|
|
125
|
+
+ DNS). **`delete`** — or pressing <kbd>Ctrl-C</kbd> in a foreground `up` —
|
|
126
|
+
**releases** them: it stops the connector and deletes the tunnel + DNS on
|
|
127
|
+
Cloudflare (and any `--service` unit). Running `up` again recreates cleanly (any
|
|
128
|
+
leftover tunnel record for that name is cleaned up first, so you never hit conflicts).
|
|
148
129
|
|
|
149
|
-
Add **`--detach`** to keep
|
|
130
|
+
Add **`--detach`** to keep connectors running in the **background** after the CLI
|
|
131
|
+
exits. Release them later with `cloudtunnel delete <target>` (or `--all`) and tail
|
|
132
|
+
their output with `cloudtunnel logs <target> -f`.
|
|
150
133
|
|
|
151
134
|
---
|
|
152
135
|
|
|
@@ -171,7 +154,25 @@ Provide it via (highest precedence first): `CLOUDFLARE_API_TOKEN` env → `cloud
|
|
|
171
154
|
|
|
172
155
|
- **Node.js ≥ 20**
|
|
173
156
|
- **`cloudflared`** on your `PATH` — install via `brew install cloudflared`, your package manager, or the [releases page](https://github.com/cloudflare/cloudflared/releases).
|
|
174
|
-
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 🧳 Upgrading from 0.3.x (profiles removed)
|
|
161
|
+
|
|
162
|
+
`save`, `run`, `profiles`, `zones`, and the `service …` sub-commands are gone —
|
|
163
|
+
everything is now inline specs on `up`, and reads live in `ls`:
|
|
164
|
+
|
|
165
|
+
| Old | New |
|
|
166
|
+
| --- | --- |
|
|
167
|
+
| `run mb` | `cloudtunnel api:8080 web:5173` (pass the specs directly) |
|
|
168
|
+
| `service enable mb --protocol http2` | `cloudtunnel <spec…> --service --protocol http2` |
|
|
169
|
+
| `service disable mb` / `profiles --rm mb` | `cloudtunnel delete <target>` |
|
|
170
|
+
| `service status` / `profiles` | `cloudtunnel ls` (SERVICE column) |
|
|
171
|
+
| `zones` | `cloudtunnel login --status` (also a ZONE in each `ls` URL) |
|
|
172
|
+
| `down <t>` / `rm <t>` | `cloudtunnel delete <t>` |
|
|
173
|
+
|
|
174
|
+
Profiles that were registered as boot services are **migrated automatically** to
|
|
175
|
+
the new per-subdomain units the first time you run cloudtunnel in a terminal.
|
|
175
176
|
|
|
176
177
|
---
|
|
177
178
|
|
|
@@ -179,10 +180,10 @@ Provide it via (highest precedence first): `CLOUDFLARE_API_TOKEN` env → `cloud
|
|
|
179
180
|
|
|
180
181
|
| Symptom | Cause & fix |
|
|
181
182
|
| --- | --- |
|
|
182
|
-
| **HTTP 1016** / subdomain won't load | The connector isn't running (`STATE = down` in `ls`). Bring it back up: `cloudtunnel <
|
|
183
|
-
| **`
|
|
183
|
+
| **HTTP 1016** / subdomain won't load | The connector isn't running (`STATE = down` in `ls`). Bring it back up: `cloudtunnel <spec>`. |
|
|
184
|
+
| **`delete` says "active connections"** | Handled automatically — cloudtunnel cleans up the connections and retries the delete. |
|
|
184
185
|
| **"grey-clouded" error** | The zone couldn't proxy the record; cfargotunnel routing needs an orange-cloud (proxied) CNAME. |
|
|
185
|
-
| **A DNS record already occupies the name** | Pick another
|
|
186
|
+
| **A DNS record already occupies the name** | Pick another subdomain/domain, or pass `-f/--force` to replace a non-tunnel record. |
|
|
186
187
|
|
|
187
188
|
---
|
|
188
189
|
|