DEV Community

Jesse James Kyemting
Jesse James Kyemting

Posted on

Bypassing Localhost Isolation: Connecting GitHub Webhooks to a Local Jenkins Node Without Third-Party Agents

When configuring a standard CI/CD pipeline, you expect to run into firewall rules. But what happens when your automation controller and your deployment target live in completely separate network ecosystems?

That's the exact problem I broke down and solved while building the automation workflow for my portfolio platform. Here's how I tackled the "local-vs-cloud" loopback trap using a native SSH workaround.

The Problem: The Ingress Black Hole

My setup was split into a hybrid topology:

  • GitHub holding the source code and declarative Jenkinsfile.
  • AWS EC2 hosting the live production Docker container space.
  • Jenkins running locally inside a private network environment on localhost:8080. When setting up a GitHub Webhook to trigger automated builds on every git push, GitHub dropped a major red flag: failed to connect to host.

Because GitHub is on the public web, it cannot route packets into a closed home router or resolve a local loopback address.

The Fix: Zero-Installation Reverse Tunnels

Instead of deploying heavy management agents or re-architecting the Jenkins system onto a public cloud node, I used a reverse SSH port forwarding technique via serveo.net.

From a standard administrative command prompt, I executed a single command:

ssh -R 80:localhost:8080 serveo.net
Enter fullscreen mode Exit fullscreen mode

This established a secure, encrypted public proxy domain pointing right back into my local machine's listening port. By updating the GitHub Webhook Payload URL to point to this new secure ingress link, the handshake cleared cleanly on the next code push with a pristine 200 OK status.

The Automation Flow

With the network bridge established, the GitOps lifecycle now executes flawlessly:

  1. Commit & Push — Code changes hit the GitHub repository.
  2. Webhook Trigger — GitHub hits the secure SSH proxy tunnel, pinging the local Jenkins node.
  3. Automated Pipeline Execution — Jenkins pulls down the fresh commit, checks the host's Docker engine variables, builds an updated nginx:alpine image, tears down the stale container, and spins up a fresh container on public Port 80 of the cloud instance. Jenkins pipeline build #19 succeeded, showing green checkmark status, commit revision, and 42 second build time

Once the webhook was live, GitHub's delivery log confirmed the tunnel was working end to end:

GitHub webhook recent deliveries showing a successful green checkmark ping delivery

And the result: a live, publicly accessible portfolio site, rebuilt automatically on every push.

Live portfolio site for Jesse Kyemting running in production, showing a dark terminal-themed UI with profile, experience, and skills sections

Key Technical Takeaways

  • Validate socket bindings early. Running sudo ss -tulnp | grep 8080 is a must-know debugging step to isolate exactly where your automation tools are listening before configuring external triggers.
  • Firewalls have layers. Network bugs aren't always cloud-based. Always check both the cloud platform's security group rules and the operating system-level firewall (e.g. sudo ufw allow 80/tcp on Ubuntu) — a fix at one layer alone won't cut it.
  • Know when to reach for a heavier solution. A reverse SSH tunnel is a great fit for a learning project or quick demo. For a production deployment, I'd put Jenkins on the same private network as the EC2 instance, or use a more durable relay with persistent auth — worth keeping in mind as this setup scales beyond a portfolio site. Have you ever used raw SSH tunnels to debug webhooks or local ingress endpoints? Let's talk about alternative lightweight setups in the comments!

Top comments (0)