How to create a self hosted ngrok
How to include the child model's fields in the dashboard and be able to search through them.
The Problem
I needed to use Facebook’s webhooks because I was creating a Messenger chatbot. In order for them to work in development I needed to “host” my local server so it can receive requests from Facebook. I tried using the free version of ngrok, but got an error (something related to security). So I was left with the option of paying for ngrok, or creating my own thing. So I spent a few days researching and I managed to puzzle together a free alternative of ngrok that worked for me.
Step 1: Create a DigitalOcean droplet
It is basically free, because you can use this referral link, which gives you 200$ of free credits. The machine we are going to use costs 4$ per month. We will also need a domain name.
Step 2: SSH into droplet
Get the IP of your machine and connect to it using ssh
.
1
ssh root@your_droplet_ip
Step 3: Get a SSL certificate using certbot
We will obtain a free SSL certificate using Let’s encrypt. You don’t necessary need a certificate, but it is free and easy, so why not.
Input your domain, so it is easier to copy the commands directly
yourdomain will be used for all commands.
Install certbot
https://certbot.eff.org/instructions?ws=nginx&os=snap
1
2
3
sudo apt-get remove certbot &&
sudo snap install --classic certbot &&
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Once certbot is installed we can provision the certificate like this:
1
certbot -d tunnel.yourdomain -d *.tunnel.yourdomain --manual --preferred-challenges dns certonly
It will ask you for an email and to accept the terms of service. After this you will see:
1
2
Account registered.
Requesting a certificate for tunnel.yourdomain and *.tunnel.yourdomain
Finally, it will ask us to create TXT records.
1
2
3
4
5
Please deploy a DNS TXT record under the name:
_acme-challenge.tunnel.yourdomain.
with the following value:
tkSrK1GJZuZjTMnU09oHhVtJ0Q5iX8iVvEJJzo1ngKc
Step 4: Setup TXT records
Go on and create the two TXT records in your DNS settings. While you are there you can create two A records with *.tunnel
and tunnel
as the “hosts”, and the ip of your droplet as the “value” (I am using Namecheap). We will need this later.
The TXT records should be with host: _acme-challenge.tunnel
and the value should be the one given in your command line.
1
2
3
4
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.tunnel.yourdomain.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.
1
2
3
4
5
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/tunnel.combatist.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/tunnel.combatist.com/privkey.pem
This certificate expires on 2025-11-18.
These files will be updated when the certificate renews.
Step 5: Configure nginx
https://ubuntu.com/tutorials/install-and-configure-nginx#2-installing-nginx
1
2
sudo apt update -y &&
sudo apt install nginx -y
Go on and create this file, which we will need for our configuration:
1
sudo nano /etc/nginx/sites-available/tunnel.yourdomain
Paste this in the newly created file:
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
server {
server_name tunnel.yourdomain;
access_log /var/log/nginx/$host;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/tunnel.yourdomain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tunnel.yourdomain/privkey.pem;
location / {
proxy_pass http://localhost:3000/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
}
error_page 502 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
# Automatically redirect http to https
server {
if ($host = tunnel.yourdomain) {
return 301 https://$host$request_uri;
}
listen 80;
server_name tunnel.yourdomain;
return 404;
}
Create a link from /etc/nginx/sites-available/tunnel.yourdomain
to /etc/nginx/sites-enabled/
, to enable the configuration:
1
sudo ln -s /etc/nginx/sites-available/tunnel.yourdomain /etc/nginx/sites-enabled/
Now go and remove the default site, and restart nginx:
1
2
rm /etc/nginx/sites-enabled/default &&
sudo systemctl reload nginx
Step 6: Run your program
1
python3 -m http.server 8888
Step 7: Create a SSH reverse tunnel
Now you can exit the droplet and go to the command line of your own machine.
Start a SSH reverse tunnel:
1
ssh -R 3000:localhost:8888 root@your_droplet_ip
Now when you go to tunnel.yourdomain
you will see the same thing you see on localhost:8888
.
Sources:
- https://www.digitalocean.com/community/questions/self-hosted-ngrok-or-serveo-alternative
- Unavailable, but I will still include it here: https://jczhang.com/2021/02/27/self-hosted-ngrok-tunnel-to-localhost-with-ssh-reverse-tunneling-nginx-letsencrypt/
- https://medium.com/@shivanshvij/a-self-hosted-ngrok-45bcec06d0cf