Provides a way to expose localhost services on publicly-reachable domains, using Heroku and Tunnelto.
The provided Dockerfile creates an image meant to run on Heroku which has the following components:
- Tunnelto server. Creates/removes localhost tunnels, routes tunnel traffic, communicates with remote Tunnelto client.
- HAProxy. Routes incoming traffic between the Tunnelto server control port (i.e. creating a tunnel) and the tunnel port (i.e. incoming tunnel traffic meant to go to localhost).
- SSL certificate renewal script. (Optional) When executed, runs Certbot in conjunction with certbot-dns-cloudflare and updates the Heroku application's SSL certificate. Normally, Heroku ACM takes care of automatic certificate renewal, but cannot handle wildcard certificates, needed to support tunnels routed by subdomain.
- Heroku application using paid dyno (for SSL support) or free dyno (no SSL support)
- While Heroku does support SSL for free dynos, SSL for custom subdomains is not included, hence the limitation.
- Cloudflare-hosted custom domain (for SSL support)
- TODO: Document AWS account in US-East-1
- Tunnelto client (for running the tunnel)
-
Create a new Heroku application (or repurpose an existing one)
-
Point your custom domain of choice to it, as well as a wildcard subdomain of it. For example, if
my-tunnel.dev
is your custom domain, bothmy-tunnel.dev
and*.my-tunnel.dev
need to point to the Heroku application. See Custom Domain Names for Apps for more information.- Note: It is possible to have multiple custom domains, as long as each custom domain has a corresponding
*.{custom-domain}
wildcard subdomain also pointing to the Heroku application.
- Note: It is possible to have multiple custom domains, as long as each custom domain has a corresponding
-
If your Heroku application is set to use a non-
container
stack, change it to use thecontainer
stack as this is a Docker application. (https://devcenter.heroku.com/articles/stack#migrating-to-a-new-stack) -
Set the following config vars on the Heroku application:
TUNNELTO_CTRL_PORT
:5000
TUNNELTO_TUNNEL_PORT
:8080
(or another port as long as it is different from Heroku'sPORT
orTUNNELTO_CTRL_PORT
)TUNNELTO_ALLOWED_HOSTS
: A comma-separated list of custom domains the application is reachable at (excluding wildcard domains, so ifmy-tunnel.dev
andmy-tunnel-2.dev
are two custom domains, the variable is set tomy-tunnel.dev,my-tunnel-2.dev
)TUNNELTO_AWS_ACCESS_KEY_ID
: TODOTUNNELTO_AWS_SECRET_ACCESS_KEY
: TODOCERTBOT_EMAIL
: (For SSL support only) TODOCERTBOT_CLOUDFLARE_TOKEN
: (For SSL support only) TODOX_HEROKU_CLIENT_SECRET
: (For SSL support only) TODOX_HEROKU_REFRESH_TOKEN
: (For SSL support only) TODO
-
Deploy the application. As documented in https://devcenter.heroku.com/categories/deploying-with-docker, you have two options:
- Git push this repository to Heroku, which will trigger a Docker build on Heroku
- Note: If you intend to deploy more than once, you may want to build the Docker image locally as Heroku does not maintain Docker build cache. repository to Heroku, either via Git or by building the Docker container locally and then deploying manually per instructions in https://devcenter.heroku.com/articles/container-registry-and-runtime.
- Deploy manually. As a convenience, you can utilize the
Makefile
helper by runningmake release HEROKU_APP={app-name-or-id}
- Git push this repository to Heroku, which will trigger a Docker build on Heroku
-
To provision SSL certificates for the first time, run
heroku run -a {app-name-or-id} ./renew-certificate.py
-
To make SSL certificate renewal a daily Heroku job:
- Provision the Heroku scheduler add-on
- Create a daily job which runs
./renew-certificate.py
- Note: If the job is set to run more frequently (e.g. hourly or every 10 minutes), Certbot will start failing to generate certificates due to Certbot rate limits
-
Install the Tunnelto client per instructions in Tunnelto and test out the tunnel:
# If using SSL CTRL_HOST=my-tunnel.dev tunnelto # If not using SSL CTRL_HOST=my-tunnel.dev CTRL_PORT=80 CTRL_TLS_OFF=1 tunnelto