zuplo 7.0.2 → 7.1.1

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.
@@ -0,0 +1,165 @@
1
+ ---
2
+ title: Connect to Tunnel Services
3
+ sidebar_label: Connect to Services
4
+ ---
5
+
6
+ <EnterpriseFeature name="Secure tunneling" />
7
+
8
+ Once a tunnel exposes a service, your gateway calls it like any other backend —
9
+ with a URL. Tunnel services use the `service://` scheme instead of a hostname,
10
+ so a service named `payments-api` is reachable at `service://payments-api`.
11
+
12
+ This page covers the service configuration file, and the three places you use a
13
+ `service://` URL: handler code, route configuration, and environment variables.
14
+ To create a tunnel first, see [Set up a tunnel](./tunnel-setup.mdx).
15
+
16
+ ## Service configuration reference
17
+
18
+ You define services in a JSON file and upload it with
19
+ [`zuplo tunnel services update`](../cli/tunnel-services-update.mdx). Each upload
20
+ replaces the tunnel's entire configuration.
21
+
22
+ ```json title="tunnel-config.json"
23
+ {
24
+ "version": 1,
25
+ "services": [
26
+ {
27
+ "name": "payments-api-prod",
28
+ "endpoint": "http://payments.internal:8080",
29
+ "configurations": [
30
+ {
31
+ "project": "my-project",
32
+ "accessibleBy": ["production"]
33
+ },
34
+ {
35
+ "project": "my-other-project",
36
+ "accessibleBy": ["production"]
37
+ }
38
+ ]
39
+ },
40
+ {
41
+ "name": "payments-api-staging",
42
+ "endpoint": "http://payments-staging.internal:8080",
43
+ "configurations": [
44
+ {
45
+ "project": "my-project",
46
+ "accessibleBy": ["preview", "working-copy"]
47
+ }
48
+ ]
49
+ }
50
+ ]
51
+ }
52
+ ```
53
+
54
+ | Property | Type | Description |
55
+ | ------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------- |
56
+ | `version` | number | Configuration format version. Use `1`. |
57
+ | `services` | array | The services this tunnel exposes. |
58
+ | `services[].name` | string | The service name your gateway calls, used as `service://<name>`. |
59
+ | `services[].endpoint` | string | The internal URL the tunnel forwards to, resolvable from the tunnel host. For example, `http://payments.internal:8080`. |
60
+ | `services[].configurations` | array | Which projects and environments can call this service. A project that isn't listed can't reach the service. |
61
+ | `configurations[].project` | string | The name of the Zuplo project. |
62
+ | `configurations[].accessibleBy` | string[] | The environments allowed to call the service. Valid values are `production`, `preview`, and `working-copy`. |
63
+
64
+ Use `accessibleBy` to keep environments apart. A service listed only under
65
+ `production` can't be reached from a preview build, even by a developer on your
66
+ own team.
67
+
68
+ To see the configuration a tunnel currently has, run
69
+ [`zuplo tunnel services describe`](../cli/tunnel-services-describe.mdx).
70
+
71
+ ## Call a service from code
72
+
73
+ Pass the `service://` URL to `fetch` exactly as you would a public URL:
74
+
75
+ ```ts
76
+ import { ZuploContext, ZuploRequest } from "@zuplo/runtime";
77
+
78
+ export default async function (request: ZuploRequest, context: ZuploContext) {
79
+ const response = await fetch("service://payments-api-prod/v1/charges");
80
+
81
+ if (!response.ok) {
82
+ context.log.error(`Payments API returned ${response.status}`);
83
+ return new Response("Upstream error", { status: 502 });
84
+ }
85
+
86
+ return response;
87
+ }
88
+ ```
89
+
90
+ Paths, query strings, headers, and request methods all work the way they do for
91
+ a normal `fetch`. The tunnel appends the path to the service's configured
92
+ `endpoint`.
93
+
94
+ ## Call a service from route configuration
95
+
96
+ Any route property that accepts a URL accepts a `service://` URL, including the
97
+ [URL Rewrite handler](../handlers/url-rewrite.mdx):
98
+
99
+ ```json title="config/routes.oas.json"
100
+ {
101
+ "paths": {
102
+ "/v1/charges": {
103
+ "get": {
104
+ "x-zuplo-route": {
105
+ "handler": {
106
+ "export": "urlRewriteHandler",
107
+ "module": "$import(@zuplo/runtime)",
108
+ "options": {
109
+ "rewritePattern": "service://payments-api-prod/v1/charges"
110
+ }
111
+ }
112
+ }
113
+ }
114
+ }
115
+ }
116
+ }
117
+ ```
118
+
119
+ You can also set the rewrite URL in the **Rewrite URL** field of the route
120
+ editor in the Zuplo Portal.
121
+
122
+ ## Switch services per environment
123
+
124
+ Most teams run a separate internal service for each environment. Rather than
125
+ changing code or route configuration per environment, store the service URL in
126
+ an [environment variable](./environment-variables.mdx) and set a different value
127
+ in each Zuplo environment.
128
+
129
+ In your production environment, point the variable at the production service:
130
+
131
+ ```text
132
+ TUNNEL_BASE_URL=service://payments-api-prod
133
+ ```
134
+
135
+ In preview and working-copy environments, point it at staging:
136
+
137
+ ```text
138
+ TUNNEL_BASE_URL=service://payments-api-staging
139
+ ```
140
+
141
+ Read the variable in handler code:
142
+
143
+ ```ts
144
+ import { ZuploContext, ZuploRequest, environment } from "@zuplo/runtime";
145
+
146
+ export default async function (request: ZuploRequest, context: ZuploContext) {
147
+ return fetch(`${environment.TUNNEL_BASE_URL}/v1/charges`);
148
+ }
149
+ ```
150
+
151
+ Environment variables work in route configuration too. The following URL Rewrite
152
+ handler combines the variable with a path parameter:
153
+
154
+ <Framed>
155
+
156
+ ![The Request Handler pane of the Zuplo route editor, with Handler set to URL Rewrite and Rewrite URL set to a value that combines the TUNNEL_BASE_URL environment variable with a path parameter](../../public/media/tunnel-setup/16b93099-511d-435b-af85-167fab5814b2.png)
157
+
158
+ </Framed>
159
+
160
+ ## Next steps
161
+
162
+ - [Advanced tunnel configuration](./tunnel-advanced.mdx) — the cloudflared
163
+ foundation, environment variables, and self-managed images.
164
+ - [Troubleshoot a tunnel](./tunnel-troubleshooting.mdx) — diagnose requests that
165
+ don't reach your backend.
@@ -1,227 +1,180 @@
1
1
  ---
2
- title: Tunnel Setup & Use
2
+ title: Set up a Tunnel
3
+ sidebar_label: Setup
3
4
  ---
4
5
 
5
6
  <EnterpriseFeature name="Secure tunneling" />
6
7
 
7
- :::caution{title="Platform Requirement"}
8
+ This guide takes you from nothing to a working tunnel: you create the tunnel in
9
+ Zuplo, run the tunnel container inside your network, tell Zuplo which internal
10
+ services to expose, and confirm the connection is up.
8
11
 
9
- The Zuplo tunnel service is officially supported on **Linux** only. The
10
- [`zuplo/tunnel` Docker image](https://hub.docker.com/r/zuplo/tunnel) is a Linux
11
- container, and any non-containerized deployment must target a Linux host. Cloud
12
- container platforms (AWS ECS, Azure Container Instances, GCP Cloud Run,
13
- Kubernetes) run Linux containers by default and require no extra configuration.
14
- If you are deploying on a virtual machine or bare metal, ensure the host runs a
15
- supported Linux distribution.
12
+ For background on what a tunnel does and how it fits your architecture, see
13
+ [Secure tunnel](./secure-tunnel.mdx).
16
14
 
17
- :::
15
+ ## Before you begin
18
16
 
19
- ## Setting up Tunnels
17
+ You need:
20
18
 
21
- A tunnel is a way to expose your _internal services_ to the Zuplo gateway
22
- without exposing it to the public internet. Your Zuplo Gateway accesses those
23
- services through the `service://` protocol.
19
+ - The [Zuplo CLI](../cli/overview.mdx) installed and authenticated.
20
+ - A Linux host or container runtime inside the network that holds your backend
21
+ API. The host needs outbound internet access and internal DNS resolution to
22
+ your backend.
23
+ - The internal endpoint of each service you want to expose, such as
24
+ `http://payments.internal:8080`.
24
25
 
25
26
  ## Create the tunnel
26
27
 
27
- Before you deploy the tunnel container, create the tunnel in Zuplo using the
28
- CLI. This gives you the tunnel record in your account and the token that you
29
- will later provide to the container as `TUNNEL_TOKEN`.
28
+ <Stepper>
30
29
 
31
- ```bash
32
- zuplo tunnel create --tunnel-name <your-tunnel-name>
33
- zuplo tunnel list
34
- zuplo tunnel describe --tunnel-id <your-tunnel-id>
35
- ```
36
-
37
- Use these commands as follows:
38
-
39
- 1. Run `zuplo tunnel create` to create the tunnel.
40
- 1. Run `zuplo tunnel list` to see the tunnels in your account and identify the
41
- tunnel ID if you need it.
42
- 1. Run `zuplo tunnel describe` with the tunnel ID to retrieve the tunnel details
43
- and copy the token value you will use for `TUNNEL_TOKEN`.
44
-
45
- The easiest way to deploy your tunnel is using a Docker container. The three
46
- basic requirements for deploying a secure tunnel with Docker are:
47
-
48
- 1. A tunnel secret that's provided to the Docker container as an environment
49
- variable named `TUNNEL_TOKEN` (the secret is provided by the Zuplo CLI when
50
- you create the tunnel. See [creating a tunnel](../cli/tunnel-create.mdx))
51
- 1. The ability for the tunnel service to make an outbound connection to the
52
- public internet to establish the secure tunnel.
53
- 1. The ability for the tunnel service to make a request to your internal API by
54
- a DNS address. (for example `https://my-service.local/api`).
55
-
56
- The tunnel can run anywhere you can deploy a Docker container. Where you deploy
57
- depends on your specific setup. To run the Docker container on your own
58
- infrastructure, refer to instructions from your cloud provider or contact
59
- [Zuplo support](mailto:support@zuplo.com) for assistance.
60
-
61
- Below are a few option for deploying the tunnel.
62
-
63
- - [Deploying Docker containers on Azure](https://docs.microsoft.com/en-us/learn/modules/run-docker-with-azure-container-instances/)
64
- - [Deploying Docker containers on AWS ECS](https://docs.aws.amazon.com/AmazonECS/latest/userguide/getting-started.html)
65
- - [Deploying container images to GCP](https://cloud.google.com/compute/docs/containers/deploying-containers)
66
-
67
- The docker container is `zuplo/tunnel` and is available on
68
- [Docker Hub](https://hub.docker.com/r/zuplo/tunnel).
69
-
70
- Your running container needs a single environment variable named `TUNNEL_TOKEN`.
71
- You should store the value as a secret using the recommended means of secret
72
- storage and environment variable injection for your platform.
73
-
74
- ## Configuring services
75
-
76
- Once you have created a tunnel, you can
77
- [configure which services](../cli/tunnel-services-update.mdx) it should expose
78
- using a configuration file. Below is a sample configuration file. The properties
79
- in the `services` objects are explained below.
80
-
81
- - `name` - This is the name of the service that you will use from your Zuplo
82
- project
83
- - `endpoint` - This is the local endpoint of your service that you tunnel can
84
- connect to
85
- - `configurations` - This object specifies which projects and which environments
86
- can access this service.
87
- - `project` - The name of the Zuplo project
88
- - `accessibleBy` - The environments which can use the tunnel. Valid values are
89
- `production`, `preview`, and `working-copy`.
90
-
91
- ```json title="tunnel-config.json"
92
- {
93
- "version": 1,
94
- "services": [
95
- {
96
- "name": "my-awesome-service-prod",
97
- "endpoint": "http://localhost:8000",
98
- "configurations": [
99
- {
100
- "project": "my-project",
101
- "accessibleBy": ["production"]
102
- },
103
- {
104
- "project": "my-other-project",
105
- "accessibleBy": ["production"]
106
- }
107
- ]
108
- },
109
- {
110
- "name": "my-awesome-service-staging",
111
- "endpoint": "http://localhost:9000",
112
- "configurations": [
113
- {
114
- "project": "my-project",
115
- "accessibleBy": ["preview", "working-copy"]
116
- },
117
- {
118
- "project": "my-other-project",
119
- "accessibleBy": ["preview", "working-copy"]
120
- }
121
- ]
122
- }
123
- ]
124
- }
125
- ```
126
-
127
- ```bash
128
- zuplo tunnel services update \
129
- --configuration-file <path-to-your-configuration-file> \
130
- --tunnel-id <your-tunnel-id>
131
- ```
132
-
133
- ## Using Services Exposed through Tunnels in Code
134
-
135
- Once set up, the services in the tunnels can be treated like any API host that
136
- you call from your Zuplo gateway. Each service exposed through tunnels is called
137
- with the URL schema `service://`, so if your service is named
138
- `my-awesome-service` you will call it using the URL
139
- `service://my-awesome-service`.
140
-
141
- This URL can be used in code as shown below.
142
-
143
- ```ts
144
- import { ZuploContext, ZuploRequest } from "@zuplo/runtime";
30
+ 1. Create the tunnel in your Zuplo account:
145
31
 
146
- export default async function (request: ZuploRequest, context: ZuploContext) {
147
- const response = await fetch("service://my-awesome-service/hello-world");
148
- if (response.status > 399) {
149
- return "It didn't work. :(";
150
- } else {
151
- return response;
152
- }
153
- }
154
- ```
155
-
156
- It's common to have multiple services for each of your internal environments.
157
- Each service can be restricted so that it's only accessible by specific Zuplo
158
- environments. For example, you might have two services one for production and
159
- one for staging.
160
-
161
- - `service://my-awesome-service-prod` (Production)
162
- - `service://my-awesome-service-staging` (Staging)
32
+ ```bash
33
+ zuplo tunnel create --tunnel-name my-tunnel
34
+ ```
163
35
 
164
- ## Using Services Exposed through Tunnels in Configuration
36
+ The command returns the tunnel ID, which starts with `tnl_`. Record it — the
37
+ remaining commands need it. To look it up later, run `zuplo tunnel list`.
165
38
 
166
- Services can also be used in routes.oas.json file such as with the URL Rewrite
167
- handler. To call a tunnel service simply use it as part of the rewrite URL as
168
- shown in the image below.
39
+ 1. Retrieve the tunnel's connection token:
169
40
 
170
- ![Zuplo route handling](../../public/media/tunnel-setup/0c91be91-a591-4cef-ac29-d266e8a3181e.png)
41
+ ```bash
42
+ zuplo tunnel describe --tunnel-id tnl_TRMZwunq2PLNQDwhu6A04Bmx
43
+ ```
171
44
 
172
- ## Service Environment Variables
45
+ Copy the token value from the output. The tunnel container authenticates with
46
+ this token.
173
47
 
174
- When using these services in your code or configuration, it's often useful to
175
- store the values as an environment variable. This way you can change which
176
- environment calls which tunnel without changing code or configuration.
48
+ :::caution
177
49
 
178
- For the production environment you would set the `BASE_SERVICE_URL` to the
179
- production service name. See
180
- [this document](../articles/environment-variables.mdx) for more about
181
- [Environment Variables](../articles/environment-variables.mdx)
50
+ The token grants the ability to connect to your tunnel. Store it in your
51
+ platform's secret manager rather than in source control or a plain
52
+ environment file. If a token is exposed, see
53
+ [Rotate the tunnel token](./tunnel-advanced.mdx#rotate-the-tunnel-token).
182
54
 
183
- ```text
184
- BASE_SERVICE_URL=service://my-awesome-service-prod
185
- ```
55
+ :::
186
56
 
187
- And for staging, you would use the staging service name.
57
+ </Stepper>
188
58
 
189
- ```text
190
- BASE_SERVICE_URL=service://my-awesome-service-staging
191
- ```
59
+ ## Run the tunnel
192
60
 
193
- In your handler code or other configuration, the service can be accessed using
194
- the environment variable.
61
+ Deploy the [`zuplo/tunnel`](https://hub.docker.com/r/zuplo/tunnel) container
62
+ anywhere inside your network. It takes a single environment variable,
63
+ `TUNNEL_TOKEN`, set to the token from the previous step.
195
64
 
196
- ```ts
197
- import { ZuploContext, ZuploRequest, environment } from "@zuplo/runtime";
65
+ To confirm the token works before you wire up your deployment platform, run the
66
+ container locally on a host inside your network:
198
67
 
199
- export default async function (request: ZuploRequest, context: ZuploContext) {
200
- const response = await fetch(`${environment.BASE_SERVICE_URL}/hello-world`);
201
- if (response.status > 399) {
202
- return "It didn't work. :(";
203
- } else {
204
- return response;
205
- }
206
- }
68
+ ```bash
69
+ docker run -d --name zuplo-tunnel \
70
+ -e TUNNEL_TOKEN=<YOUR_TUNNEL_TOKEN> \
71
+ zuplo/tunnel:latest
207
72
  ```
208
73
 
209
- Environment variables can also be used in configuration, such as the URL Rewrite
210
- handler as shown below.
211
-
212
- ![Zuplo environment variables](../../public/media/tunnel-setup/16b93099-511d-435b-af85-167fab5814b2.png)
213
-
214
- ## Tunnel Upgrades
215
-
216
- Zuplo publishes a new release of the tunnel Docker image about once per month or
217
- whenever Cloudflare ships a release to their underlying tunnel tools. The most
218
- recent version of the Docker Image is always tagged with the `latest` tag. We
219
- recommend periodically checking and upgrading the tunnel to the latest release
220
- to ensure you have the latest security and performance updates.
221
-
222
- We recommend testing each release of the tunnel in a staging environment before
223
- rolling out to production.
224
-
225
- ## Troubleshooting
74
+ Replace `<YOUR_TUNNEL_TOKEN>` with the token you copied. For production, pin a
75
+ specific image tag instead of `latest` and inject the token from your secret
76
+ manager. For details, see
77
+ [Advanced tunnel configuration](./tunnel-advanced.mdx).
226
78
 
227
- For troubleshooting see [this document](./tunnel-troubleshooting.mdx).
79
+ Run at least two instances so the tunnel survives the loss of a single host or
80
+ pod. Instances that share the same token act as replicas of one tunnel.
81
+
82
+ Where you deploy depends on your infrastructure. The following guides cover the
83
+ common platforms:
84
+
85
+ - [Deploy containers on AWS ECS](https://docs.aws.amazon.com/AmazonECS/latest/userguide/getting-started.html)
86
+ - [Deploy containers on Azure Container Instances](https://docs.microsoft.com/en-us/learn/modules/run-docker-with-azure-container-instances/)
87
+ - [Deploy container images on GCP](https://cloud.google.com/compute/docs/containers/deploying-containers)
88
+
89
+ For help with a platform that isn't listed, contact
90
+ [Zuplo support](mailto:support@zuplo.com).
91
+
92
+ ## Expose your internal services
93
+
94
+ A running tunnel doesn't expose anything by itself. You define the services it
95
+ forwards to in a configuration file, then upload that file to Zuplo.
96
+
97
+ <Stepper>
98
+
99
+ 1. Create a configuration file that names each service, its internal endpoint,
100
+ and the Zuplo projects and environments allowed to call it:
101
+
102
+ ```json title="tunnel-config.json"
103
+ {
104
+ "version": 1,
105
+ "services": [
106
+ {
107
+ "name": "payments-api-prod",
108
+ "endpoint": "http://payments.internal:8080",
109
+ "configurations": [
110
+ {
111
+ "project": "my-project",
112
+ "accessibleBy": ["production"]
113
+ }
114
+ ]
115
+ },
116
+ {
117
+ "name": "payments-api-staging",
118
+ "endpoint": "http://payments-staging.internal:8080",
119
+ "configurations": [
120
+ {
121
+ "project": "my-project",
122
+ "accessibleBy": ["preview", "working-copy"]
123
+ }
124
+ ]
125
+ }
126
+ ]
127
+ }
128
+ ```
129
+
130
+ For the meaning of each property, see
131
+ [Service configuration reference](./tunnel-services.mdx#service-configuration-reference).
132
+
133
+ 1. Upload the configuration to your tunnel:
134
+
135
+ ```bash
136
+ zuplo tunnel services update \
137
+ --tunnel-id tnl_TRMZwunq2PLNQDwhu6A04Bmx \
138
+ --configuration-file ./tunnel-config.json
139
+ ```
140
+
141
+ The upload replaces the tunnel's entire service configuration, so include
142
+ every service you want available each time you run it.
143
+
144
+ </Stepper>
145
+
146
+ ## Verify the tunnel
147
+
148
+ <Stepper>
149
+
150
+ 1. Check that the tunnel reports itself as connected:
151
+
152
+ ```bash
153
+ zuplo tunnel describe --tunnel-id tnl_TRMZwunq2PLNQDwhu6A04Bmx
154
+ ```
155
+
156
+ Look at the `status` field. A new tunnel takes a few seconds to register the
157
+ first time it connects. If the status stays down, see
158
+ [Troubleshoot a tunnel](./tunnel-troubleshooting.mdx).
159
+
160
+ 1. Confirm Zuplo has the services you uploaded:
161
+
162
+ ```bash
163
+ zuplo tunnel services describe --tunnel-id tnl_TRMZwunq2PLNQDwhu6A04Bmx
164
+ ```
165
+
166
+ 1. Call a service from your gateway. Add a route to your project that rewrites
167
+ to one of your service URLs, such as `service://payments-api-prod`, and send
168
+ a request to it. For the full set of ways to call a service, see
169
+ [Connect to tunnel services](./tunnel-services.mdx).
170
+
171
+ </Stepper>
172
+
173
+ ## Next steps
174
+
175
+ - [Connect to tunnel services](./tunnel-services.mdx) — call `service://` URLs
176
+ from handler code, route configuration, and environment variables.
177
+ - [Advanced tunnel configuration](./tunnel-advanced.mdx) — pin image versions,
178
+ tune the connection, rotate tokens, and build your own image.
179
+ - [Troubleshoot a tunnel](./tunnel-troubleshooting.mdx) — work through a tunnel
180
+ that's down or not passing traffic.