# DockFlare (Tunnel management)

<table data-view="cards"><thead><tr><th></th><th></th></tr></thead><tbody><tr><td>Time Required</td><td>5 Minutes</td></tr><tr><td>Difficulty</td><td>Easy</td></tr><tr><td>Required Knowledge</td><td>Cloudflare DNS, Cloudflare Zero Trust, Docker Compose</td></tr></tbody></table>

{% hint style="warning" %}

## Please ensure you have followed [Cloudflare Zero Trust](/guides/other-guides/cloudflare/cloudflare-zero-trust.md#set-up-wildcard-application) before following this guide - you may accidentally make your internal resources public.

{% endhint %}

## Generate an API key

You will need an API key with write access to your Cloudflare Zero Trust and DNS zones

1. Navigate to <https://dash.cloudflare.com/profile/api-tokens>
2. At API tokens, click on 'Create Token'
3. Select the 'Custom Token' and set the below
   1. Give your token a name, eg "Dockflare"

   2. Permissions:

      |         |                           |      |
      | ------- | ------------------------- | ---- |
      | Account | Cloudflare Tunnel         | Edit |
      | Account | Account Settings          | Read |
      | Account | Access: Apps and Policies | Edit |
      | Zone    | Zone                      | Read |
      | Zone    | DNS                       | Edit |

   3. Account Resources"

      |         |              |
      | ------- | ------------ |
      | Include | All Accounts |

   4. Zone Resources"

      |         |                                        |
      | ------- | -------------------------------------- |
      | Include | All Zones (or select specific domains) |
4. Click on 'Continue to Summary'
5. Click on 'Create token'
6. Save your API key to your password vault

## Get your Account ID

1. Navigate to <https://dash.cloudflare.com/>
2. Next to your name / account name, click on the 3 dots menu
3. Click on Copy Account ID
4. Save to your Password vault

## Create Portainer Stack

{% hint style="info" %}
The below compose file is NOT my live production file - refer to the all docker stack under the 'homelab' section
{% endhint %}

{% code title="docker-compose.yml" %}

```yml
services:
    dockflare:
    image: alplat/dockflare:v2.0.4 
## This older image does NOT require setting up the WebUI for it to function
    restart: unless-stopped
    healthcheck:
      test: wget --no-verbose --tries=1 --spider http://localhost:5000 -O /dev/null || exit 1
      interval: 30s
      retries: 3
      start_period: 30s
      timeout: 20s 
    ports:
      - ${WEB_PORT:-5000}:5000
    environment:
      - TUNNEL_NAME=${HOSTNAME:-MissingHostname}
## Forces Cloudflare tunnel to run with the Host network
      - CLOUDFLARED_NETWORK_NAME=host
      - CLOUDFLARED_IMAGE=cloudflare/cloudflared:${CF_TUNNELVER:-latest}  
      - CF_API_TOKEN=${CF_APITOKEN}
      - CF_ACCOUNT_ID=${CF_ACCOUNTID}
      - AGENT_STATUS_UPDATE_INTERVAL_SECONDS=5
      - SYNC_ALL_CLOUDFLARE_POLICIES=true
      - TZ=${TZ:-UTC}
      - GRACE_PERIOD_SECONDS=28800
      - CLEANUP_INTERVAL_SECONDS=900
      - SCAN_ALL_NETWORKS=true
      - MAX_CONCURRENT_DNS_OPS=${DOCKFLARE_DNSOPS:-2}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - dockflare:/app/data
    labels:
      - autoheal=true
      - dockflare.enable=true
      - dockflare.0.hostname=${HOSTNAME:-MissingHostname}-dockflare.${DOMAIN}
      - dockflare.0.service=http://${HOSTNAME:-localhost}:${DOCKLAREPORT:-5000}
      - dockflare.0.access.policy=authentication
      - dockflare.0.tunnel.name=Dockflare
      - dockflare.0.zonename=${DOMAIN}
      #- cloudflare.tunnel.path=${URLPATH:-}

volumes:
  dockflare:
```

{% endcode %}

{% code title=".env file" %}

```
# --- General System ---
TZ=
## Internal DNS name (do not use IP) of the machine running Dockflare
HOSTNAME=
## https://hub.docker.com/r/cloudflare/cloudflared/tags
CF_TUNNELVER=latest

# --- Cloudflare Credentials ---
## API token
CF_APITOKEN=
## Account ID
CF_ACCOUNTID=

# --- Domain Settings ---
## Your Dockflare container will be available at ${hostname}-dockflare.${domain}
DOMAIN=

# --- Networking ---
WEB_PORT=5000
```

{% endcode %}

## How to use Dockflare

Add the following labels to any docker compose containers you wish to make accessible via Zero Trust,

<pre class="language-yaml"><code class="lang-yaml">      labels:
            - dockflare.enable=true
            - dockflare.0.hostname=${SUBDOMAIN}${DOMAIN}
            - dockflare.0.service=http://${HOSTNAME:-localhost}:${<a data-footnote-ref href="#user-content-fn-1">WEBPORT:-5000</a>}
            - dockflare.0.access.policy=${DF_POLICY:-tld_default}
            - dockflare.0.tunnel.name={DF_APPNAME}
            - dockflare.0.zonename=${DOMAIN}
            - dockflare.0.tunnel.path=${URLPATH:-}
</code></pre>

and use the following env files

{% tabs %}
{% tab title="root (example.com)" %}

```
HOSTNAME=
WEBPORT=
POLICY=tld_default
APPNAME=
DOMAIN=
```

{% endtab %}

{% tab title="subdomain (sub.example.com)" %}

```
SUBDOMAIN=
HOSTNAME=
WEBPORT=
POLICY=tld_default
APPNAME=
DOMAIN=
```

{% endtab %}

{% tab title="sub + path (sub.example.com/subpath)" %}

```
SUBDOMAIN=
HOSTNAME=
WEBPORT=
POLICY=tld_default
APPNAME=
DOMAIN=
URLPATH=
```

{% endtab %}

{% tab title="path (example.com/subpath)" %}

```
HOSTNAME=
WEBPORT=
POLICY=tld_default
APPNAME=
DOMAIN=
URLPATH=
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
It is possible to have multiple Dockflare links to 1 container, eg an internal admin page and a public status page. Use `dockflare.1.xxx`, `dockflare.2.xxx`, `dockflare.3.xxx` etc for this\
\
You may need to edit the variables to make this function correctly
{% endhint %}

[^1]: update do match your containers port


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.trentbauer.com/guides/other-guides/cloudflare/dockflare-tunnel-management.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
