Unknown Instruction : Sudo , when i try to build the docker image - docker

When I try to build the below docker file , i get the error "Error response from daemon: Dockerfile parse error line 12: unknown instruction: SUDO"
FROM jenkins
USER root
RUN apt-get -qqy update; apt-get install -qqy sudo
RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers
RUN wget http://get.docker.com/builds/Linux/x86_64/docker-latest.tgz
RUN tar -xvzf docker-latest.tgz
RUN mv docker/* /usr/bin/
USER jenkins
RUN /usr/local/bin/install-plugins.sh junit git git-client ssh-slaves greenballs chucknorris ws-cleanup
sudo mkdir -p /var/jenkins_home
cd /var/jenkins_home
sudo chown -R 1000 /var/jenkins_home

Below commands doesn't belong to Dockerfile syntax
sudo mkdir -p /var/jenkins_home
cd /var/jenkins_home
sudo chown -R 1000 /var/jenkins_home
Add the RUN infront of them if you wants to run them. But the good practice is to mount folder from local to container. If you are tying to map the jenkins home folder, then create /var/jenkins_home folder on local system & then mount to docker container with -v option.
You can follow given link for using docker in dockerized jenkins: https://medium.com/#manav503/how-to-build-docker-images-inside-a-jenkins-container-d59944102f30

Related

Copy a file from local to docker container via a shell script

I have the following folder structure
db
- build.sh
- Dockerfile
- file.txt
build.sh
PGUID=$(id -u postgres)
PGGID=$(id -g postgres)
CS=$(lsb_release -cs)
docker build --build-arg POSTGRES_UID=${PGUID} --build-arg POSTGRES_GID=${PGGID} --build-arg LSB_CS=${CS} -t postgres:1.0 .
docker run -d postgres:1.0 sh -c "cp file.txt ./file.txt"
Dockerfile
FROM ubuntu:19.10
RUN apt-get update
ARG LSB_CS=$LSB_CS
RUN echo "lsb_release: ${LSB_CS}"
RUN apt-get install -y sudo \
&& sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt eoan-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
RUN apt-get install -y wget \
&& apt-get install -y gnupg \
&& wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | \
sudo apt-key add -
RUN apt-get update
RUN apt-get install tzdata -y
ARG POSTGRES_GID=128
RUN groupadd -g $POSTGRES_GID postgres
ARG POSTGRES_UID=122
RUN useradd -r -g postgres -u $POSTGRES_UID postgres
RUN apt-get update && apt-get install -y postgresql-10
RUN locale-gen en_US.UTF-8
RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/10/main/pg_hba.conf
RUN echo "listen_addresses='*'" >> /etc/postgresql/10/main/postgresql.conf
EXPOSE 5432
CMD ["pg_ctlcluster", "--foreground", "10", "main", "start"]
file.txt
"Hello Hello"
Basically i want to be able to build my image, start my container and copy file.txt in my local to the docker container.
I tried doing it like this docker run -d postgres:1.0 sh -c "cp file.txt ./file.txt" but it doesn't work. I have also tried other options as well but also not working.
At the moment when i run my script sh build.sh, it runs everything and even starts a container but doesn't copy over that file to the container.
Any help on this is appreciated
Sounds like what you want is a mounting the file into a location of your docker container.
You can mount a local directory into your container and access it from the inside:
mkdir /some/dirname
copy filet.txt /some/dirname/
# run as demon, mount /some/dirname to /directory/in/container, run sh
docker run -d -v /some/dirname:/directory/in/container postgres:1.0 sh
Minimal working example:
On windows host:
d:\>mkdir d:\temp
d:\>mkdir d:\temp\docker
d:\>mkdir d:\temp\docker\dir
d:\>echo "SomeDataInFile" > d:\temp\docker\dir\file.txt
# mount one local file to root in docker container, renaming it in the process
d:\>docker run -it -v d:\temp\docker\dir\file.txt:/other_file.txt alpine
In docker container:
/ # ls
bin etc lib mnt other_file.txt root sbin sys usr
dev home media opt proc run srv tmp var
/ # cat other_file.txt
"SomeDataInFile"
/ # echo 32 >> other_file.txt
/ # cat other_file.txt
"SomeDataInFile"
32
/ # exit
this will mount the (outside) directory/file as folder/file inside your container. If you specify a directory/file inside your docker that already exists it will be shadowed.
Back on windows host:
d:\>more d:\temp\docker\dir\file.txt
"SomeDataInFile"
32
See f.e Docker volumes vs mount bind - Use cases on Serverfault for more info about ways to bind mount or use volumes.

Permissions in Docker volume

I am struggling with permissions on docker volume, I get access denied for writing.
This is a small part of my docker file
FROM ubuntu:18.04
RUN apt-get update && \
apt-get install -y \
apt-transport-https \
build-essential \
ca-certificates \
curl \
vim && \............
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && apt-get install -y nodejs
# Add non-root user
ARG USER=user01
RUN useradd -Um -d /home/$USER -s /bin/bash $USER && \
apt install -y python3-pip && \
pip3 install qrcode[pil]
#Copy that startup.sh into the scripts folder
COPY /scripts/startup.sh /scripts/startup.sh
#Making the startup.sh executable
RUN chmod -v +x /scripts/startup.sh
#Copy node API files
COPY --chown=user1 /node_api/* /home/user1/
USER $USER
WORKDIR /home/$USER
# Expose needed ports
EXPOSE 3000
VOLUME /data_storage
ENTRYPOINT [ "/scripts/startup.sh" ]
Also a small part of my startup.sh
#!/bin/bash
/usr/share/lib/provision.py --enterprise-seed $ENTERPRISE_SEED > config.json
Then my docker builds command:
sudo docker build -t mycontainer .
And the docker run command:
sudo docker run -v data_storage:/home/user01/.client -p 3008:3000 -itd mycontainer
The problem I have is that the Python script will create the folder: /home/user01/.client and it will copy some files in there. That always worked fine. But now I want those files, which are data files, in a volume for backup porpuses. And as I am mapping with my volume I get permissions denied, so the python script is not able to write anymore.
So at the end of my dockerfile this instructions combined with the mapping in the docker run command give me the permission denied:
VOLUME /data_storage
Any suggestions on how to resolve this? some more permissions needed for the "user01"?
Thanks
I was able to resolve my issue by removing the "volume" command from the dockerfile and just doing the mapping at the moment of executing the docker run:
sudo docker run -v data_storage:/home/user01/.client -p 3008:3000 -itd mycontainer

How to access docker daemon from container with other user than root

I'm trying to run a Jenkins container that builds docker images. I've started last week with docker and I'm a bit confused with the use of volumes from host and how users are handled.
I've been searching on internet and I've found a git issue were someone posted a solution to have access to the docker daemon from the container. Basically, the idea is to mound inside the Jenkins container the volumes that contain the docker bin folder and the docker.sock from the host like this:
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /usr/local/bin/docker:/usr/local/bin/docker
I've done that and it works but only if I'm root. When I started to learn docker, I followed the example in a blog where, instead of directly using a jenkins image, the author copied the Dockerfiles from the jenkins image itself and its dependencies to explain the process. As part of the process, a jenkins user is created and it is the one in used when starting the container. My problem now is that I cannot make the jenkins user have access to the docker.sock mounted as it belongs to root and the group docker in the host. I tried adding the user docker in the Dockerfile but I still get a permission denied error from a Jenkins job when accessing the docker.sock. If I inspect the mounted /var/run/docker.sock inside the container I can see that docker.sock belongs to group user instead of docker so I don't know exactly what's going on when the directory is mounted. I haven't worked much with Linux so my guess is that the user docker doesn't exist when the directory is mounted and that it then uses a default user but I may probably be completely wrong.
Another thing I still don't get is, if I create a container specifically to be used as a Jenkins container and nothing else is supposed to be run there, what's the purpose of creating a specific jenkins user? Is there any reason why I cannot use directly the user root?
This is the Dockerfile I use. Thanks.
FROM centos:7
# Yum workaround to stalled mirror
RUN sed -i -e 's/enabled=1/enabled=0/g' /etc/yum/pluginconf.d/fastestmirror.conf
RUN rm -f /var/lib/rpm/__*
RUN rpm --rebuilddb -v -v
RUN yum clean all
# see https://bugs.debian.org/775775
# and https://github.com/docker-library/java/issues/19#issuecomment-70546872
ENV CA_CERTIFICATES_JAVA_VERSION 20140324
RUN yum -v install -y \
wget \
zip \
which \
openssh-client \
unzip \
java-1.8.0-openjdk-devel \
git \
&& yum clean all
#RUN /var/lib/dpkg/info/ca-certificates-java.postinst configure
# Install Tini
ENV TINI_VERSION 0.9.0
ENV TINI_SHA fa23d1e20732501c3bb8eeeca423c89ac80ed452
# Use tini as subreaper in Docker container to adopt zombie processes
RUN curl -fsSL https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini-static -o /bin/tini && chmod +x /bin/tini \
&& echo "$TINI_SHA /bin/tini" | sha1sum -c -
# SET Jenkins Environment Variables
ENV JENKINS_HOME /var/jenkins_home
ENV JENKINS_SLAVE_AGENT_PORT 50000
ENV JENKINS_VERSION 2.22
ENV JENKINS_SHA 5b89b6967e7af8119c52c7e86223b47665417a22
ENV JENKINS_UC https://updates.jenkins-ci.org
ENV COPY_REFERENCE_FILE_LOG $JENKINS_HOME/copy_reference_file.log
# SET Java variables
ENV JAVA_HOME /usr/lib/jvm/java/jre
ENV PATH /usr/lib/jvm/java/bin:$PATH
# Jenkins is run with user `jenkins`, uid = 1000
# If you bind mount a volume from the host or a data container,
# ensure you use the same uid
RUN useradd -d "$JENKINS_HOME" -u 1000 -m -s /bin/bash jenkins
#Not working. Folder not yet mounted?
#RUN DOCKER_GID=$(stat -c '%g' /var/run/docker.sock) && \
#Using gid from host
RUN groupadd -for -g 50 docker && \
usermod -aG docker jenkins
# Jenkins home directory is a volume, so configuration and build history
# can be persisted and survive image upgrades
VOLUME /var/jenkins_home
# `/usr/share/jenkins/ref/` contains all reference configuration we want
# to set on a fresh new installation. Use it to bundle additional plugins
# or config file with your custom jenkins Docker image.
RUN mkdir -p /usr/share/jenkins/ref/init.groovy.d
# Install Jenkins
RUN curl -fL http://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/${JENKINS_VERSION}/jenkins-war-${JENKINS_VERSION}.war -o /usr/share/jenkins/jenkins.war \
&& echo "$JENKINS_SHA /usr/share/jenkins/jenkins.war" | sha1sum -c -
ENV JAVA_OPTS="-Xmx8192m"
ENV JENKINS_OPTS="--logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war"
# Prep Jenkins Directories
RUN chown -R jenkins "$JENKINS_HOME" /usr/share/jenkins/ref
RUN mkdir /var/log/jenkins
RUN mkdir /var/cache/jenkins
RUN chown -R jenkins:jenkins /var/log/jenkins
RUN chown -R jenkins:jenkins /var/cache/jenkins
# Expose Ports for web and slave agents
EXPOSE 8080
EXPOSE 50000
# Copy in local config files
COPY init.groovy /usr/share/jenkins/ref/init.groovy.d/tcp-slave-agent-port.groovy
COPY jenkins.sh /usr/local/bin/jenkins.sh
COPY plugins.sh /usr/local/bin/plugins.sh
RUN chmod +x /usr/local/bin/plugins.sh
RUN chmod +x /usr/local/bin/jenkins.sh
# Install default plugins
COPY plugins.txt /tmp/plugins.txt
RUN /usr/local/bin/plugins.sh /tmp/plugins.txt
# Add ssh key
RUN eval "$(ssh-agent -s)"
RUN mkdir /usr/share/jenkins/ref/.ssh && \
chmod 700 /usr/share/jenkins/ref/.ssh && \
ssh-keyscan github.com > /usr/share/jenkins/ref/.ssh/known_hosts
COPY id_rsa /usr/share/jenkins/ref/.ssh/id_rsa
COPY id_rsa /usr/share/jenkins/ref/.ssh/id_rsa.pub
COPY hudson.tasks.Maven.xml /usr/share/jenkins/ref/hudson.tasks.Maven.xml
RUN chown -R jenkins:jenkins /usr/share/jenkins/ref && \
chmod 600 /usr/share/jenkins/ref/.ssh/id_rsa && \
chmod 600 /usr/share/jenkins/ref/.ssh/id_rsa.pub && \
chmod 600 /usr/share/jenkins/ref/hudson.tasks.Maven.xml
COPY id_rsa /root/.ssh/id_rsa
COPY id_rsa /root/.ssh/id_rsa.pub
# ssh keys for root. To use root as the user
RUN chmod 600 /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa.pub && \
ssh-keyscan github.com > /root/.ssh/known_hosts
# Switch to the jenkins user
USER jenkins
# Tini as the entry point to manage zombie processes
ENTRYPOINT ["/bin/tini", "--", "/usr/local/bin/jenkins.sh"]
Apparently the issue was in the gid. For some reason I thought the docker gid of the group in the host was 50 but actually it was actually 100. When I changed it to be 100, the jenkins job started to work.
I still don't know why docker.sock shows it belongs to group user instead of docker in the container though. If I do cat /etc/group in the container I see
root:x:0:
...
users:x:100:
...
jenkins:x:1000:
docker:x:100:jenkins
and in the host
root:x:0:
lp:x:7:lp
nogroup:x:65534:
staff:x:50:docker
docker:x:100:docker
dockremap:x:101:dockremap

docker image - centos 7 > ssh service not found

I installed docker image - centos 7 on my ubuntu machine. But ssh service not found. so I cant run this service.
[root#990e92224a82 /]# yum install openssh-server openssh-clients
Loaded plugins: fastestmirror, ovl
Loading mirror speeds from cached hostfile
* base: mirror.dhakacom.com
* extras: mirror.dhakacom.com
* updates: mirror.dhakacom.com
Package openssh-server-6.6.1p1-31.el7.x86_64 already installed and latest version
Package openssh-clients-6.6.1p1-31.el7.x86_64 already installed and latest version
Nothing to do
[root#990e92224a82 /]# ss
ssh ssh-agent ssh-keygen sshd ssltap
ssh-add ssh-copy-id ssh-keyscan sshd-keygen
How can I remotely login docker image?
You have to do the following instructions on Dockerfile.
RUN yum install -y sudo wget telnet openssh-server vim git ncurses-term
RUN useradd your_account
RUN mkdir -p /home/your_account/.ssh && chown -R your_account /home/your_account/.ssh/
# Create known_hosts
RUN touch /home/your_account/.ssh/known_hosts
COPY files/authorized_keys /home/your_account/.ssh/
COPY files/config /home/your_account/.ssh/
COPY files/pam.d/sshd /etc/pam.d/sshd
RUN touch /home/your_account/.ssh/environment
RUN chown -R your_account /home/your_account/.ssh
RUN chmod 400 -R /home/your_account/.ssh/*
RUN chmod 700 -R /home/your_account/.ssh/known_hosts
RUN chmod 700 /home/your_account/.ssh/environment
# Enable sshd
COPY files/sshd_config /etc/ssh/
RUN ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa
# Add a account into sudoers and this account doesn't need to type his password
COPY files/sudoers /etc/
COPY files/start.sh /root/
I have to remove "pam_nologin.so" on the file /etc/pam.d/sshd, because when I upgrade the openssh-server's version to openssh-server-6.6.1p1-31.el7, the pam_nologin.so will disallow remote login for any users even the file /etc/nologin is not exist.
start.sh
#!/bin/bash
/usr/sbin/sshd -E /tmp/sshd.log
Start centos container
docker run -d -t -p $(sshPort):22 --name $(containerName) $(imageName) /bin/bash
docker exec -d $(containerName) bash -c "sh /root/start.sh"
Login container
ssh $(Docker ip) $(sshPort)
In extend to #puritys
You could do this in the Dockerfile instead
Last in the file:
ENTRYPOINT /usr/sbin/sshd -E /tmp/sshd.log && /bin/bash
Then you will only need to run:
docker run -d -p -t $(sshPort):22 --name $(containerName) $(imageName) /bin/bash

Jenkins and SonarQube in same dockerfile

How to create Docker image which contains jenkins and sonarqube in same container. I have a dockerfile for jenkins.
FROM jenkins
USER root
RUN apt-get update \
&& apt-get install -y sudo \
&& rm -rf /var/lib/apt/lists/*
RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers
USER jenkins
COPY hudson.plugins.msbuild.MsBuildBuilder.xml /var/jenkins_home
COPY hudson.plugins.sonar.SonarPublisher.xml /var/jenkins_home
COPY hudson.plugins.sonar.SonarRunnerInstallation.xml /var/jenkins_home
COPY org.jenkinsci.plugins.MsTestBuilder.xml /var/jenkins_home
COPY plugins.txt /usr/share/jenkins/plugins.txt
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt
How to add sonarqube with this dockerfile.
You should really only run a single process in a single container (see https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/ for learning on docker best practises). Instead use the docker-compose tool to start up your separate docker containers.

Resources