{"id":135,"date":"2019-03-14T10:27:00","date_gmt":"2019-03-14T10:27:00","guid":{"rendered":""},"modified":"2026-01-08T12:25:21","modified_gmt":"2026-01-08T06:55:21","slug":"can-you-integrate-a-github-webhook-with-privately-hosted-jenkins-no-think-again","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/2019\/03\/14\/can-you-integrate-a-github-webhook-with-privately-hosted-jenkins-no-think-again\/","title":{"rendered":"Can you integrate a GitHub Webhook with Privately hosted Jenkins No? Think again"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align: left;\">\n<div dir=\"ltr\" style=\"text-align: left;\">\n<div dir=\"ltr\" style=\"text-align: left;\">\n<div dir=\"ltr\" style=\"text-align: left;\">\n<div class=\"separator\" style=\"clear: both;\"><span style=\"font-size: 28px; font-weight: 900; text-align: left;\">Introduction<\/span><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div dir=\"ltr\" style=\"text-align: left;\">\n<div dir=\"ltr\" style=\"line-height: 1.38; margin-bottom: 0; margin-top: 0;\">\n<p data-start=\"860\" data-end=\"1203\">Triggering Jenkins builds automatically after every code commit is a core requirement in any continuous integration setup. Jenkins supports automated triggers through repository polling or event based notifications. While polling works, it consumes resources and introduces delays. Push based triggering through webhooks is far more efficient.<\/p>\n<p data-start=\"1205\" data-end=\"1498\">The difficulty appears when Jenkins is hosted inside a private network and the version control system is hosted on a cloud platform such as GitLab. In this scenario, GitLab cannot directly reach the Jenkins endpoint, making webhook based triggering difficult without exposing Jenkins publicly.<\/p>\n<p data-start=\"1500\" data-end=\"1745\">Webhook Relay solves this problem by acting as a secure bridge between GitLab and a privately hosted Jenkins server. This article explains how GitLab webhooks can trigger Jenkins jobs using Webhook Relay, based on real implementation experience.<\/p>\n<p data-start=\"1500\" data-end=\"1745\"><img decoding=\"async\" src=\"https:\/\/opstree.com\/blog\/\/wp-content\/uploads\/2019\/03\/8ddd4-screenshot2b2019-03-142bat2b3.06.522bpm.png?w=300\" \/><\/p>\n<h2 data-start=\"1752\" data-end=\"1789\">Installing the Webhook Relay Agent<\/h2>\n<p data-start=\"1791\" data-end=\"1913\">The Webhook Relay agent needs to run on the same machine where Jenkins is hosted or where Jenkins is reachable internally.<\/p>\n<p data-start=\"1915\" data-end=\"1982\">Below is the installation process shown as step based instructions.<\/p>\n<div class=\"contain-inline-size rounded-2xl corner-superellipse\/1.1 relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl\/main:top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><code class=\"whitespace-pre!\"><code class=\"whitespace-pre!\"><span class=\"hljs-comment\"># download the relay binary<\/span><br \/>\ncurl -sSL https:<span class=\"hljs-regexp\">\/\/<\/span>storage.googleapis.com<span class=\"hljs-regexp\">\/webhookrelay\/<\/span>downloads\/relay-linux-amd64 &gt; relay<\/code><\/code><span class=\"hljs-comment\"># make the binary executable<\/span><br \/>\nchmod +x relay<\/p>\n<p><code class=\"whitespace-pre!\"><code class=\"whitespace-pre!\"><\/code><\/code><span class=\"hljs-comment\"># move it to a directory in system path<\/span><br \/>\nsudo mv relay <span class=\"hljs-regexp\">\/usr\/<\/span>local<span class=\"hljs-regexp\">\/bin\/<\/span>relay<\/p>\n<\/div>\n<\/div>\n<p data-start=\"2232\" data-end=\"2352\">Webhook Relay service runs on a public endpoint, while this agent runs locally and listens for forwarded webhook events.<\/p>\n<h2 data-start=\"2359\" data-end=\"2394\">Creating a Webhook Relay Account<\/h2>\n<p data-start=\"2396\" data-end=\"2493\">Create an account on the official Webhook Relay platform using the registration page shown below.<\/p>\n<div class=\"contain-inline-size rounded-2xl corner-superellipse\/1.1 relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl\/main:top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><code class=\"whitespace-pre!\"><span class=\"hljs-symbol\">https:<\/span><span class=\"hljs-comment\">\/\/my.webhookrelay.com\/register<\/span><br \/>\n<\/code><\/div>\n<\/div>\n<p data-start=\"2541\" data-end=\"2655\">After signing up, access to the Webhook Relay dashboard is provided, where authentication tokens can be generated.<\/p>\n<h2 data-start=\"2662\" data-end=\"2695\">Authenticating the Relay Agent<\/h2>\n<p data-start=\"2697\" data-end=\"2778\">From the dashboard, create an access token. This generates a key and secret pair.<\/p>\n<p data-start=\"2780\" data-end=\"2834\">Use those credentials to authenticate the relay agent.<\/p>\n<div class=\"contain-inline-size rounded-2xl corner-superellipse\/1.1 relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl\/main:top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><code class=\"whitespace-pre!\"><span class=\"language-xml\">relay login \\<br \/>\n-k <\/span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">your_token_key<\/span><\/span>&gt; \\<br \/>\n-s <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">your_token_secret<\/span><\/span>&gt;<br \/>\n<\/code><\/div>\n<\/div>\n<p data-start=\"2908\" data-end=\"2982\">A successful login message confirms that the agent is connected and ready.<\/p>\n<h2 data-start=\"2989\" data-end=\"3022\">Creating the GitLab Repository<\/h2>\n<p data-start=\"3024\" data-end=\"3142\">Create a GitLab repository for testing webhook integration. To keep the setup simple, a public repository can be used.<\/p>\n<p data-start=\"3144\" data-end=\"3206\">For reference, assume the repository name is <code data-start=\"3189\" data-end=\"3205\">WebhookProject<\/code>.<\/p>\n<h2 data-start=\"3213\" data-end=\"3253\">Preparing Jenkins for GitLab Webhooks<\/h2>\n<p data-start=\"3255\" data-end=\"3316\">Install the required Jenkins plugins from the plugin manager.<\/p>\n<p data-start=\"3318\" data-end=\"3406\">Navigate through the Jenkins dashboard to install<br data-start=\"3367\" data-end=\"3370\" \/>GitLab Plugin<br data-start=\"3383\" data-end=\"3386\" \/>GitLab Hook Plugin<\/p>\n<p data-start=\"3408\" data-end=\"3483\">Once installed, Jenkins becomes capable of receiving GitLab webhook events.<\/p>\n<h2 data-start=\"3490\" data-end=\"3517\">Creating the Jenkins Job<\/h2>\n<p data-start=\"3519\" data-end=\"3608\">Create a new Jenkins job and configure it to pull source code from the GitLab repository.<\/p>\n<p data-start=\"3610\" data-end=\"3683\">Enable the option that allows Jenkins to be triggered by GitLab webhooks.<\/p>\n<p data-start=\"3685\" data-end=\"3807\">After enabling this option, Jenkins generates a webhook endpoint associated with the job. It usually follows this pattern.<\/p>\n<div class=\"contain-inline-size rounded-2xl corner-superellipse\/1.1 relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl\/main:top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><code class=\"whitespace-pre!\"><span class=\"language-xml\">http:\/\/<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">jenkins-host<\/span><\/span><\/span>&gt;:8080\/project\/<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">job-name<\/span><\/span>&gt;<br \/>\n<\/code><\/div>\n<\/div>\n<p data-start=\"3864\" data-end=\"3897\">Example shown for reference only.<\/p>\n<div class=\"contain-inline-size rounded-2xl corner-superellipse\/1.1 relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl\/main:top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><code class=\"whitespace-pre!\"><a href=\"#\">http:\/\/localhost:8080\/project\/webhook-gitlab-test<\/a><br \/>\n<\/code><\/div>\n<\/div>\n<p data-start=\"3958\" data-end=\"4029\">Copy this endpoint, as it will be used in the forwarding configuration.<\/p>\n<h2 data-start=\"4036\" data-end=\"4078\">Forwarding Webhooks Using Webhook Relay<\/h2>\n<p data-start=\"4080\" data-end=\"4198\">Start webhook forwarding by creating a relay bucket. This bucket acts as a routing channel between GitLab and Jenkins.<\/p>\n<div class=\"contain-inline-size rounded-2xl corner-superellipse\/1.1 relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl\/main:top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><code class=\"whitespace-pre!\"><span class=\"hljs-attribute\">relay<\/span> forward <span class=\"hljs-punctuation\">\\<br \/>\n<\/span>  --bucket gitlab-jenkins <span class=\"hljs-punctuation\">\\<br \/>\n<\/span>  http:\/\/&lt;jenkins-host&gt;:<span class=\"hljs-number\">8080<\/span>\/project\/&lt;job-name&gt;<br \/>\n<\/code><\/div>\n<\/div>\n<p data-start=\"4301\" data-end=\"4423\">Important note<br data-start=\"4315\" data-end=\"4318\" \/>Do not stop this process. Keep it running in the background.<br data-start=\"4378\" data-end=\"4381\" \/>Open a new terminal tab for further steps.<\/p>\n<p data-start=\"4425\" data-end=\"4501\">Once this command starts, the relay agent generates a public forwarding URL.<\/p>\n<h2 data-start=\"4508\" data-end=\"4537\">Configuring GitLab Webhook<\/h2>\n<p data-start=\"4539\" data-end=\"4627\">Open the GitLab repository settings and navigate to the integrations or webhook section.<\/p>\n<p data-start=\"4629\" data-end=\"4708\">Paste the forwarding URL generated by Webhook Relay into the webhook URL field.<\/p>\n<p data-start=\"4710\" data-end=\"4800\">For initial testing, SSL verification can be disabled to avoid certificate related issues.<\/p>\n<p data-start=\"4802\" data-end=\"4833\">Save the webhook configuration.<\/p>\n<h2 data-start=\"4840\" data-end=\"4866\">Testing the Integration<\/h2>\n<p data-start=\"4868\" data-end=\"4926\">Clone the GitLab repository locally and push a new commit.<\/p>\n<div class=\"contain-inline-size rounded-2xl corner-superellipse\/1.1 relative bg-token-sidebar-surface-primary\">\n<div class=\"sticky top-[calc(--spacing(9)+var(--header-height))] @w-xl\/main:top-9\">\n<div class=\"absolute end-0 bottom-0 flex h-9 items-center pe-2\">\n<div class=\"bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs\"><\/div>\n<\/div>\n<\/div>\n<div class=\"overflow-y-auto p-4\" dir=\"ltr\"><code class=\"whitespace-pre!\">git <span class=\"hljs-keyword\">add<\/span> .<br \/>\ngit <span class=\"hljs-keyword\">commit<\/span> <span class=\"hljs-operator\">-<\/span>m \"test webhook trigger\"<br \/>\ngit push origin main<br \/>\n<\/code><\/div>\n<\/div>\n<p data-start=\"5005\" data-end=\"5173\">As soon as the push is completed, GitLab sends a webhook event. Webhook Relay receives it and forwards it to the local agent, which triggers the Jenkins job internally.<\/p>\n<p data-start=\"5175\" data-end=\"5237\">You can verify this by checking the Jenkins job build history.<\/p>\n<h2 data-start=\"5244\" data-end=\"5259\">Viewing Logs<\/h2>\n<p data-start=\"5261\" data-end=\"5361\">GitLab webhook logs can be viewed from<br data-start=\"5299\" data-end=\"5302\" \/>Repository settings<br data-start=\"5321\" data-end=\"5324\" \/>Integrations<br data-start=\"5336\" data-end=\"5339\" \/>Webhook edit section<\/p>\n<p data-start=\"5363\" data-end=\"5453\">Webhook Relay logs are available in the Relay Logs section of the Webhook Relay dashboard.<\/p>\n<p data-start=\"5455\" data-end=\"5507\">Jenkins build logs confirm successful job execution.<\/p>\n<h2 data-start=\"5514\" data-end=\"5527\">Conclusion<\/h2>\n<p data-start=\"5529\" data-end=\"5757\">Webhook Relay makes it possible to trigger Jenkins builds through GitLab webhooks even when Jenkins is hosted inside a private network. This approach avoids exposing Jenkins publicly while still enabling real time CI automation.<\/p>\n<p data-start=\"5759\" data-end=\"5942\">The same pattern works for GitHub and other webhook enabled platforms. With proper configuration, secure and efficient CI workflows can be achieved in restricted network environments.<\/p>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Triggering Jenkins builds automatically after every code commit is a core requirement in any continuous integration setup. Jenkins supports automated triggers through repository polling or event based notifications. While polling works, it consumes resources and introduces delays. Push based triggering through webhooks is far more efficient. The difficulty appears when Jenkins is hosted inside &hellip; <a href=\"https:\/\/opstree.com\/blog\/2019\/03\/14\/can-you-integrate-a-github-webhook-with-privately-hosted-jenkins-no-think-again\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Can you integrate a GitHub Webhook with Privately hosted Jenkins No? Think again&#8221;<\/span><\/a><\/p>\n","protected":false},"author":159459904,"featured_media":29900,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[1],"tags":[44070,30871489,27998418,768739308,5603054,281597904,768739299,17852159,676319248],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2025\/11\/DevSecOps-1.jpg","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfDBOm-2b","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/135"}],"collection":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/users\/159459904"}],"replies":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/comments?post=135"}],"version-history":[{"count":7,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/135\/revisions"}],"predecessor-version":[{"id":30299,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/135\/revisions\/30299"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media\/29900"}],"wp:attachment":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media?parent=135"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=135"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=135"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}