How to install and run a dockerized Jenkins CI with webhook support
Jenkins is an extremely popular automation server that can run tests, build and publish software, or perform pretty much any other user-defined action. Docker, on the other hand, is quite a focused tool; it’s used to package software into containers and run them. This makes Jenkins and Docker a good pair when testing, shipping and deploying things.
In this tutorial, you’ll see how easy it is to install and run a modern, all-in-one dockerized Jenkins with Synpse which provides:
- Rock-solid deployment with persistent storage
- Webhook delivery to the server to trigger build jobs without public IP or domain
- Secure remote SSH access to the server without exposing it to the internet
We will split this article into several sections - installation, administration, and webhook configuration. Let’s get started.
Prerequisites
Webhook Relay and Synpse have paid tiers with increased quotas and support plans; however a free tier should be enough for setting this up.
- Webhook Relay account - free tier should be enough for setting up homelab or testing
- Synpse account - remote device management, free up to 5 devices (definitely enough for Jenkins!)
- Linux server, ideally Ubuntu, however other distros should work as well
- Docker - installed on the server
Installation
First, install the Synpse agent on your server. You can view installation instructions here https://docs.synpse.net/agent/install/linux-docker. This will provide us with lightweight deployment capabilities. Once installed, add the label type: controller
to that device in your Synpse dashboard.
Next, let’s create an application that will run on the server:
name: jenkins
description: CI/CD server
scheduling:
type: Conditional
selectors:
type: controller
spec:
containers:
- name: jenkins
image: jenkins/jenkins:lts
user: root
privileged: true
ports:
- 8080:8080
- 50000:50000
volumes: # Persistent volumes
- /data/jenkins-compose:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
This will download the image and start the container. Once it shows up as ready, open the http://device-ip:8080
address. You will then require an initial admin password, found through Synpse inbuilt web SSH terminal:
Enter your initial admin password and proceed with the plugin installation:
You should also setup Jenkins agents to do the heavy work as they can just be additional containers either in the same application spec or separate applications that Jenkins server connects to but we will explore that route in a separate blog post.
Webhooks Without Public IP or Domain
It’s important to be able to receive webhooks without exposing our Jenkins server to the internet. For this, we will need to deploy a container next to the Jenkins server which will help with request forwarding.
Let’s start by getting the tokens from https://my.webhookrelay.com/tokens and creating two secrets in Synpse named webhookrelayKey and webhookrelaySecret that contain your authentication tokens. Then, go to https://my.webhookrelay.com/buckets page and create a bucket named jenkins. Now, we can add the new container to the Jenkins server app:
name: jenkins
description: CI/CD server
scheduling:
type: Conditional
selectors:
type: controller
spec:
containers:
- name: jenkins
image: jenkins/jenkins:lts
user: root
privileged: true
ports:
- 8080:8080
- 50000:50000
volumes: # Persistent volumes
- /data/jenkins-compose:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
# Webhook Relay forwarding container. This container allows
# us to receive the webhooks that are hitting public server endpoints
- name: webhookrelay
image: webhookrelay/webhookrelayd:latest
env:
- name: RELAY_KEY
fromSecret: webhookrelayKey
- name: RELAY_SECRET
fromSecret: webhookrelaySecret
- name: BUCKETS
value: jenkins
Click save and after a few seconds we should see two containers running:
Configuring Jenkins Plugin
The easiest way to start receiving GitHub webhooks is by using this plugin https://plugins.jenkins.io/github. To install:
- Go to your Jenkins plugin manager
- Find and install “GitHub plugin” (at the time of writing - current version was 1.27.0)
- Once it installed, we will need to configure it:
Add default GitHub server (don’t bother adding credentials as we are using public repo anyway):
Configuring Jenkins Job
When you want Jenkins to do something - create a job. In this case, we will be using Freestyle project:
We have to configure several sections here - Source Code Management and Build Triggers. First, set repository (in this case it’s my demo app repo repository):
Next step is setting a build trigger to GitHub hook trigger for GITScm polling:
This means that once the Jenkins receives a webhook, it can identify which repo is changed and thus triggers a pull and job execution.
Configure Webhook Relay Bucket
Once things are running, go back to your bucket details in Webhook Relay and add Jenkins container as the destination. It should be:
- Name:
jenkins
- Destination
http://jenkins:8080/github-webhook/
- Type:
internal
Port always needs to match the port on which the application is running in a container. For example, if you do a mapping of 8888:8080 for Jenkins server, destination should still be on port 8080 as that is what’s available internally.
Configure GitHub
Go to your repository settings and add the input endpoint URL from your Webhook Relay bucket:
Push to Build!
Once you push to your repository, you should see few things:
- In Webhook Relay dashboard a new webhook received and forwarded
- A new build in Jenkins dashboard
Let’s wrap up
In this tutorial, we deployed the main Jenkins server as a Docker container with persistent volumes. We also configured GitHub webhooks to trigger builds without us requiring to have a public IP or configure firewalls.
In our upcoming blog post, we will explore ways of connecting more agents to the server.