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:
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.
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!
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.
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:" 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
-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.
/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.
/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.
-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.-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 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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With