Setup secured Jenkins master with docker Setup secured Jenkins master with docker jenkins jenkins

Setup secured Jenkins master with docker


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.


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:" passwordechosudo cp jenkins_keystore.jks /var/lib/docker/volumes/jenkins_home/_datadocker 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 called jenkins_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 using docker volume before copying the keystore.
  • -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.
  • -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.


I would use nginx together with jenkins in the same container, and use supervisord to manage both processes. Securing different services with builtin tools is a pain; nginx works the same for all services, and is easy to configure. It is possible, and nicer in some ways, to use docker-compose (was fig) to create two different containers and hook them up with the pretty internal networking that docker provides with links. The problem is that running pairs of jobs together is still not well supported in cluster managers like marathon. It's far easier to tell most services to run a single container, rather than to run two containers, but make sure they're on the same host.