Setup secured Jenkins master with docker
Like otognan, I would also recommend doing #2, but it seems that his answer is outdated.
First of all, use the jenkins/jenkins:lts
image, as the jenkins
image is deprecated (see https://hub.docker.com/_/jenkins/ )
Now, lets set it up. You'll need to stop your current jenkins container to free up the ports.
First, you'll need a certificate keystore. If you don't have one, you could create a self-signed one with
keytool -genkey -keyalg RSA -alias selfsigned -keystore jenkins_keystore.jks -storepass mypassword -keysize 4096
Next, let's pass the SSL arguments into the jenkins container. This is the script I use to do so:
read -s -p "Keystore Password:" password
echo
sudo cp jenkins_keystore.jks /var/lib/docker/volumes/jenkins_home/_data
docker run -d -v jenkins_home:/var/jenkins_home -v $(which docker):/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock -p 443:8443 -p 50000:50000 jenkins/jenkins:lts --httpPort=-1 --httpsPort=8443 --httpsKeyStore=/var/jenkins_home/jenkins_keystore.jks --httpsKeyStorePassword=$password
- this script prompts the user for the keystore password
-v jenkins_home:/var/jenkins_home
creates a named volume calledjenkins_home
, which happens to exist at/var/lib/docker/volumes/jenkins_home/_data
by convention.- if the directory at
/var/lib/docker/volumes/jenkins_home/_data
does not exist yet, you will need to create the named volume usingdocker volume
before copying the keystore.
- if the directory at
-p 443:8443
maps 8443 jenkins port in the container to the 443 port of the host--httpPort=-1 --httpsPort=8443
blocks http and exposes https on port 8443 inside the container (port 443 outside the container).--httpsKeyStore=/var/jenkins_home/jenkins_keystore.jks --httpsKeyStorePassword=$password
provides your keystore, which exists at/var/jenkins_home/jenkins_keystore.jks
inside the container (/var/lib/docker/volumes/jenkins_home/_data/jenkins_keystore.jks
outside the container).-v /var/run/docker.sock:/var/run/docker.sock
is optional, but is the recommended way to allow your jenkins instance to spin up other docker containers.- WARNING: By giving the container access to
/var/run/docker.sock
, it is easy to break out of the containment provided by the container, and gain access to the host machine. This is obviously a potential security risk.
- WARNING: By giving the container access to
-v $(which docker):/usr/bin/docker
is also optional, but allows your jenkins container to be able to run the docker binary.- Be aware that, because docker is now dynamically linked, it no longer comes with dependencies, so you may be required to install dependencies in the container.
- The alternative is to omit
-v $(which docker):/usr/bin/docker
and install docker within the jenkins container. You'll need to ensure that the inner container docker and the outer host docker are the same version, so that communication over/var/run/docker.sock
is supported. - In either case, you may want to use a Dockerfile to create a new Jenkins docker image.
- Another alternative is to include
-v $(which docker):/usr/bin/docker
, but install a statically-linked binary of docker on the host machine.
You should now be able to access the jenkins webportal via https with no port specifier (since port 443 is default for https)
Thanks to otognan for getting me part of the way here.
After passing few tutorials on Docker I found that the easiest option to follow is number 2. Jenkins docker image declares the entry point in a way that you can easily pass arguments to the jenkins.
Lets say you have your keystore (e.g. self-signed in this example) as jenkins_keystore.jks in the home folder of ubuntu ec2 instance. Here is the example how to generate one:
keytool -genkey -keyalg RSA -alias selfsigned -keystore jenkins_keystore.jks -storepass mypassword -keysize 2048
Now you can easily configure jenkins to run on https only without creating your own docker image:
docker run -v /home/ubuntu:/var/jenkins_home -p 443:8443 jenkins --httpPort=-1 --httpsPort=8443 --httpsKeyStore=/var/jenkins_home/jenkins_keystore.jks --httpsKeyStorePassword=mypassword
-v /home/ubuntu:/var/jenkins_home
exposes the host home folder to the jenkins docker container-p 443:8443
maps 8443 jenkins port in the container to the 443 port of the host--httpPort=-1 --httpsPort=8443
blocks jenkins http and exposes it with https on port 8443 inside the container--httpsKeyStore=/var/jenkins_home/jenkins_keystore.jks --httpsKeyStorePassword=mypassword
provides your keystore that has been mapped from the host home folder to the container/var/jenkins_home/
folder.
I know this is a very old topic but I wanted to share a blog post which covers reverse proxy option in detail: https://itnext.io/setting-up-https-for-jenkins-with-nginx-everything-in-docker-4a118dc29127
Jenkins suggests to setup reverse proxy in documents. It may seem like an extra effort in the first place but it is a general solution for other services related with CI/CD environment as well (i.e. SonarQube).