Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setup secured Jenkins master with docker

I would like to set up a secured Jenkins master server on ec2 with docker. I'm using standard jenkins docker file from here: https://registry.hub.docker.com/_/jenkins/

By default it opens an unsecured 8080 http port. However I want it to use a standard 443 port with https (at first I want to use self-signed ssl certificate).

I researched in this topic a little bit and found several possible solution. I'm not really experienced with docker so I still couldn't find a simple one I can use or implement. Here are some options I found:

  • Use standard jenkins docker on 8080 but configure a secured apache or nginx server on my ec2 instance that will redirect the trafic. I don't like this because the server will be outside the docker so I can not keep it in the version control
  • Somehow modify the jenkins docker file to start jenkins with a https configured according to https://wiki.jenkins-ci.org/display/JENKINS/Starting+and+Accessing+Jenkins. I'm not sure how to do that though. Do I need to create my own docker container?
  • use docker file with secured nginx like this one https://registry.hub.docker.com/u/marvambass/nginx-ssl-secure/ and somehow combine two docker containers or make them communicate? Not sure how to that either.

Could someone experienced please recommend me the best solution?

P.S. I'm not sure how much troubles ec2 is going to give me but I assume its just about opening 443 in a security group.

like image 395
otognan Avatar asked Apr 20 '15 17:04

otognan


People also ask

Can we use Jenkins and Docker together?

Scaling Jenkins and Docker with KubernetesCombining Jenkins and Docker together can bring improved speed and consistency to your automation tasks, which is why we've collected some helpful resources on this page to get you started!

How do I set Docker credentials in Jenkins?

In Jenkins you have to add a new credential with your Docker Hub account details. Go to Credentials → Global → Add credentials and fill out the form with your username and password. Create your Jenkins pipeline.


3 Answers

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 image 195
otognan Avatar answered Sep 29 '22 07:09

otognan


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 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.

like image 42
cowlinator Avatar answered Sep 29 '22 05:09

cowlinator


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).

like image 29
beserb Avatar answered Sep 29 '22 05:09

beserb