0

I have created a Multistage dockerfile.

FROM dot-portal.de.pri.o2.com:8079/centos:centos7 as base

# Install a basic SSH server GIT, UNZIP, LSOF and JDK 8

ADD myrepo.repo /etc/yum.repos.d/myrepo.repo

RUN rm -rf /etc/yum.repos.d/CentOS*

COPY docker /opt/docker

RUN  yum repolist refresh && yum clean all && yum repolist && yum install -y openssh-server git unzip lsof epel-release bzip2 fontconfig && yum clean all && rm -rf /var/cache/yum && cd /opt/docker && rpm -ivh *.rpm && rm -rf /opt/docker

ADD docker-compose-Linux-x86_64 /usr/local/bin/docker-compose

RUN ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

# update sshd settings, create jenkins user, set jenkins user pw, generate ssh keys
RUN sed -i 's|session    required     pam_loginuid.so|session    optional     pam_loginuid.so|g' /etc/pam.d/sshd \
    && mkdir -p /var/run/sshd \
    && useradd -u 1000 -m -s /bin/bash jenkins \
    && echo "jenkins:jenkins" | chpasswd \
    && usermod -aG wheel jenkins \
    && /usr/bin/ssh-keygen -A \
    && sed -i "s/#UsePrivilegeSeparation.*/UsePrivilegeSeparation no/g" /etc/ssh/sshd_config \
    && sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config \
    && echo export JAVA_HOME="/`alternatives  --display java | grep best | cut -d "/" -f 2-6`" >> /etc/environment \
    && usermod -a -G docker jenkins \
        && sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd


RUN git config --global http.sslVerify false && mkdir -p /opt/app/jenkins

COPY --chown=jenkins:jenkins jenkins_tools /opt/app/jenkins/jenkins_tools/

ADD node-v10.13.0-linux-x64.tar.gz /opt/app/jenkins/jenkins_tools

ENV CI_TOOLS_HOME /opt/app/jenkins/jenkins_tools

ENV ARCH Linux-x86_64
ENV CI_TOOLS_HOME /opt/app/jenkins/jenkins_tools
ENV JAVA_HOME /usr/java/jdk1.8.0_241-amd64/

COPY dot-portal.de.pri.o2.com.crt $CI_TOOLS_HOME/dot-portal.de.pri.o2.com.crt
RUN cd $CI_TOOLS_HOME && echo yes | keytool -importcert -file dot-portal.de.pri.o2.com.crt -alias "dot-portal.de.pri.o2.com" -keystore "$JAVA_HOME/jre/lib/security/cacerts" -storepass changeit

COPY --chown=jenkins:jenkins authorized_keys /home/jenkins/.ssh/

RUN mkdir /root/.ssh && mkdir -p /opt/app/home/jenkins && chown -R jenkins:jenkins /opt/app/home/jenkins

COPY dockerslave /etc/default/docker

RUN ln -s $CI_TOOLS_HOME/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/bin/ && chown -R jenkins:jenkins /opt/app/jenkins/jenkins_tools

FROM base
COPY --from=base /opt/app/jenkins/jenkins_tools /opt/app/jenkins/jenkins_tools
COPY --from=base /etc/default/docker /etc/default/docker
COPY --from=base /usr/bin/phantomjs /usr/bin/phantomjs

ENV CI_TOOLS_HOME /opt/app/jenkins/jenkins_tools
ENV ARCH Linux-x86_64
ENV CI_TOOLS_HOME /opt/app/jenkins/jenkins_tools
ENV JAVA_HOME /usr/java/jdk1.8.0_241-amd64/
ENV MAVEN_HOME /opt/app/jenkins/jenkins_tools/nonarch/maven-3.3.9
RUN echo "export PATH=$CI_TOOLS_HOME/node-v10.13.0-linux-x64/bin/:$CI_TOOLS_HOME/phantomjs-2.1.1-linux-x86_64/bin/:$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH" >> ~/.bashrc

# Standard SSH port
EXPOSE 22

CMD ["/usr/sbin/sshd", "-D", "-e"]

My Question is, the package and user which I installed/created in the base Image wont be reflect in the Final Image. From Base only I'm creating final Image, but when I connect to the container, I'm unable to see the user "jenkins" created in base image and the packages also missing.

user2439278
  • 1,222
  • 7
  • 41
  • 75
  • As I see final image does not contain any instructions on creating users. Why you would like to expect to have user jenkins in final image? – GintsGints Apr 07 '20 at 09:24

1 Answers1

0

What are you trying to achieve with a multistage docker build here? If your second stage starts from the result of first stage in a build with two stages, you might as well have only one stage...

Usually multi stage builds are used because one uses the first stage (e.g. "builder") to build some artefact which requires a lot of development tools. In the second stage only that artefact will be copied into a small base image to get a final image which is very small as it does not contain the tooling needed for building the artefact.

Example from the docker docs:

FROM golang:1.7.3 as builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html  
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]  

In Your case I am pretty sure that your final image does contain the jenkins user, because your second stage is started from the base stage. However these copy commands which copy from the base image will reset the permissions to root in your second stage:

COPY --from=base /opt/app/jenkins/jenkins_tools /opt/app/jenkins/jenkins_tools
COPY --from=base /etc/default/docker /etc/default/docker
COPY --from=base /usr/bin/phantomjs /usr/bin/phantomjs

This copy commands are redundant as you start FROM base anyways. If you'd remove these lines the jenkins_tools directory will be correctly owned by the jenkins user.

Note that you can change the user which is used to execute commands during the docker build with USER <username>

Leo
  • 1,702
  • 13
  • 15
  • If I remove the COPY lines, will my docker image size will be reduced? Now the Jenkins SSH slave docker image size is 2.5GB – user2439278 Apr 07 '20 at 12:23
  • Yes, it will be smaller. In this case I would probably remove the `FROM base` line too, it is unnecessary for this image. – Leo Apr 07 '20 at 15:18
  • If i remove the FROM base line , it creates a image of size 2GB – user2439278 Apr 08 '20 at 09:02
  • I want to reduce the size of the image – user2439278 Apr 08 '20 at 09:02
  • did you remove the three copy lines? Also it seems like you are copying a bunch of tools into the container, do you really need all of them? What is this line `COPY docker /opt/docker` supposed to do? You do not need you docker engine inside the image for docker in docker, only the cli – Leo Apr 08 '20 at 11:09
  • I need the docker to available inside the container and tools is required for the build in slave machine – user2439278 Apr 08 '20 at 11:31
  • You can only have a single docker engine running per kernel. For docker in docker you should install only the docker-cli and docker-compose and mount the docker socket into the container which should be able to use docker. – Leo Apr 08 '20 at 13:52