# A permanent address with Cloudflare Tunnel

At the end, the runner has an address like `https://runner.yourcompany.com` that your team can open from anywhere, and it no longer changes when the box restarts.

## At a glance

**Time:** 15 minutes, plus a few minutes for a new domain to settle.

**You need:**

- The runner from [Any Linux box](any-box.md)
- A free Cloudflare account
- A domain you own, added to that account (or one bought in Cloudflare under **Domain Registration → Register Domains**, which adds it for you)

## Steps

### Make the tunnel

1. **In the Cloudflare dashboard, open Zero Trust** from the left menu. The first time, choose a team name and the **Free** plan. Cloudflare may ask for a card even for the free plan.

2. **Go to Networks → Tunnels and press Create a tunnel.**

3. **Choose Cloudflared, name it `loopgate-runner` and save.**

4. **Choose Docker and copy only the token.** Cloudflare shows a command that ends with `--token` and a long string starting `eyJ`. Copy that string. Do not run the command; Loopgate's file runs the connector for you.

### Start the connector on your box

5. **Go to the `loopgate` folder and download the tunnel's settings file.**

   ```sh
   cd ~/loopgate && curl -fsSLO https://loopgate.dev/runner/tunnel.env.example && cp tunnel.env.example tunnel.env
   ```

6. **Paste the token after `TUNNEL_TOKEN=`**, then save and leave (Ctrl+O, Enter, Ctrl+X). The token connects anything to your tunnel. Treat it like a password.

   ```sh
   nano tunnel.env
   ```

7. **Start the tunnel, now and on every start from now on.**

   ```sh
   echo "COMPOSE_PROFILES=tunnel" >> .env && docker compose up -d
   ```

   You should see: `Container loopgate-runner-tunnel-1  Started`, and in Cloudflare the tunnel's status turns **Healthy** within a minute.

### Point a name at the runner

8. **In Cloudflare, press Next** (or open the tunnel's **Public Hostname** tab, called **Published application routes** in some accounts) **and add one**, leaving the other settings as they are:
   - **Subdomain:** `runner`
   - **Domain:** your domain
   - **Service type:** `HTTP`
   - **URL:** `runner:4311`

9. **Give the runner its new address**, with no slash at the end.

   ```sh
   echo "LOOPGATE_RUNNER_URL=https://runner.yourcompany.com" >> runner.env
   ```

10. **Restart the runner.**

    ```sh
    docker compose up -d runner
    ```

    You should see: the portal's Devices row shows the new address, no longer marked `temporary`.

11. **Check the runner's own line.**

    ```sh
    docker compose logs runner
    ```

    You should see: `Runner ready at https://runner.yourcompany.com`.

12. **In the Loopgate portal, open Devices and press Open** on the runner's row.

    You should see: the workbench, on your new address. Settings → General names it `permanent`.

## Good to know

- Your box dials out to Cloudflare and Cloudflare sends your team down that line, so the box opens no door to the internet.
- The runner's own door turns away anyone who is not a current member of your org, which is why a public address is safe.
- A browser stays signed in there for thirty days from its last use. A teammate on a link with no sign-in gets **Sign in**, which goes through the portal.
- Links Slack posts from now on survive a restart.
- [By hand](by-hand.md) has every line of `runner.env` and `tunnel.env`.

## If something is off

- **"Not a current member of this org."** An owner or admin adds the person in the portal. They can get in within about two minutes, and someone removed is out as fast.
- **The tunnel is not Healthy.** Check the token in `tunnel.env`, then run `docker compose up -d`.

## Next

- [Connect Slack](slack-connect.md)
- [Updates and backups](care.md)
