How to use Jenkins docker image to run Jenkins master

How to use Jenkins docker image as a master and as a build node.
In the recent past, Containerization is becoming very popular. Docker is a very prominent player in the field of containerization.
Today I am going to show step by step procedure on how to use a docker image for both Jenkins master and node. Also, I am going to address a few known issues and how to find a workaround for them. In the tutorial, I will use the Jenkins version jenkins/jenkins:2.107.3.
Pull the image from docker hub
$ docker pull jenkins/Jenkins:2.107.3
Note that the dockerized Jenkins will use /var/jenkins_home as Jenkins home. If you want to change this you have to edit the docker file provided by the docker hub, which was used to build the image jenkins/jenkins:2.107.3. I will not cover that in the tutorial.
The additional steps we are doing on top of the base image Jenkins/jenkins:2.107.3
1.     Customize the Jenkins docker image with additional packages and new users
2.     Use different user other than the default jenkins user.
3.     Use a different home directory for a different user but use the same jenkins_home folder
4.     Use a host-volume to map to Jenkins_home inside the container
5.     Use the host machine ssh keys on the container as also
Let us see one by one and what are the issues we have.
In most cases you will not want to use the default user called Jenkins, you need to use the user which is specific to your organization or company. I will call the new user as user_jenkins, this user is already present in my host machine and it needs to be created in the new image.
Below docker file will add the new user, declares 2 arguments for ssh private and public key, copy the plugins.txt file and install them, finally copies the necessary ssh keys from host to the container.  

from jenkins/jenkins:2.107.3
ARG priv
ARG pub
USER root

COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt

# Add user user_jenkins using static UID/GID from AD, home /var/lib/jenkins, adequate shell
RUN groupadd -g 215 group_jenkins && \
    useradd -u 1396 -g group_jenkins -d /var/jenkins_home_tmp -s /bin/bash -m user_jenkins

USER user_jenkins

# insert ssh keys
RUN mkdir -p ~/.ssh && \
    echo "$priv" > ~/.ssh/id_rsa && \
    echo "$pub" > ~/.ssh/id_rsa.pub && \
    chmod 644 ~/.ssh/id_rsa.pub && chmod 600 ~/.ssh/id_rsa && chmod 700 ~/.ssh 

Now try to build the docker image using docker build command. We need to keep the plugins.txt in the build context and ssh keys to be passed as a build parameter. 

The format of the plugins.txt file should as below 

mask-passwords:2.8
workflow-step-api:2.2
external-monitor-job:1.4
accelerated-build-now-plugin:1.0.1
pam-auth:1.1
ssh-credentials:1.10
plot:1.11
configurationslicing:1.47
active-directory:2.2
git-parameter:0.6.1
disk-usage:0.28
structs:1.2
envinject:1.92.1
release:2.5.4
custom-tools-plugin:0.4.4
coverity:1.7.1
elastic-axis:1.2
run-condition:1.0
slave-status:1.6
groovy-label-assignment:1.2.0
matrix-project:1.4.1
scm-api:1.2
warnings:4.56
docker-plugin:0.16.2
ssh-agent:1.13
maven-plugin:2.7.1
periodic-reincarnation:1.10
icon-shim:2.0.3
docker-slaves:1.0.6
mapdb-api:1.0.9.0
throttle-concurrents:1.9.0
analysis-core:1.79
jquery:1.11.2-0
slave-setup:1.10
subversion:1.54
postbuild-task:1.8
artifactdeployer:0.33
timestamper:1.8.8
gerrit-trigger:2.21.1
bouncycastle-api:1.648.3
translation:1.10
monitoring:1.59.0
credentials:2.1.13
javadoc:1.1
build-name-setter:1.6.5
antisamy-markup-formatter:1.1
PrioritySorter:3.4
extended-choice-parameter:0.74
workflow-scm-step:2.2
cvs:2.11
authentication-tokens:1.3
ldap:1.11
unreliable-slave-plugin:1.2
description-setter:1.10
parameterized-trigger:2.31
project-stats-plugin:0.4
token-macro:1.12.1
ant:1.2
script-security:1.29
leastload:1.0.3
junit:1.2-beta-4
ssh-slaves:1.9
repo:1.10.2
email-ext:2.44
purge-build-queue-plugin:1.0
git:2.5.2
matrix-auth:1.1
keepSlaveOffline:1.0
preSCMbuildstep:0.3
mailer:1.11
docker-commons:1.6
conditional-buildstep:1.3.5
jobConfigHistory:2.16
dashboard-view:2.9.10
durable-task:1.13
git-client:1.19.7

build-failure-analyzer:1.16.0

Passing ssh keys to the image during the build time is necessary for various reasons. One such reason is to clone from git or Github, which requires ssh keys to connect to the servers. Copying ssh keys is also tricky because we are copying both private and public keys. Earlier I used to keep the ssh keys in a plain text inside the docker file. But that is very dangerous. Now I am trying to pass them as a build parameter. The only concern with the approach is that the keys are available in the docker layer. There is an experimental option available in the docker engine to squash the layers so the layers are which are exposing the security information, can be merged into other layers. This can be achieved using –squash option in the docker build command.
The docker build command
$ docker build --build-arg priv="$(cat ~/.ssh/id_rsa)" --build-arg pub="$(cat ~/.ssh/id_rsa.pub)" -t jenkins_2 --no-cache  -f docker .
The key thing to be noted here is the --build-arg parameters. I am reading the existing ssh keys from the host machine and passing them as a parameter. Note that here 2 separate –-build-arg parameters one each for the private key and public key. The parameters are handled by ARG instruction in the docker file
Once the image is built successfully we can start the container.
Run command
$ docker run -d  -p 8082:8080  -p 5002:5000  jenkins_2
I am using different ports. You will get the error message as shown below or similar.  

17:46:34 root dev ~ → docker logs 4s6yuknv568
touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied
Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?
Note that the ‘/var/jenkins_home/’ is the default home directory from where the Jenkins runs. If you are using a user other than default user Jenkins, you will get permission denied error.
To overcome this error there should be a proper folder created before running the container. The new folder created will be mapped as host volume as in the below command.  
$ su user_jenkins
$ mkdir -p /opt/my_jenkins_home
$ docker run -d  -p 8082:8080  -p 5002:5000 -v /opt/my_jenkins_home:/var/jenkins_home  jenkins_2

Why some mobile phones does not support screen mirroring?

On my Youtube channel, I have posted a video that shows how to mirror your mobile screen onto LED or LCD TV which is equipped with Wi-Fi and Miracast. To clarify what is Miracast, it is a hardware device built into your TV. If your TV is equipped with Miracast, then you don't have to use any additional dongles like Google ChromeCast to cast your mobile screen onto the TV. Please note that the Miracast feature and Google Chromecast may work differently.

I got lots of comments asking questions like whether the TV is smart, whether the TV is used as a monitor with a CPU, is there any dongle connected to the TV, whether it requires internet, etc.  To clarify all these questions, it is a basic LED TV with Wi-FI and Miracst enabled. No internet, no dongle connected and it is not a smart TV.

The most important question I am trying to clarify here is why some mobile phones do not have mirroring options.

First, you need to understand that screen mirroring works on a Wi-Fi network.  That means there will be a Wi-Fi network set up between your mobile phone and your TV. There is no intermediate Wi-Fi router. There will be an active connection between your phone and TV. This will not allow you to connect to any other Wi-Fi network for the internet. You have to completely rely on your carrier provided mobile data. It may incur a lot of data usage. So, some mobile manufacturers disabled this option from the design itself. This is the case with single-band Wi-Fi-enabled mobiles.

But the newer mobile phones from different manufacturers support dual-band Wi-Fi.  That means simultaneously you can connect to the TV and to another WI-Fi network for the internet. You do not have to rely on your mobile data. Most of the MI Redmi phone supports the dual-band Wi-Fi and they support screen mirroring out of the box.

The solution for those who do not have a screen mirroring option is to use apps or third-party mirroring devices like Google Chrome cast, Miracast, or even Amazon stick. You can also use specific MHL cables which are similar to HDMI cable. Each app may work differently and some apps may require root mobile phones.





How to install Apps in Android TV

As Android TVs are becoming famous, it's obvious to know whether it will allow us to install apps on Android TV the way we do it on Android mobile and to know how to install the apps on TV. The same version of a particular app may not support all the TVs and you might not get all the apps available for Mobile. But certainly, there are plenty of apps for various purpose and it can be installed on Android TV.

There are two ways to install an app on Android TV. Please note that this procedure is specific to MI Android TV. A similar procedure can be used for other Android TV.

Install using .apk file

The first option is to install it from a .apk file. The apk file has to be downloaded and copied into a USB using a computer. Insert the USB drive into TV, go to the location of the apk file inside the USB drive. Open the selected apk file, it will ask you to enable or trust the 'third party app' installation. If you have not done this before, got to settings and enable it. Please note that it may be a security violation if you install it from an unauthorized source. Before installing an app from an unknown source, understand the consequences, and proceed. 

Install using an App Store

The second option is to install from Android TV-specific App Store. The App Store has to be installed using the first method - apk installation from USB.

There is one App store called AptoideTV. It has all the major apps which are more than enough to get all the required apps for your Smart TV 

AptoideTV

Download the apk for AptoideTV-3.2.5.apk from the below link. Copy it into a USB drive and insert it into your TV. Browse to the location, where the apk is present and click on the apk file. It will ask you to enable the Third-Party App installation.


Once the App Store is installed, you can use it like any other App Store. Browse or search for an app from different categories and install. 

Check out this video which shows how to install the Chrome App on 32 inch MI TV