docs: add GitHub Actions Full tunnel documentation and workflows (#783)

* docs: add GitHub Actions tunnel general documentation README.md

* docs: add cloudflared quick tunnel guide

* Add: add cloudflared quick tunnel workflow

* docs: add ngrok tunnel guide

* Add: add ngrok tunnel workflow

* fix: Update cloudflared-quick.md to add link to related yml file

* fix: Update ngrok.md to add related file link

* docs: add cloudflared named tunnel guide

* Add: add cloudflared named workflow
This commit is contained in:
Euvel
2026-05-07 01:13:16 +03:30
committed by GitHub
parent 0e678630a8
commit 3e8623571f
7 changed files with 657 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
# GitHub Actions Full Tunnel
A temporary, repeatable Full tunnel mode for users who cannot or prefer not to
purchase a VPS. Uses GitHub Actions free hosted runners to run the official
`mhrv-tunnel-node` container for 6-hour sessions at no cost.
## Who This Is For
- Users who cannot access international payment methods to purchase a VPS
- Users who need Full tunnel mode occasionally — CAPTCHA-protected sites,
streaming, or services that require a real browser
- Users who want to test Full tunnel mode before committing to a permanent VPS
- Users in networks where the standard `apps_script` mode is sufficient for
daily browsing, but Full mode is needed for specific use cases
## How It Works
1. A GitHub Actions workflow starts the official `mhrv-tunnel-node` Docker
container on a free hosted runner
2. A tunneling service (cloudflared or ngrok) exposes the container to the
internet on a public URL
3. `CodeFull.gs` is configured to forward tunnel traffic to this URL
4. The runner stays alive for 6 hours, then shuts down automatically
5. The workflow can be re-triggered at any time for another 6-hour session
## Available Methods
Three methods are provided, ordered by setup complexity. Each is documented in
its own guide with step-by-step instructions.
| # | Method | Guide | Account Required | URL Behavior |
|---|---|---|---|---|
| 1 | cloudflared Quick Tunnel | [cloudflared-quick.md][quick] | None | New URL each session |
| 2 | ngrok Tunnel | [ngrok.md][ngrok] | ngrok (free) | New URL each session |
| 3 | cloudflared Named Tunnel | [cloudflared-named.md][named] | Cloudflare + domain | **Permanent URL** |
**New to Full tunnel mode?** Start with [Method 1][quick] — no accounts
needed beyond GitHub and Google.
**Need a stable URL that survives restarts?** Use [Method 3][named] — requires
a one-time Cloudflare CLI setup but the URL never changes.
## Shared Requirements
All methods share these requirements:
| Requirement | Details |
|---|---|
| GitHub account | Free. Repository must be private to keep secrets secure. |
| Google account | Free. Used to deploy `CodeFull.gs`. |
| `CodeFull.gs` deployed | See the main project documentation for deployment instructions. |
| `TUNNEL_AUTH_KEY` secret | A strong password shared between the workflow and `CodeFull.gs`. |
## After Starting the Tunnel
1. Run the workflow from your repository's **Actions** tab
2. Copy the `TUNNEL_SERVER_URL` from the workflow log output
3. Update the `TUNNEL_SERVER_URL` constant in `CodeFull.gs`
4. Deploy `CodeFull.gs` (Deploy → New Deployment → Web App)
5. Configure your `mhrv-rs` client to use the new deployment in Full mode
For methods where the URL changes each session (1 and 2), steps 24 must be
repeated each time the workflow runs. Method 3 uses a permanent URL — configure
`CodeFull.gs` once and only re-trigger the workflow when needed.
## Limitations
- **6-hour maximum per session.** GitHub Actions enforces a 360-minute timeout
on hosted runners. Re-trigger the workflow for another session.
- **URL changes on restart (Methods 1 & 2).** The tunnel URL is assigned at
runtime. `CodeFull.gs` must be updated and redeployed each time.
- **Shared IP ranges.** GitHub-hosted runners share IP ranges with other users.
Some websites may already have these IPs flagged.(sometimes need re-run)
- **GitHub Actions terms.** This workflow is intended for occasional personal
use. Review [GitHub's Terms for Additional Products and Features][gh-terms]
and ensure your usage complies.
## Compliance Note
This workflow uses GitHub-hosted runners for a purpose adjacent to, but not
directly part of, software development on the repository. Usage is low-burden
(a single Docker container, moderate outbound traffic for one user) and aligns
with GitHub's acceptable use guidelines for development and testing
infrastructure. Continuous, high-bandwidth, or commercial use is not
recommended. For persistent Full mode operation, a dedicated VPS remains the
recommended solution.
[quick]: cloudflared-quick.md
[ngrok]: ngrok.md
[named]: cloudflared-named.md
[gh-terms]: https://docs.github.com/en/site-policy/github-terms/github-terms-for-additional-products-and-features#actions
@@ -0,0 +1,187 @@
# cloudflared Named Tunnel
Run a Full tunnel with a **permanent, unchanging URL** using a Cloudflare
account and a custom domain. The tunnel URL never changes between restarts —
configure `CodeFull.gs` once and only re-trigger the workflow when needed.
## Prerequisites
- A GitHub account (free)
- A Cloudflare account with a domain
- `cloudflared` installed on your local machine for one-time setup
- `CodeFull.gs` deployed as a Google Apps Script Web App
## One-Time Local Setup
These steps are performed **once** on your local machine. They create a named
tunnel on Cloudflare and route your domain to it.
### Step 1: Install cloudflared
**Linux (Debian/Ubuntu):**
```bash
curl -L --output cloudflared.deb \
https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
```
**macOS:**
```bash
brew install cloudflared
```
**Windows:**
Download the installer from the [cloudflared releases page](https://github.com/cloudflare/cloudflared/releases).
### Step 2: Authenticate with Cloudflare
```bash
cloudflared tunnel login
```
This opens a browser window. Select your domain and authorize.
### Step 3: Create a Named Tunnel
```bash
cloudflared tunnel create my-tunnel
```
This outputs a tunnel ID (a UUID) and creates a credentials file at:
```
~/.cloudflared/<TUNNEL_ID>.json
```
Copy the tunnel ID — you will need it later.
### Step 4: Route Your Domain
```bash
cloudflared tunnel route dns my-tunnel tunnel.yourdomain.com
```
Replace `tunnel.yourdomain.com` with the actual subdomain you want to use.
This creates a DNS record on Cloudflare pointing to your tunnel.
### Step 5: Get the Credentials File
```bash
cat ~/.cloudflared/<TUNNEL_ID>.json
```
Copy the entire JSON output. You will use this as the
`CLOUDFLARE_TUNNEL_CREDENTIALS` secret in GitHub Actions.
## GitHub Setup
### Step 6: Create the Repository
If you already have a repository from another method, you can reuse it.
Otherwise:
1. Go to [github.com](https://github.com) and sign in
2. Click the **+** icon in the top-right corner, then **New repository**
3. Enter a repository name (e.g., `my-tunnel`)
4. Select **Private** (recommended — keeps your secrets secure)
5. Click **Create repository**
### Step 7: Add the Secrets
1. In your repository, go to **Settings > Secrets and variables > Actions**
2. Click **New repository secret** and add each of the following:
| Name | Value |
|---|---|
| `TUNNEL_AUTH_KEY` | A strong password. You will also set this in `CodeFull.gs`. |
| `CLOUDFLARE_TUNNEL_ID` | The tunnel ID from Step 3. |
| `CLOUDFLARE_TUNNEL_HOSTNAME` | The subdomain you configured in Step 4 (e.g., `tunnel.yourdomain.com`). |
| `CLOUDFLARE_TUNNEL_CREDENTIALS` | The entire JSON contents of the credentials file from Step 5. |
3. Click **Add secret** for each
### Step 8: Add the Workflow
1. In your repository, go to the **Actions** tab
2. Click **New workflow**
3. Click the **set up a workflow yourself** link
4. Delete the default content and paste the contents of `cloudflared-named.yml` [[here]]
5. Click **Commit changes...**, add a commit message, then click **Commit changes**
The workflow file will be saved to `.github/workflows/cloudflared-named.yml`.
### Step 9: Run the Workflow
1. Go to the **Actions** tab
2. Select **Full Tunnel (cloudflared Named)** from the left sidebar
3. Click **Run workflow > Run workflow**
The workflow will start immediately.
### Step 10: Configure CodeFull.gs
Open `CodeFull.gs` in the Google Apps Script editor and update these constants:
```javascript
const TUNNEL_SERVER_URL = "https://tunnel.yourdomain.com";
const TUNNEL_AUTH_KEY = "the-secret-you-set-in-step-7";
```
Deploy: **Deploy > New Deployment > Web App**.
Copy the new Deployment ID and update your `mhrv-rs` config.
**This step is performed only once.** The tunnel URL never changes between
restarts.
### Step 11: Verify
Use `mhrv-rs test` or visit `https://ipleak.net` through your proxy.
You should see a Cloudflare IP address.
## How It Works
1. GitHub Actions starts a Docker container running `mhrv-tunnel-node` on port
`8080`
2. `cloudflared` connects to Cloudflare using the named tunnel credentials
3. Cloudflare routes traffic from your custom domain to the runner through a
secure, persistent tunnel
4. `CodeFull.gs` forwards tunnel operations to your custom domain over HTTPS
5. The runner stays alive for 6 hours, then shuts down automatically
6. On restart, the same domain routes to the new runner — no configuration
changes needed
## Restarting the Tunnel
The tunnel shuts down after 6 hours. To start a new session:
1. Go to the **Actions** tab
2. Select **Full Tunnel (cloudflared Named)**
3. Click **Run workflow > Run workflow**
That is all — the URL is permanent so `CodeFull.gs` does not need to be updated.
For automatic restarts every 6 hours, add a `schedule` trigger to the workflow:
```yaml
on:
workflow_dispatch:
schedule:
- cron: '0 */6 * * *'
```
## Limitations
- Requires a one-time local setup with `cloudflared` CLI
- Requires a Cloudflare account with a domain
- 6-hour maximum per session (GitHub Actions limit)
## Troubleshooting
| Problem | Solution |
|---|---|
| `cloudflared tunnel login` fails | Ensure your browser can reach `dash.cloudflare.com`. You may need to use a proxy or alternative network for this step. |
| `cloudflared tunnel create` fails | Verify you are authenticated. Run `cloudflared tunnel login` again. |
| Workflow fails at Docker step | GitHub Actions may be pulling the image for the first time. Wait 2-3 minutes and retry. |
| `cloudflared` fails to connect | Verify all four secrets are set correctly. Check that `CLOUDFLARE_TUNNEL_CREDENTIALS` contains valid JSON. |
| `CodeFull.gs` returns 502 or timeout | Verify the workflow is still running. Check that `TUNNEL_AUTH_KEY` matches in both the secret and `CodeFull.gs`. Ensure the DNS record was created in Step 4. |
[here]: cloudflared-named.yml
@@ -0,0 +1,52 @@
name: Full Tunnel (cloudflared Named)
on:
workflow_dispatch:
permissions:
contents: read
jobs:
tunnel:
runs-on: ubuntu-latest
timeout-minutes: 360
steps:
- name: Start mhrv-tunnel-node
run: |
docker run -d --name mhrv-tunnel \
-p 8080:8080 \
-e TUNNEL_AUTH_KEY="${{ secrets.TUNNEL_AUTH_KEY }}" \
ghcr.io/therealaleph/mhrv-tunnel-node:latest
sleep 5
curl -s http://localhost:8080/health || sleep 5
- name: Install cloudflared
run: |
curl -L --output cloudflared.deb \
https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
- name: Configure tunnel
run: |
mkdir -p ~/.cloudflared
echo "${{ secrets.CLOUDFLARE_TUNNEL_CREDENTIALS }}" > ~/.cloudflared/credentials.json
cat > ~/.cloudflared/config.yml << EOF
tunnel: ${{ secrets.CLOUDFLARE_TUNNEL_ID }}
credentials-file: /home/runner/.cloudflared/credentials.json
ingress:
- hostname: ${{ secrets.CLOUDFLARE_TUNNEL_HOSTNAME }}
service: http://localhost:8080
- service: http_status:404
EOF
- name: Run tunnel
run: |
cloudflared tunnel --config ~/.cloudflared/config.yml run &
echo "TUNNEL_SERVER_URL = https://${{ secrets.CLOUDFLARE_TUNNEL_HOSTNAME }}"
sleep 21000
- name: Cleanup
if: always()
run: |
docker stop mhrv-tunnel || true
pkill cloudflared || true
@@ -0,0 +1,112 @@
# cloudflared Quick Tunnel
Run a Full tunnel for 6 hours with **zero account setup** beyond GitHub.
Cloudflare's free Quick Tunnel service provides a temporary public URL — no
Cloudflare account, no API token, no configuration files required.
## Prerequisites
- A GitHub account (free)
- `CodeFull.gs` deployed as a Google Apps Script Web App
- No Cloudflare account or ngrok account needed
## Setup
### Step 1: Create the Repository
1. Go to [github.com](https://github.com) and sign in
2. Click the **+** icon in the top-right corner, then **New repository**
3. Enter a repository name (e.g., `my-tunnel`)
4. Select **Private** (recommended — keeps your secrets secure)
5. Click **Create repository**
### Step 2: Add the Secret
1. In your new repository, go to **Settings > Secrets and variables > Actions**
2. Click **New repository secret**
3. Set **Name** to `TUNNEL_AUTH_KEY`
4. Set **Value** to a strong password of your choice
5. Click **Add secret**
You will use this same password later in `CodeFull.gs`.
### Step 3: Add the Workflow
1. In your repository, go to the **Actions** tab
2. Click **New workflow** (or go to the next step)
3. Click the **set up a workflow yourself** link
4. Delete the default content (if exists) and paste the contents of `cloudflared-quick.yml` [[here]]
5. Click **Commit changes...**, add a commit message, then click **Commit changes**
The workflow file will be saved to `.github/workflows/main.yml`.
(name does not matter and you can change it to anything)
### Step 4: Run the Workflow
1. Go to the **Actions** tab
2. Select **Full Tunnel (cloudflared Quick)** from the left sidebar
3. Click **Run workflow > Run workflow**
The workflow will start immediately.
### Step 5: Get the Tunnel URL
1. Click on the running workflow to see live logs
2. Wait for the **Expose tunnel** step to complete (about 15 seconds)
3. Look for the `::notice::Tunnel URL:` line in the log output
4. Copy the URL — it will look like `https://random-name.trycloudflare.com`
### Step 6: Configure CodeFull.gs
Open `CodeFull.gs` in the Google Apps Script editor and update these constants:
```javascript
const TUNNEL_SERVER_URL = "https://random-name.trycloudflare.com";
const TUNNEL_AUTH_KEY = "the-secret-you-set-in-step-2";
```
Deploy: **Deploy > New Deployment > Web App**.
Copy the new Deployment ID and update your `mhrv-rs` config.
### Step 7: Verify
Use `mhrv-rs test` or visit `https://ipleak.net` through your proxy.
## How It Works
1. GitHub Actions starts a Docker container running `mhrv-tunnel-node` on port
`8080`
2. `cloudflared` creates a free Quick Tunnel — a temporary `*.trycloudflare.com`
subdomain that routes to `localhost:8080` on the runner
3. The workflow extracts this URL from the `cloudflared` logs and displays it
4. `CodeFull.gs` forwards tunnel operations to this URL over HTTPS
5. The runner stays alive for 6 hours, then shuts down automatically
No DNS configuration, no SSL certificates, no port forwarding — `cloudflared`
handles everything.
## Renewing the Tunnel
The tunnel shuts down after 6 hours. To start a new session:
1. Go to the **Actions** tab
2. Select **Full Tunnel (cloudflared Quick)**
3. Click **Run workflow > Run workflow**
4. Copy the **new** tunnel URL from the logs (it changes each time)
5. Update `TUNNEL_SERVER_URL` in `CodeFull.gs` and redeploy
## Limitations
- The `*.trycloudflare.com` URL changes every time the workflow runs
- `CodeFull.gs` must be updated and redeployed each session
- 6-hour maximum per session (GitHub Actions limit)
## Troubleshooting
| Problem | Solution |
|---|---|
| Workflow fails at Docker step | GitHub Actions may be pulling the image for the first time. Wait 2-3 minutes and retry. |
| No tunnel URL appears in logs | Check that the **Expose tunnel** step completed. The URL is extracted from `cloudflared` output — allow 15 seconds for the tunnel to establish. |
| `CodeFull.gs` returns 502 or timeout | Verify the tunnel URL is correct and the workflow is still running. Check that `TUNNEL_AUTH_KEY` matches in both the secret and `CodeFull.gs`. |
[here]: cloudflared-quick.yml
@@ -0,0 +1,43 @@
name: Full Tunnel (cloudflared Quick)
on:
workflow_dispatch:
permissions:
contents: read
jobs:
tunnel:
runs-on: ubuntu-latest
timeout-minutes: 360
steps:
- name: Start mhrv-tunnel-node
run: |
docker run -d --name mhrv-tunnel \
-p 8080:8080 \
-e TUNNEL_AUTH_KEY="${{ secrets.TUNNEL_AUTH_KEY }}" \
ghcr.io/therealaleph/mhrv-tunnel-node:latest
sleep 5
curl -s http://localhost:8080/health || sleep 5
- name: Install cloudflared
run: |
curl -L --output cloudflared.deb \
https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
- name: Expose tunnel
run: |
cloudflared tunnel --url http://localhost:8080 2>&1 | tee tunnel.log &
sleep 10
URL=$(grep -o 'https://[a-zA-Z0-9.-]*\.trycloudflare\.com' tunnel.log | head -1)
echo "TUNNEL_URL=$URL" >> $GITHUB_ENV
echo "::notice::Tunnel URL: $URL"
echo "TUNNEL_SERVER_URL = $URL"
sleep 21000
- name: Cleanup
if: always()
run: |
docker stop mhrv-tunnel || true
pkill cloudflared || true
+124
View File
@@ -0,0 +1,124 @@
# ngrok Tunnel
Run a Full tunnel for 6 hours using an ngrok account (free tier). ngrok provides
a public URL that exposes the tunnel-node running on GitHub Actions.
## Prerequisites
- A GitHub account (free)
- An ngrok account (free — sign up at [ngrok.com](https://ngrok.com))
- `CodeFull.gs` deployed as a Google Apps Script Web App
## Setup
### Step 1: Get Your ngrok Authtoken
1. Go to [dashboard.ngrok.com](https://dashboard.ngrok.com) and sign in
2. Copy your authtoken from the **Getting Started** or **Your Authtoken** section
### Step 2: Create the Repository
If you already have a repository from another method, you can reuse it.
Otherwise:
1. Go to [github.com](https://github.com) and sign in
2. Click the **+** icon in the top-right corner, then **New repository**
3. Enter a repository name (e.g., `my-tunnel`)
4. Select **Private** (recommended — keeps your secrets secure)
5. Click **Create repository**
### Step 3: Add the Secrets
1. In your repository, go to **Settings > Secrets and variables > Actions**
2. Click **New repository secret** and add:
| Name | Value |
|---|---|
| `TUNNEL_AUTH_KEY` | A strong password. You will also set this in `CodeFull.gs`. |
| `NGROK_AUTH_TOKEN` | Your ngrok authtoken from Step 1. |
3. Click **Add secret** for each
### Step 4: Add the Workflow
1. In your repository, go to the **Actions** tab
2. Click **New workflow**
3. Click the **set up a workflow yourself** link
4. Delete the default content and paste the contents of `ngrok.yml` [[here]]
5. Click **Commit changes...**, add a commit message, then click **Commit changes**
The workflow file will be saved to `.github/workflows/ngrok.yml`.
### Step 5: Run the Workflow
1. Go to the **Actions** tab
2. Select **Full Tunnel (ngrok)** from the left sidebar
3. Click **Run workflow > Run workflow**
The workflow will start immediately.
### Step 6: Get the Tunnel URL
1. Click on the running workflow to see live logs
2. Wait for the **Expose tunnel** step to complete (about 10 seconds)
3. Look for the `::notice::Tunnel URL:` line in the log output
4. Copy the URL — it will look like `https://abc123.ngrok-free.app`
### Step 7: Configure CodeFull.gs
Open `CodeFull.gs` in the Google Apps Script editor and update these constants:
```javascript
const TUNNEL_SERVER_URL = "https://abc123.ngrok-free.app";
const TUNNEL_AUTH_KEY = "the-secret-you-set-in-step-3";
```
Deploy: **Deploy > New Deployment > Web App**.
Copy the new Deployment ID and update your `mhrv-rs` config.
### Step 8: Verify
Use `mhrv-rs test` or visit `https://ipleak.net` through your proxy.
You should see a GitHub Actions or ngrok IP address.
## How It Works
1. GitHub Actions starts a Docker container running `mhrv-tunnel-node` on port
`8080`
2. `ngrok` creates a secure tunnel using your authtoken, assigning a temporary
`*.ngrok-free.app` URL that routes to `localhost:8080` on the runner
3. The workflow extracts this URL from the ngrok API and displays it
4. `CodeFull.gs` forwards tunnel operations to this URL over HTTPS
5. The runner stays alive for 6 hours, then shuts down automatically
## Renewing the Tunnel
The tunnel shuts down after 6 hours. To start a new session:
1. Go to the **Actions** tab
2. Select **Full Tunnel (ngrok)**
3. Click **Run workflow > Run workflow**
4. Copy the **new** tunnel URL from the logs (it changes each time)
5. Update `TUNNEL_SERVER_URL` in `CodeFull.gs` and redeploy
## Limitations
- Requires an ngrok account (free tier: 1 online tunnel, limited connections
per minute)
- The `*.ngrok-free.app` URL changes every time the workflow runs
- `CodeFull.gs` must be updated and redeployed each session
- 6-hour maximum per session (GitHub Actions limit)
- Slightly higher latency than cloudflared methods (extra hop through ngrok's
relay servers)
## Troubleshooting
| Problem | Solution |
|---|---|
| ngrok authentication fails | Verify `NGROK_AUTH_TOKEN` matches the token in your [ngrok dashboard](https://dashboard.ngrok.com). |
| Workflow fails at Docker step | GitHub Actions may be pulling the image for the first time. Wait 2-3 minutes and retry. |
| No tunnel URL appears in logs | Check that the **Expose tunnel** step completed. The URL is fetched from the ngrok API — allow 10 seconds for the tunnel to establish. |
| Connection limit reached | ngrok's free tier limits connections per minute. Wait a moment and retry. |
| `CodeFull.gs` returns 502 or timeout | Verify the tunnel URL is correct and the workflow is still running. Check that `TUNNEL_AUTH_KEY` matches in both the secret and `CodeFull.gs`. |
[here]: ngrok.yml
+48
View File
@@ -0,0 +1,48 @@
name: Full Tunnel (ngrok)
on:
workflow_dispatch:
permissions:
contents: read
jobs:
tunnel:
runs-on: ubuntu-latest
timeout-minutes: 360
steps:
- name: Start mhrv-tunnel-node
run: |
docker run -d --name mhrv-tunnel \
-p 8080:8080 \
-e TUNNEL_AUTH_KEY="${{ secrets.TUNNEL_AUTH_KEY }}" \
ghcr.io/therealaleph/mhrv-tunnel-node:latest
sleep 5
curl -s http://localhost:8080/health || sleep 5
- name: Install ngrok
run: |
curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
| sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null \
&& echo "deb https://ngrok-agent.s3.amazonaws.com bookworm main" \
| sudo tee /etc/apt/sources.list.d/ngrok.list \
&& sudo apt update \
&& sudo apt install ngrok
ngrok config add-authtoken ${{ secrets.NGROK_AUTH_TOKEN }}
- name: Expose tunnel
id: expose
run: |
ngrok http 8080 --log=stdout > ngrok.log &
sleep 5
URL=$(curl -s http://localhost:4040/api/tunnels | python3 -c "import sys,json;print(json.load(sys.stdin)['tunnels'][0]['public_url'])")
echo "TUNNEL_URL=$URL" >> $GITHUB_OUTPUT
echo "::notice::Tunnel URL: $URL"
echo "TUNNEL_SERVER_URL = $URL"
sleep 21000
- name: Cleanup
if: always()
run: |
docker stop mhrv-tunnel || true
pkill ngrok || true