-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
151 lines (135 loc) · 22.4 KB
/
index.html
File metadata and controls
151 lines (135 loc) · 22.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<!DOCTYPE html><html class="default" lang="en" data-base="."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>tunnelforge</title><meta name="description" content="Documentation for tunnelforge"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="assets/style.css"/><link rel="stylesheet" href="assets/highlight.css"/><script defer src="assets/main.js"></script><script async src="assets/icons.js" id="tsd-icons-script"></script><script async src="assets/search.js" id="tsd-search-script"></script><script async src="assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="index.html" class="title">tunnelforge</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><h1>tunnelforge</h1></div><div class="tsd-panel tsd-typography"><p><img src="media/tunnelforge-350x350.jpg" alt="TunnelForge Logo"></p>
<p><img src="https://img.shields.io/github/license/elshadaghazade/tunnelforge?label=license&style=for-the-badge" alt="GitHub">
<img src="https://img.shields.io/github/actions/workflow/status/elshadaghazade/tunnelforge/release.yml?branch=main" alt="GitHub Workflow Status">
<img src="https://img.shields.io/github/issues/elshadaghazade/tunnelforge" alt="GitHub issues">
<img src="https://img.shields.io/docker/pulls/elshadaghazade/tunnelforge-server?label=docker%20pulls%20for%20server" alt="Docker Pulls Server">
<img src="https://img.shields.io/docker/pulls/elshadaghazade/tunnelforge-client?label=docker%20pulls%20for%20client" alt="Docker Pulls Client"></p>
<a id="tunnelforge" class="tsd-anchor"></a><h1 class="tsd-anchor-link">TunnelForge<a href="#tunnelforge" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p><strong>TunnelForge</strong> is a lightweight, open-source, self-hosted alternative to <a href="https://ngrok.com/">ngrok</a> that provides tunneling services for exposing local applications to the internet. It supports HTTP, WebSocket, and any other TCP-based protocols, allowing seamless integration with modern applications.</p>
<a id="demo-video" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Demo Video<a href="#demo-video" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p><a href="https://youtu.be/owV8mpbeKIg"><img src="https://img.youtube.com/vi/owV8mpbeKIg/hqdefault.jpg" alt="Watch the Demo"></a></p>
<p>Click the image above to watch the <strong>TunnelForge</strong> demo and learn how it works in action!</p>
<a id="features" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Features<a href="#features" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ul>
<li>Expose local services to the internet with unique subdomains.</li>
<li>Support for HTTP, WebSocket, and other TCP-based protocols.</li>
<li>Easy setup for local and public servers.</li>
<li>Support for environment-based configurations.</li>
<li>Daemonized server processes with PM2.</li>
<li>DNS configuration support via Cloudflare.</li>
<li>Future Docker support for containerized deployments.</li>
</ul>
<a id="installation" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Installation<a href="#installation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ol>
<li>Clone the repository:<pre><code class="bash"><span class="hl-0">git</span><span class="hl-1"> </span><span class="hl-2">clone</span><span class="hl-1"> </span><span class="hl-2">https://github.com/elshadaghazade/tunnelforge.git</span><br/><span class="hl-0">cd</span><span class="hl-1"> </span><span class="hl-2">tunnelforge</span>
</code><button type="button">Copy</button></pre>
</li>
<li>Install dependencies:<pre><code><span class="hl-3">npm</span><span class="hl-1"> </span><span class="hl-3">install</span>
</code><button>Copy</button></pre>
</li>
<li>Build the project:<pre><code><span class="hl-3">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-3">build</span>
</code><button>Copy</button></pre>
</li>
</ol>
<a id="usage" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Usage<a href="#usage" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="development-mode" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Development Mode<a href="#development-mode" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><ol>
<li>Start the <strong>server</strong>:<pre><code><span class="hl-3">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-4">server</span><span class="hl-1">:</span><span class="hl-3">dev</span>
</code><button>Copy</button></pre>
The server will generate a static subdomain (sub1).</li>
<li>Add an entry to your local <code>/etc/hosts</code> file:<pre><code><span class="hl-5">127.0</span><span class="hl-1">.</span><span class="hl-5">0.1</span><span class="hl-1"> </span><span class="hl-3">sub1</span><span class="hl-1">.</span><span class="hl-3">myproxy</span><span class="hl-1">.</span><span class="hl-3">com</span>
</code><button>Copy</button></pre>
</li>
<li>Start the <strong>client</strong>:<pre><code><span class="hl-3">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-4">client</span><span class="hl-1">:</span><span class="hl-3">dev</span><span class="hl-1"> -- -</span><span class="hl-3">h</span><span class="hl-1"> </span><span class="hl-3">myproxy</span><span class="hl-1">.</span><span class="hl-3">com</span><span class="hl-1"> -</span><span class="hl-3">p</span><span class="hl-1"> [</span><span class="hl-6">SERVER_PORT_FROM_ENV</span><span class="hl-1">] -</span><span class="hl-3">q</span><span class="hl-1"> [</span><span class="hl-6">LOCAL_APP_PORT</span><span class="hl-1">] -</span><span class="hl-3">r</span><span class="hl-1"> [</span><span class="hl-6">LOCAL_APP_HOST</span><span class="hl-1">]</span>
</code><button>Copy</button></pre>
</li>
<li>Access your application using:<pre><code><span class="hl-4">http</span><span class="hl-1">:</span><span class="hl-7">//sub1.myproxy.com:[INCOMING_PORT_FROM_ENV]</span>
</code><button>Copy</button></pre>
</li>
</ol>
<a id="production-mode" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Production Mode<a href="#production-mode" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ol>
<li><strong>On the server</strong>:
<ul>
<li>Open ports for <code>CLIENT_SERVER_PORT</code> and <code>INCOMING_SERVER_PORT</code> in your cloud environment (e.g., AWS EC2).</li>
<li>Configure DNS in Cloudflare:
<ul>
<li>Create an <code>A</code> record for <code>*.yourdomain.com</code> pointing to your server's IP.</li>
</ul>
</li>
<li>Run the server:<pre><code><span class="hl-3">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-4">server</span><span class="hl-1">:</span><span class="hl-3">prod</span>
</code><button>Copy</button></pre>
</li>
<li>PM2 users can daemonize the process:<pre><code><span class="hl-3">pm2</span><span class="hl-1"> </span><span class="hl-3">start</span><span class="hl-1"> </span><span class="hl-3">ecosystem</span><span class="hl-1">.</span><span class="hl-3">config</span><span class="hl-1">.</span><span class="hl-3">js</span>
</code><button>Copy</button></pre>
</li>
</ul>
</li>
<li>On the client:
<ul>
<li>Build the client:<pre><code><span class="hl-3">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-3">build</span>
</code><button>Copy</button></pre>
</li>
<li>Run the client:<pre><code><span class="hl-3">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-4">client</span><span class="hl-1">:</span><span class="hl-3">prod</span><span class="hl-1"> -- -</span><span class="hl-3">h</span><span class="hl-1"> </span><span class="hl-3">yourdomain</span><span class="hl-1">.</span><span class="hl-3">com</span><span class="hl-1"> -</span><span class="hl-3">p</span><span class="hl-1"> [</span><span class="hl-6">SERVER_PORT_FROM_ENV</span><span class="hl-1">] -</span><span class="hl-3">q</span><span class="hl-1"> [</span><span class="hl-6">LOCAL_APP_PORT</span><span class="hl-1">] -</span><span class="hl-3">r</span><span class="hl-1"> [</span><span class="hl-6">LOCAL_APP_HOST</span><span class="hl-1">]</span>
</code><button>Copy</button></pre>
</li>
<li>After connecting, the client logs the public address:<pre><code><span class="hl-3">Your</span><span class="hl-1"> </span><span class="hl-3">public</span><span class="hl-1"> </span><span class="hl-3">address</span><span class="hl-1"> </span><span class="hl-3">is</span><span class="hl-1"> </span><span class="hl-4">http</span><span class="hl-1">:</span><span class="hl-7">//[UNIQUE_SUBDOMAIN].yourdomain.com:[INCOMING_PORT_FROM_ENV]</span>
</code><button>Copy</button></pre>
</li>
<li>Access your public application using the generated public address.</li>
</ul>
</li>
</ol>
<a id="environment-variables" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Environment Variables<a href="#environment-variables" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Set these variables in your <code>.env.development</code> or <code>.env.production</code> file:</p>
<pre><code><span class="hl-6">NODE_ENV</span><span class="hl-1">=</span><span class="hl-3">production</span><br/><span class="hl-6">CLIENT_SERVER_PORT</span><span class="hl-1">=</span><span class="hl-5">4000</span><br/><span class="hl-6">INCOMING_SERVER_PORT</span><span class="hl-1">=</span><span class="hl-5">4001</span><br/><span class="hl-6">SERVER_CLIENT_HOST</span><span class="hl-1">=</span><span class="hl-5">0.0</span><span class="hl-1">.</span><span class="hl-5">0.0</span><br/><span class="hl-6">SERVER_INCOMING_HOST</span><span class="hl-1">=</span><span class="hl-5">0.0</span><span class="hl-1">.</span><span class="hl-5">0.0</span><br/><span class="hl-6">RECONNECT_INTERVAL</span><span class="hl-1">=</span><span class="hl-5">1000</span><br/><span class="hl-6">PROXY_SERVER_MAIN_HOST</span><span class="hl-1">=</span><span class="hl-3">globalmedbooking</span><span class="hl-1">.</span><span class="hl-3">com</span><br/><br/><span class="hl-6">CLIENT_PARAM_SERVER_HOST</span><span class="hl-1">=</span><span class="hl-5">127.0</span><span class="hl-1">.</span><span class="hl-5">0.1</span><br/><span class="hl-6">CLIENT_PARAM_SERVER_PORT</span><span class="hl-1">=</span><span class="hl-5">4000</span><br/><span class="hl-6">CLIENT_PARAM_LOCAL_APP_HOST</span><span class="hl-1">=</span><span class="hl-5">127.0</span><span class="hl-1">.</span><span class="hl-5">0.1</span><br/><span class="hl-6">CLIENT_PARAM_LOCAL_APP_PORT</span><span class="hl-1">=</span><span class="hl-5">3010</span>
</code><button>Copy</button></pre>
<a id="dockerizing-tunnelforge" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Dockerizing TunnelForge<a href="#dockerizing-tunnelforge" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>You can easily run both the <strong>TunnelForge server</strong> and <strong>client</strong> using Docker. This approach simplifies deployment, ensuring a consistent environment for running the application</p>
<a id="steps-to-dockerize-tunnelforge" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Steps to Dockerize TunnelForge<a href="#steps-to-dockerize-tunnelforge" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><ol>
<li>
<p><strong>Prepare the <code>.env</code> File</strong></p>
<p>Create an .env file in the root directory with the following contents, adjusting the values to match your desired configuration:</p>
<pre><code><span class="hl-6">NODE_ENV</span><span class="hl-1">=</span><span class="hl-3">production</span><br/><span class="hl-6">CLIENT_SERVER_PORT</span><span class="hl-1">=</span><span class="hl-5">4000</span><br/><span class="hl-6">INCOMING_SERVER_PORT</span><span class="hl-1">=</span><span class="hl-5">4001</span><br/><span class="hl-6">SERVER_CLIENT_HOST</span><span class="hl-1">=</span><span class="hl-5">0.0</span><span class="hl-1">.</span><span class="hl-5">0.0</span><br/><span class="hl-6">SERVER_INCOMING_HOST</span><span class="hl-1">=</span><span class="hl-5">0.0</span><span class="hl-1">.</span><span class="hl-5">0.0</span><br/><span class="hl-6">RECONNECT_INTERVAL</span><span class="hl-1">=</span><span class="hl-5">1000</span><br/><span class="hl-6">PROXY_SERVER_MAIN_HOST</span><span class="hl-1">=</span><span class="hl-3">yourcustomdomain</span><span class="hl-1">.</span><span class="hl-3">com</span><br/><br/><span class="hl-6">CLIENT_PARAM_SERVER_HOST</span><span class="hl-1">=</span><span class="hl-5">127.0</span><span class="hl-1">.</span><span class="hl-5">0.1</span><br/><span class="hl-6">CLIENT_PARAM_SERVER_PORT</span><span class="hl-1">=</span><span class="hl-5">4000</span><br/><span class="hl-6">CLIENT_PARAM_LOCAL_APP_HOST</span><span class="hl-1">=</span><span class="hl-5">127.0</span><span class="hl-1">.</span><span class="hl-5">0.1</span><br/><span class="hl-6">CLIENT_PARAM_LOCAL_APP_PORT</span><span class="hl-1">=</span><span class="hl-5">3010</span>
</code><button>Copy</button></pre>
<ul>
<li><strong>Server Environment Variables:</strong>
<ul>
<li><code>CLIENT_SERVER_PORT</code> and <code>INCOMING_SERVER_PORT</code>: Ports exposed by the TunnelForge server.</li>
<li><code>PROXY_SERVER_MAIN_HOST</code>: Your main domain to handle subdomains.</li>
</ul>
</li>
<li><strong>Client Parameters:</strong>
<ul>
<li><code>CLIENT_PARAM_SERVER_HOST</code> and <code>CLIENT_PARAM_SERVER_PORT</code>: Host and port of the TunnelForge server.</li>
<li><code>CLIENT_PARAM_LOCAL_APP_HOST</code> and <code>CLIENT_PARAM_LOCAL_APP_PORT</code>: Host and port of the local application to expose.</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>Build and Run with Docker Compose</strong></p>
<p>The provided <code>docker-compose.yml</code> file is configured to build and run both the server and client. To start everything, simply run:</p>
<pre><code><span class="hl-3">docker</span><span class="hl-1"> </span><span class="hl-3">compose</span><span class="hl-1"> </span><span class="hl-3">up</span><span class="hl-1"> -</span><span class="hl-3">d</span>
</code><button>Copy</button></pre>
</li>
<li>
<p><strong>Server and Client Communication</strong></p>
<ul>
<li>The <strong>server</strong> will listen on the ports specified in <code>CLIENT_SERVER_PORT</code> and <code>INCOMING_SERVER_PORT</code>.</li>
<li>The <strong>client</strong> will forward requests to your local application and make it publicly accessible via the <code>PROXY_SERVER_MAIN_HOST</code> and generated subdomain.</li>
</ul>
</li>
<li>
<p><strong>Accessing Your Public URL</strong></p>
<p>After starting the services, the client will log the public URL for accessing your local application. This will be in the format:</p>
<pre><code><span class="hl-4">http</span><span class="hl-1">:</span><span class="hl-7">//[generated-subdomain].yourcustomdomain.com:[INCOMING_SERVER_PORT]</span>
</code><button>Copy</button></pre>
</li>
<li>
<p><strong>Explore the Docker Images</strong></p>
<p>You can find the Docker images for TunnelForge on Docker Hub:</p>
<ul>
<li><a href="https://hub.docker.com/r/elshadaghazade/tunnelforge-server">TunnelForge Server</a></li>
<li><a href="https://hub.docker.com/r/elshadaghazade/tunnelforge-client">TunnelForge Client</a></li>
</ul>
</li>
</ol>
<a id="contributing" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Contributing<a href="#contributing" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>We welcome contributions! See our <a href="media/CONTRIBUTING.md">Contributing Guidelines</a> for details.</p>
<a id="license" class="tsd-anchor"></a><h2 class="tsd-anchor-link">License<a href="#license" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>TunnelForge is licensed under the <a href="media/LICENSE">MIT License</a>.</p>
<a id="official-website" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Official Website<a href="#official-website" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Visit the official website of TunnelForge for more details: <a href="https://tunnelforge.org">tunnelforge.org</a>.</p>
<a id="documentation" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Documentation<a href="#documentation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>The full API and usage documentation is hosted on <a href="https://elshadaghazade.github.io/tunnelforge/">GitHub Pages</a>.</p>
<p>If you'd like to view it locally or use it in a different hosting platform, the documentation is generated using TypeDoc and is located in the <a href="media/index.html">/docs</a> folder.</p>
<p>Happy tunneling with <strong>TunnelForge!</strong></p>
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#tunnelforge"><span>Tunnel<wbr/>Forge</span></a><ul><li><a href="#demo-video"><span>Demo <wbr/>Video</span></a></li><li><a href="#features"><span>Features</span></a></li><li><a href="#installation"><span>Installation</span></a></li><li><a href="#usage"><span>Usage</span></a></li><li><ul><li><a href="#development-mode"><span>Development <wbr/>Mode</span></a></li></ul></li><li><a href="#production-mode"><span>Production <wbr/>Mode</span></a></li><li><a href="#environment-variables"><span>Environment <wbr/>Variables</span></a></li><li><a href="#dockerizing-tunnelforge"><span>Dockerizing <wbr/>Tunnel<wbr/>Forge</span></a></li><li><ul><li><a href="#steps-to-dockerize-tunnelforge"><span>Steps to <wbr/>Dockerize <wbr/>Tunnel<wbr/>Forge</span></a></li></ul></li><li><a href="#contributing"><span>Contributing</span></a></li><li><a href="#license"><span>License</span></a></li><li><a href="#official-website"><span>Official <wbr/>Website</span></a></li><li><a href="#documentation"><span>Documentation</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">tunnelforge</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>