Docker/Dockerfile: Using ENTRYPOINT for git clone - docker

I am trying to run a git clone command inside my Dockerfile as entrypoint so that it is not cached and I am guaranteed to have the most up to date source code. Currently I have the following code in the Dockerfile:
FROM ubuntu:trusty
MAINTAINER Fernando Mayo <fernando#tutum.co>, Feng Honglin <hfeng#tutum.co>
# Install packages
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
apt-get -y install vim supervisor git curl unzip apache2 libapache2-mod-php5 pwgen php-apc php5-mcrypt php5-mysql php5-curl&& \
echo "ServerName localhost" >> /etc/apache2/apache2.conf
# Install Composer
RUN curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer
RUN composer global require "laravel/installer"
ENV PATH ~/.composer/vendor/bin:$PATH
# Add image configuration and scripts
ADD start-apache2.sh /start-apache2.sh
ADD start-mysqld.sh /start-mysqld.sh
ADD run.sh /run.sh
RUN chmod 755 /*.sh
ADD my.cnf /etc/mysql/conf.d/my.cnf
ADD supervisord-apache2.conf /etc/supervisor/conf.d/supervisord-apache2.conf
ADD supervisord-mysqld.conf /etc/supervisor/conf.d/supervisord-mysqld.conf
ADD php.ini /etc/php5/cli/php.ini
ADD 000-default.conf /etc/apache2/sites-available/000-default.conf
# config to enable .htaccess
RUN a2enmod rewrite
# Copy over private key, and set permissions
ADD .ssh /root/.ssh
# Get aws stuff
RUN curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
RUN unzip awscli-bundle.zip
RUN ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
# Clone the repo
RUN rm -rd /var/www/html
RUN git clone ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/Laravel /var/www/html
# Set file permissions
RUN chmod -R 777 /var/www/html/storage
RUN chmod -R 777 /var/www/html/bootstrap/cache
# Environment variables to configure php
ENV PHP_UPLOAD_MAX_FILESIZE 10M
ENV PHP_POST_MAX_SIZE 10M
EXPOSE 80 3306
CMD ["/run.sh"]
To remove the cache I changed the following lines:
# Clone the repo
RUN rm -rd /var/www/html
RUN git clone ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/Laravel /var/www/html
# Set file permissions
RUN chmod -R 777 /var/www/html/storage
RUN chmod -R 777 /var/www/html/bootstrap/cache
with
# Clone the repo
RUN rm -rd /var/www/html
ENTRYPOINT git clone ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/Laravel /var/www/html
# Set file permissions
ENTRYPOINT chmod -R 777 /var/www/html/storage
ENTRYPOINT chmod -R 777 /var/www/html/bootstrap/cache
I can build this Dockerfile but when I run it stops before I can do anything (I can't access it with localhost and I don't see any errors). What am I doing wrong with ENTRYPOINT?

Your entry point just does one thing and exits. You probably want to run your server in your entry point so the container sticks around. In your case, it seems like you want to run run.sh.
Additionally, only one ENTRYPOINT is allowed. You should convert your multiple entry points to a script and use that as the entry point. From the documentation:
Only the last ENTRYPOINT instruction in the Dockerfile will have an
effect.

Related

Permissions problem in Docker container built in Ubuntu VM composed of files created on Windows host

I work on a project that has a large number of Java SpringBoot services (and other types) running in k8s clusters. Each service has a small start script that executes a more complex script that is provided in a configmap. This all works fine in builds and at runtime.
I need to make some changes to that complex script. I've already made the changes and tested the concept in an isolated script. I still need to do more testing of it. I am attempting to take some of the command lines that run in our Linux build system and run them on my VirtualBox Ubuntu VM that runs on my Windows 10 laptop. Although I am running this on the VM, most of the files were created and written on the host Windows 10 laptop that I get to using a VirtualBox Shared Folder.
When I look at the "ls -l" output of "startService.sh", I just get this:
-rwxrwx--- 1 root vboxsf 634 Aug 24 15:07 startService.sh*
Note that I am running docker with my own uid, and I have that uid in the "vboxsf" group.
It seems like when the file gets copied into the image, either the owner or the perms get changed in a way that make it inaccessible from within the container.
I tried adding a "RUN chmod 777 startService.sh" in the Dockerfile, just before the ENTRYPOINT, but that fails at build time with this:
Step 23/26 : RUN chmod 777 startService.sh
---> Running in 6dbb89c930c1
chmod: startService.sh: Operation not permitted
The command '/bin/sh -c chmod 777 startService.sh' returned a non-zero code: 1
I don't know why this is happening, or whether this is something that might mitigate this.
My "docker build" command looks like it went fine. I saw it execute all the steps that the normal build shows. The "docker run" step seemed to go fine, but it finished very quickly. When I looked at the "docker log" for the container, it just said entirely:
/bin/sh: ./startService.sh: Permission denied
Note that everything here is done the same way it is on the build server. There seems to be something funny with the fact that I'm running an Ubuntu
You have to write chmod +x startService.sh before docker run or docker-compose up -d --build
And example Dockerfile for django. Look at actions with wait-for, you must make same
###########
# BUILDER #
###########
# pull official base image
FROM python:3.8.3-slim as builder
# set work directory
WORKDIR /usr/src/app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install psycopg2 dependencies
RUN apt-get update \
&& apt-get -y install libpq-dev gcc \
python3-dev musl-dev libffi-dev\
&& pip install psycopg2
# lint
RUN pip install --upgrade pip
COPY . .
# install dependencies
COPY ./requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt
# copy project
COPY . .
#########
# FINAL #
#########
# pull official base image
FROM python:3.8.3-slim
# create directory for the app user
RUN mkdir -p /home/app
# create the app user
RUN addgroup --system app && adduser --system --group app
# create the appropriate directories
ENV HOME=/home/app
ENV APP_HOME=/home/app/web
RUN mkdir $APP_HOME
RUN mkdir $APP_HOME/static
RUN mkdir $APP_HOME/media
RUN mkdir $APP_HOME/currencies
WORKDIR $APP_HOME
# install dependencies
RUN apt-get update && apt-get install -y libpq-dev bash netcat rabbitmq-server
COPY --from=builder /usr/src/app/wheels /wheels
COPY --from=builder /usr/src/app/requirements.txt .
COPY wait-for /bin/wait-for
COPY /log /var/log
COPY /run /var/run
RUN pip install --no-cache /wheels/*
# copy project
COPY . $APP_HOME
# chown all the files to the app user
RUN chown -R app:app $APP_HOME
RUN chown -R app:app /var/log/
RUN chown -R app:app /var/run/
EXPOSE 3000
# change to the app user
USER app
# only for dgango
CMD ["gunicorn", "Config.asgi:application", "--bind", "0.0.0.0:8000", "--workers", "3", "-k","uvicorn.workers.UvicornWorker","--log-file","-"]

Creating an Elastic search image. Issue with non-root user and image size

Solution - Used Multi-stage build file to reduce the size significantly. solution pasted below
Edit: Already played with default elastic search image, But the purpose of this exercise is to learn working of Dockerfile. That is how i noticed my image being much larger (2.5G) than official image (742 M)
New to dockers/containers landscape ( was using vagrants till now ) .
To get better understanding of Dockerfile working, decided to create an ES image ( similar to ones i created in the past for a vagrant box ) .
Can someone help in reviewing the docker file and answer following issues being encountered.
Running ES as root is not allowed and running it from /home/newuser gives following error.
What am i missing here ? How should i create a new user/group to resolve this issue.
newuser#9f5820d430eb:~$ elasticsearch
Exception in thread "main" java.lang.RuntimeException: starting java failed with [1]
output:
[0.000s][error][logging] Error opening log file 'logs/gc.log': Permission denied
[0.001s][error][logging] Initialization of output 'file=logs/gc.log' using options 'filecount=32,filesize=64m' failed.
error:
Invalid -Xlog option '-Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m', see error log for details.
Error: Could not create the Java Virtual Machine.
The dockerfile is installing JDK and ES but the images size is over 2GB. Can this be reduced . Found something called multi-stage images. not sure how to fit that concept in my dockerfile.
In vagrant provisions i update paths to /etc/environment.
Should this be done for containers ? I am not sure if it adds any value.
Docerkfile -
# Base image stage 1
FROM ubuntu
#MAINTAINER demo#gmail.com
LABEL maintainer="demo#foo.com"
############################################
### Install openjava
############################################
#RUN apt-get update
ARG JAVA_HOME=/opt/java
ARG JDK_PACKAGE=openjdk-14.0.2_linux-x64_bin.tar.gz
# setup paths
ENV JAVA_HOME $JAVA_HOME
# Setup JAVA_HOME, this is useful for docker commandline
ENV PATH $PATH:$JAVA_HOME/bin
## write to environment file for all future sessions
# sudo /bin/sh -c 'echo JAVA_HOME="/opt/java/" >> /etc/environment'
# sudo /bin/sh -c '. /etc/environment ; echo PATH="$JAVA_HOME/bin:$PATH" >> /etc/environment'
## download open java
# ADD https://download.java.net/java/GA/jdk14.0.2/205943a0976c4ed48cb16f1043c5c647/12/GPL/$JDK_PACKAGE /
# ADD $JDK_PACKAGE /
COPY $JDK_PACKAGE /
RUN mkdir -p $JAVA_HOME/ && \
tar -zxf /$JDK_PACKAGE --strip-components 1 -C $JAVA_HOME && \
rm -f /$JDK_PACKAGE
############################################
### Install elastic search
############################################
ARG ES_HOME=/opt/elasticsearch
ARG ES_PACKAGE=elasticsearch-7.10.1-linux-x86_64.tar.gz
# setup paths
ENV ES_HOME $ES_HOME
# Setup ES_HOME, this is useful for docker commandline
ENV PATH $PATH:$ES_HOME/bin
##write to environment file for all future sessions
#sudo /bin/sh -c 'echo ES_HOME="/opt/elasticsearch/" >> /etc/environment'
#sudo /bin/sh -c '. /etc/environment ; echo PATH="$ES_HOME/bin:$PATH" >> /etc/environment'
## download es
# ADD https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.1-linux-x86_64.tar.gz /
# ADD $JDK_PACKAGE /
COPY $ES_PACKAGE /
RUN mkdir -p $ES_HOME/ && \
tar -zxf /$ES_PACKAGE --strip-components 1 -C $ES_HOME && \
rm -f /$ES_PACKAGE
# Mount elasticsearch.yml config
ADD config/elasticsearch.yml /elasticsearch/config/elasticsearch.yml
#ADD config/elasticsearch.yml /
############################################
### Others
############################################
# Expose ports
EXPOSE 9200
EXPOSE 9300
## give permission to entire elasticsearch setup directory
RUN chmod 755 -R $ES_HOME
RUN chmod 755 -R $JAVA_HOME
RUN chmod 755 -R /var/log
# add non root user
RUN useradd newuser --create-home --shell /bin/bash
RUN echo 'newuser:newpassword' | chpasswd
RUN adduser newuser sudo
USER newuser
WORKDIR /home/newuser
# Define default command.
#CMD ["elasticsearch"]
Solution -
Multi stage build file with non-root user
ARG JAVA_HOME=/opt/java
ARG JDK_PACKAGE=openjdk-14.0.2_linux-x64_bin.tar.gz
ARG ES_HOME=/opt/elasticsearch
ARG ES_PACKAGE=elasticsearch-7.10.1-linux-x86_64.tar.gz
#MAINTAINER demo#gmail.com
#LABEL maintainer="demo#foo.com"
############################################
### Install openjava
############################################
# Base image stage 1
FROM ubuntu as jdk
ARG JAVA_HOME
ARG JDK_PACKAGE
WORKDIR /opt/
## download open java
# ADD https://download.java.net/java/GA/jdk14.0.2/205943a0976c4ed48cb16f1043c5c647/12/GPL/$JDK_PACKAGE /
# ADD $JDK_PACKAGE /
COPY $JDK_PACKAGE .
RUN mkdir -p $JAVA_HOME/ && \
tar -zxf $JDK_PACKAGE --strip-components 1 -C $JAVA_HOME && \
rm -f $JDK_PACKAGE
############################################
### Install elastic search
############################################
# Base image stage 2
From ubuntu as es
#ARG JAVA_HOME
ARG ES_HOME
ARG ES_PACKAGE
WORKDIR /opt/
## download es
# ADD https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.1-linux-x86_64.tar.gz /
# ADD $JDK_PACKAGE /
COPY $ES_PACKAGE .
RUN mkdir -p $ES_HOME/ && \
tar -zxf $ES_PACKAGE --strip-components 1 -C $ES_HOME && \
rm -f $ES_PACKAGE
# Mount elasticsearch.yml config
ADD config/elasticsearch.yml /opt/elasticsearch/config/elasticsearch.yml
############################################
### final
############################################
From ubuntu as finalbuild
ARG JAVA_HOME
ARG ES_HOME
ARG ES_PACKAGE
WORKDIR /opt/
# get artifacts from previous stages
COPY --from=jdk $JAVA_HOME $JAVA_HOME
COPY --from=es $ES_HOME $ES_HOME
# Setup JAVA_HOME, this is useful for docker commandline
ENV JAVA_HOME $JAVA_HOME
ENV ES_HOME $ES_HOME
# setup paths
ENV PATH $PATH:$JAVA_HOME/bin
ENV PATH $PATH:$ES_HOME/bin
# Expose ports
EXPOSE 9200
EXPOSE 9300
# Define mountable directories.
#VOLUME ["/data"]
## give permission to entire elasticsearch setup directory
RUN useradd newuser --create-home --shell /bin/bash && \
echo 'newuser:newpassword' | chpasswd && \
chown -R newuser $ES_HOME $JAVA_HOME && \
chown -R newuser:newuser /home/newuser && \
chmod 755 /home/newuser
#chown -R newuser:newuser /home/newuser
#chown -R newuser /home/newuser && \
USER newuser
WORKDIR /home/newuser
#RUN chown -R newuser /home/newuser
#RUN apt-get update && \
# apt-get install -yq curl
# Define default command.
CMD ["elasticsearch"]
The concept of docker is that you have tons of out-of-the-box images ready for you!
Why do you want to build your own Dockerfile for a common tech like Elasticsearch?
Why not simply:
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.10.1
and you have the image ready locally for run?
You can read more about running Elasticseach with docker here.
BTW, this image size is ~774MB
EDIT:
If it's for learning purpose, I can recommend dive which can analyze baked images (like the elasticsearch:7.10.1 and shows you each step of the image build (in other words, the dockerfile that built that image) and the base image it start FROM.

Adding files to a docker instance not working

I have the following snippet in my docker file:
...
ADD app.war /opt/apache-tomcat-8.5.14/webapps/app.war
...
However, entering the docker image as:
docker exec -it tomcat /bin/sh
and doing an ls to the webapps folder, the file isn't there. The file, in my local OS, windows, it is in the same folder as the dockerfile. Any clue about why this happens?
EDIT:
However, using the cp command in my windows cmd, it works correctly after checking in the container.
The dockerfile:
FROM alpine:latest
MAINTAINER Adilson Cesar <adilsonbna#gmail.com>
# Expose Web Port
EXPOSE 8080
# Set environment
ENV JAVA_HOME /opt/jdk
ENV PATH ${PATH}:${JAVA_HOME}/bin
ENV JAVA_PACKAGE server-jre
ENV TOMCAT_VERSION_MAJOR 8
ENV TOMCAT_VERSION_FULL 8.5.14
ENV CATALINA_HOME /opt/tomcat
# Download and install Java
RUN apk --update add openjdk8-jre &&\
mkdir -p /opt/jdk &&\
ln -s /usr/lib/jvm/java-1.8-openjdk/bin /opt/jdk
# Download and install Tomcat
RUN apk add --update curl &&\
curl -LO https://archive.apache.org/dist/tomcat/tomcat-${TOMCAT_VERSION_MAJOR}/v${TOMCAT_VERSION_FULL}/bin/apache-tomcat-${TOMCAT_VERSION_FULL}.tar.gz &&\
curl -LO https://archive.apache.org/dist/tomcat/tomcat-${TOMCAT_VERSION_MAJOR}/v${TOMCAT_VERSION_FULL}/bin/apache-tomcat-${TOMCAT_VERSION_FULL}.tar.gz.md5 &&\
md5sum -c apache-tomcat-${TOMCAT_VERSION_FULL}.tar.gz.md5 &&\
gunzip -c apache-tomcat-${TOMCAT_VERSION_FULL}.tar.gz | tar -xf - -C /opt &&\
rm -f apache-tomcat-${TOMCAT_VERSION_FULL}.tar.gz apache-tomcat-${TOMCAT_VERSION_FULL}.tar.gz.md5 &&\
ln -s /opt/apache-tomcat-${TOMCAT_VERSION_FULL} /opt/tomcat &&\
rm -rf /opt/tomcat/webapps/examples /opt/tomcat/webapps/docs &&\
apk del curl &&\
rm -rf /var/cache/apk/*
ADD app.war /opt/apache-tomcat-8.5.14/webapps/
# Launch Tomcat on startup
CMD ${CATALINA_HOME}/bin/catalina.sh run
Thanks!
Although docker docs suggest otherwise
If <dest> does not end with a trailing slash, it will be considered a regular file and the contents of <src> will be written at <dest>
Try this by removing the destination filename. It should work.
ADD app.war /opt/apache-tomcat-8.5.14/webapps/
Also, from Docker Best Practices it is advised to use COPY instead of ADD if you're just copying local files and not playing around with remote URLs.
Although ADD and COPY are functionally similar, generally speaking, COPY is preferred. That’s because it’s more transparent than ADD

Why "docker build" fails on local image

Probably I'm missing something obvious, but could someone please explain the following:
When I pull and run an image, e.g docker pull dgraziotin/lamp && docker run -t -i -p 80:80 -p 3306:3306 --name osxlamp dgraziotin/lamp - it works just fine
Now I want to play with Dockerfile and build it manually on my computer (I can do this, right?)
So I download the source files from Github https://github.com/dgraziotin/osx-docker-lamp, cd to unpacked folder and run docker build -t test .
The building process starts but I see lot of weird errors like "Package php5-mysql is not available". I tried different images with the same result. How to properly build local images?
UPD:
Dockerfile
FROM phusion/baseimage:latest
MAINTAINER Daniel Graziotin <daniel#ineed.coffee>
ENV REFRESHED_AT 2016-03-29
# based on tutumcloud/tutum-docker-lamp
# MAINTAINER Fernando Mayo <fernando#tutum.co>, Feng Honglin <hfeng#tutum.co>
ENV DOCKER_USER_ID 501
ENV DOCKER_USER_GID 20
ENV BOOT2DOCKER_ID 1000
ENV BOOT2DOCKER_GID 50
# Tweaks to give Apache/PHP write permissions to the app
RUN usermod -u ${BOOT2DOCKER_ID} www-data && \
usermod -G staff www-data && \
useradd -r mysql && \
usermod -G staff mysql
RUN groupmod -g $(($BOOT2DOCKER_GID + 10000)) $(getent group $BOOT2DOCKER_GID | cut -d: -f1)
RUN groupmod -g ${BOOT2DOCKER_GID} staff
# Install packages
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
apt-get -y install supervisor wget git apache2 libapache2-mod-php5 mysql-server php5-mysql pwgen php-apc php5-mcrypt zip unzip && \
echo "ServerName localhost" >> /etc/apache2/apache2.conf
# needed for phpMyAdmin
run php5enmod mcrypt
# Add image configuration and scripts
ADD start-apache2.sh /start-apache2.sh
ADD start-mysqld.sh /start-mysqld.sh
ADD run.sh /run.sh
RUN chmod 755 /*.sh
ADD supervisord-apache2.conf /etc/supervisor/conf.d/supervisord-apache2.conf
ADD supervisord-mysqld.conf /etc/supervisor/conf.d/supervisord-mysqld.conf
# Remove pre-installed database
RUN rm -rf /var/lib/mysql
# Add MySQL utils
ADD create_mysql_users.sh /create_mysql_users.sh
RUN chmod 755 /*.sh
# Add phpmyadmin
RUN wget -O /tmp/phpmyadmin.tar.gz https://files.phpmyadmin.net/phpMyAdmin/4.6.0/phpMyAdmin-4.6.0-all-languages.tar.gz
RUN tar xfvz /tmp/phpmyadmin.tar.gz -C /var/www
RUN ln -s /var/www/phpMyAdmin-4.6.0-all-languages /var/www/phpmyadmin
RUN mv /var/www/phpmyadmin/config.sample.inc.php /var/www/phpmyadmin/config.inc.php
ENV MYSQL_PASS:-$(pwgen -s 12 1)
# config to enable .htaccess
ADD apache_default /etc/apache2/sites-available/000-default.conf
RUN a2enmod rewrite
# Configure /app folder with sample app
RUN mkdir -p /app && rm -fr /var/www/html && ln -s /app /var/www/html
ADD app/ /app
#Environment variables to configure php
ENV PHP_UPLOAD_MAX_FILESIZE 10M
ENV PHP_POST_MAX_SIZE 10M
# Add volumes for the app and MySql
VOLUME ["/etc/mysql", "/var/lib/mysql", "/app" ]
EXPOSE 80 3306
CMD ["/run.sh"]
SOLVED As I understood many of custom images contain outdated/invalid code and must be avoided as much as possible. We should rely on official well known and supported images.
Unrelated to the exact problem, but your Dockerfile could use some rework based on Best Practices for writing Dockerfiles.
I'd like to point out the ADD vs COPY best practice and the deprecated MAINTAINER Instruction (you should use LABEL maintainer="Daniel Graziotin ").
Also on the part where you add phpmyadmin it's useless to use RUN instead of ADD if you don't extract and delete the archive in the same layer (using multiline arguments). This can also be found under the ADD vs COPY best practices.
Other than that I can say this is a pretty solid Dockerfile! Sad it won't work because of the application...

How to create a Jenkins job and/or user from a dockerfile?

I am trying to set up a customised Jenkins 2 server from a dockerfile.
I use the official image and I want to be able to add things that I need like custom jobs and an admin user.
This is my dockerfile so far:
FROM openjdk:8-jdk
RUN apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/*
ENV JENKINS_HOME /var/jenkins_home
ENV JENKINS_SLAVE_AGENT_PORT 50000
ARG user=jenkins
ARG group=jenkins
ARG uid=1000
ARG gid=1000
# 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 groupadd -g ${gid} ${group} \
&& useradd -d "$JENKINS_HOME" -u ${uid} -g ${gid} -m -s /bin/bash ${user}
# 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
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 -
COPY init.groovy /usr/share/jenkins/ref/init.groovy.d/tcp-slave-agent-port.groovy
# jenkins version being bundled in this docker image
ARG JENKINS_VERSION
ENV JENKINS_VERSION ${JENKINS_VERSION:-2.19.2}
# jenkins.war checksum, download will be validated using it
ARG JENKINS_SHA=32b8bd1a86d6d4a91889bd38fb665db4090db081
# Can be used to customize where jenkins.war get downloaded from
ARG JENKINS_URL=https://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/${JENKINS_VERSION}/jenkins-war-${JENKINS_VERSION}.war
# could use ADD but this one does not check Last-Modified header neither does it allow to control checksum
# see https://github.com/docker/docker/issues/8331
RUN curl -fsSL ${JENKINS_URL} -o /usr/share/jenkins/jenkins.war \
&& echo "${JENKINS_SHA} /usr/share/jenkins/jenkins.war" | sha1sum -c -
ENV JENKINS_UC https://updates.jenkins.io
RUN chown -R ${user} "$JENKINS_HOME" /usr/share/jenkins/ref
# for main web interface:
EXPOSE 8080
# will be used by attached slave agents:
EXPOSE 50000
ENV COPY_REFERENCE_FILE_LOG $JENKINS_HOME/copy_reference_file.log
USER ${user}
COPY jenkins-support /usr/local/bin/jenkins-support
COPY jenkins.sh /usr/local/bin/jenkins.sh
ENTRYPOINT ["/bin/tini", "--", "/usr/local/bin/jenkins.sh"]
# from a derived Dockerfile, can use `RUN plugins.sh active.txt` to setup /usr/share/jenkins/ref/plugins from a support bundle
COPY plugins.txt /usr/share/jenkins/plugins.txt
COPY plugins.sh /usr/local/bin/plugins.sh
COPY install-plugins.sh /usr/local/bin/install-plugins.sh
# Add the command line tools
COPY jenkins-cli.jar "$JENKINS_HOME"
# Create jobs
ARG job_name_1="my_super_job"
#ARG job_name_2="my_ultra_job"
# create the jobs folder recursively
RUN mkdir -p "$JENKINS_HOME"/jobs/${job_name_1}
RUN mkdir -p "$JENKINS_HOME"/jobs/${job_name_1}/workspace/
RUN mkdir -p "$JENKINS_HOME"/jobs/${job_name_1}/builds
RUN mkdir -p "$JENKINS_HOME"/jobs/${job_name_1}/builds/lastFailedBuild
RUN mkdir -p "$JENKINS_HOME"/jobs/${job_name_1}/builds/lastStableBuild
RUN mkdir -p "$JENKINS_HOME"/jobs/${job_name_1}/builds/lastSuccessfulBuild
RUN mkdir -p "$JENKINS_HOME"/jobs/${job_name_1}/builds/lastUnstableBuild
RUN mkdir -p "$JENKINS_HOME"/jobs/${job_name_1}/builds/lastUnsuccessfulBuild
RUN mkdir -p "$JENKINS_HOME"/jobs/${job_name_1}/builds/legacyIds
#RUN mkdir -p "$JENKINS_HOME"/jobs/${job_name_2}
## add the custom configs to the container
COPY ${job_name_1}_config.xml "$JENKINS_HOME"/jobs/${job_name_1}/config.xml
USER root
#RUN chmod 600 "$JENKINS_HOME"/jobs/${job_name_1}/config.xml
RUN java -jar /var/jenkins_home/jenkins-cli.jar -s http://localhost:8080 create-job my_super_job < /var/jenkins_home/jobs/my_super_job/config.xml
#COPY ${job_name_2}_config.xml "$JENKINS_HOME"/jobs/${job_name_2}/config.xml
# --Install plugins--
# Notice: Deprecated method which however works with a 'plugins.txt' file
#USER root
#RUN chmod 600 /usr/share/jenkins/plugins.txt
#RUN chmod 600 /usr/local/bin/install-plugins.sh
#RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt
# Notice: Recommended method with open case on Github [https://github.com/jenkinsci/docker/issues/348]
# Notice: Select whichever plugins you want
#RUN /usr/local/bin/install-plugins.sh \
#dashboard-view:2.9.10 \
#pipeline-stage-view:2.2 \
#parameterized-trigger:2.32 \
#bitbucket:1.1.5 \
#git:3.0.0 \
#github:1.22.4
# --Install plugins--
I have tried to create a job on build time by first launching a container, creating the job manually, saving the config.xml file, and then copying it in the image from the Dockerfile. Moreover, I am trying to replicate the files/folder structure when a job is being created.
But it is not working. The job is not appearing in Jenkins.
I also tried to use the jenkins-cli.jar, but as I understood , there must be a live Jenkins server to connect to and execute anything which is not the case at build time.
Finally, I suppose creating an admin user in build time must be way more complicated that creating a job...
So, does anyone have any experience on this?

Resources