In the previous post, Site Build Part One - Docker and NGINX,
we created the Ansible roles to install Docker and NGINX on the server. Next up
we’ll get Jenkins up and running inside a Docker container.
Goals
Start a Docker container running Jenkins with Ansible installed
Mount volumes for persisting the Jenkins application data
Create a virtual host that proxies external traffic to the Jenkins container
Secure virtual host traffic with letencrypt
Containerized Jenkins
First we create an Ansible play for our Jenkins instance. I’ll be running this
on the same server as the site to keep my hosting costs to a minimum. The play
is similar to the common play. It targets inventory tagged jenkins and adds a
new role pmclain.JENKINS.
jenkins.yml
Base Jenkins Role
This role has a few variables we’ll want to define.
roles/pmclain.JENKINS/defaults/main.yml
Now comes time for creating the base of our Anisble role. Here we have enough
for starting Jenkins in a container, persisting data on the host.
SECURITY IMPLICATIONS OF THE VOLUME MOUNTS BELOW
I plan on using the Jenkins Docker plugin for some pipelines later on. For my
own ease of use I’m giving the container access to the host Docker dameon. I
would not recommend doing this on a production server as it gives the guest
container access to ALL containers running on the host.
roles/pmclain.JENKINS/tasks/main.yml
Allowing External Traffic to Jenkins via HTTPS
Executing the role above will allow local access to Jenkins from our server.
I wanted to experiment with proxying requests to the running containing using a
public domain.
Going back to the role’s main task we’ll prepend addition tasks for:
Generating an SSL certificate for the public domain with letsencrypt
Configure a virtual host proxying traffic to the Jenkins container
I had initially installed certbot through yum and it borked the pip packages
Ansible needed for interacting with Docker. After fumbling around with pip
environments for a few minutes, I gave up and decided on generating the certs
with the letencrypt official Docker image. This is not ideal since it requires
we stop NGINX for binding the container to port 80.
roles/pmclain.JENKINS/tasks/main.yml
Below is the template for the NGINX virtual host. All it does is proxy inbound
traffic from the public domain to the Jenkins container.