Applying environment variables to JBoss Bootable Jar in OpenShift/Docker? - docker

I have an application that I am testing in Docker as a JBoss bootable jar. The dockerfile adds the jar to the container, and then runs it. I'd like to pass the database credentials as environment variables for testing, and then as secrets in OpenShift. I tried adding the jar and manipulating it prior to running the CMD java -jar myapp.jar, but the path varies from build to build, and my attempt to capture the path doesn't work when I build the image. I also considered injecting the variables after the application is deployed. It worked, but it was a manual process.
Pre-altering the file did not work because as I was unzipping the files, I was unable to set a variable to store the random path.
FROM registry.redhat.io/ubi8/openjdk-17-runtime
USER root
ENV envhostname=localhost envusername=myappuser envpassword=myapppassword envSID=myappsid
RUN microdnf install fontconfig &&\
microdnf install zip-3.0-23.el8.x86_64
USER 185
ADD myapp-0.0.1-SNAPSHOT-bootable.jar myapp-0.0.1-SNAPSHOT-bootable.jar
RUN unzip myapp-0.0.1-SNAPSHOT-bootable.jar
RUN unzip -n wildfly.zip
RUN export contentpath=$(find . -name "content" | grep -E 'content.+content')
RUN unzip $contentpath
RUN contentpath=${contentpath::-7}
RUN sed -i "s/envhostname/$envhostname/i" $contentpath/WEB-INF/classes/myapp/common/bc4j.xcfg
RUN sed -i "s/envusername/$envusername/i" $contentpath/WEB-INF/classes/myapp/common/bc4j.xcfg
RUN sed -i "s/envpassword/$envpassword/i" $contentpath/WEB-INF/classes/myapp/common/bc4j.xcfg
RUN sed -i "s/envSID/$envSID/i" $contentpath/WEB-INF/classes/myapp/common/bc4j.xcfg
RUN zip -f -Ar $contentpath/content $contentpath/WEB-INF/classes/myapp/common/bc4j.xcfg
RUN zip -f wildfly.zip $contentpath/content
RUN zip -f myapp-0.0.1-SNAPSHOT-bootable.jar wildfly.zip
CMD java -jar myapp-0.0.1-SNAPSHOT-bootable.jar
And I don't know how to automatically trigger a shell script to run after the CMD.
There has to be some better way to handle this.

Oof. I just needed to think this through more. I solved this by modifying my Dockerfile as such
FROM registry.redhat.io/ubi8/openjdk-17-runtime
USER root
ENV envhostname=localhost envusername=myappuser envpassword=mapppw envSID=myapp
RUN microdnf install fontconfig &&\
microdnf install zip-3.0-23.el8.x86_64
ADD myapp-0.0.1-SNAPSHOT-bootable.jar myapp-0.0.1-SNAPSHOT-bootable.jar
ADD prepcfg.sh prepcfg.sh
RUN chmod 777 myapp-0.0.1-SNAPSHOT-bootable.jar
USER 185
CMD ["./prepcfg.sh"]
and creating prepcfg.sh
#!/bin/sh
unzip myapp-0.0.1-SNAPSHOT-bootable.jar
unzip -n wildfly.zip
export contentpath=$(find . -name "content" | grep -E 'content.+content')
contentpath=${contentpath::-7}
cd $contentpath
unzip content
sed -i "s/envhostname/$envhostname/i" WEB-INF/classes/myapp/common/bc4j.xcfg
sed -i "s/envusername/$envusername/i" WEB-INF/classes/myapp/common/bc4j.xcfg
sed -i "s/envpassword/$envpassword/i" WEB-INF/classes/myapp/common/bc4j.xcfg
sed -i "s/envSID/$envSID/i" WEB-INF/classes/myapp/common/bc4j.xcfg
zip -f -Ar content WEB-INF/classes/myapp/common/bc4j.xcfg
cd ~
zip wildfly.zip $contentpath/content
zip myapp-0.0.1-SNAPSHOT-bootable.jar wildfly.zip
java -jar myapp-0.0.1-SNAPSHOT-bootable.jar
Because I don't need to worry about running two commands when I can just initialize my JBoss server at the end of the script called in the Dockerfile.

Related

dockerfile how to run shopt -s extglob

I have the following Dockerfile
FROM python:3.9-slim-buster
## DO SOMETHING HERE
RUN /bin/bash -c shopt -s extglob && rm -rfv !(".env")
I am getting
Step 42/49 : RUN /bin/bash -c shopt -s extglob && rm -rfv !(".env")
---> Running in 5b4ceacb1908
/bin/sh: 1: Syntax error: "(" unexpected
HOw to run this command. I need this
Every RUN line in your Dockerfile will launch a new container with a separate shell. The extglob shell option must be set before a line of input is parsed by the shell, so one way to go about this is to launch the shell with that option enabled:
RUN /bin/bash -O extglob -c 'rm -rfv !(".env")'
The main caveat is that you have to quote the command line as a string.
I'd recommend avoiding bash-specific syntax wherever possible.
In this case, the bash-specific glob pattern !(.env) means "every file except .env. So you can accomplish this specific task by moving .env out of the way, deleting the whole directory, recreating it, and moving .env back; all without worrying about which shell expansion objects are set.
RUN cd .. \
&& mv the_dir/.env . \
&& rm -rf the_dir \
&& mkdir the_dir \
&& mv .env the_dir
You also might consider whether you need a broad rm -rf at all. Because of Docker's layer system, the previous content of the directory is still "in the image". If you use a multi-stage build then the later stage will start from a clean slate, and you can COPY in whatever you need.
FROM python:3.9-slim-buster AS build
...
FROM python:3.9-slim-buster
WORKDIR /app
COPY .env .
COPY --from=build ...
/bin/bash seems to work for "shopt -s extglob" part but not the other. Separate the lines like this:
RUN /bin/bash -c shopt -s extglob
RUN /bin/bash -c rm -rfv !(".env")
or
RUN /bin/bash -c "shopt -s extglob && rm -rfv !(\".env\")"

permission denied docker localhost

i just started to learn docker...
and i faced this issue, of building image from dockerfile, run a container and trying to access to it!
so when i try to login localhost via ssh -p 12000 root#localhost,
it keeps saying permission denied even when i put abcd for password
FROM ubuntu:20.04
RUN apt update && apt -y upgrade
RUN apt install -y openssh-server
RUN apt-get install -y gcc
RUN mkdir /var/run/sshd
RUN echo 'root:abcd' | chpasswd
RUN sed -i 's/#*PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
RUN sed -i 's#session\s*s*required\s*pam_loginuid.so#session optional pam_loginuid.so#g' /etc/pam.d/sshd
ENV NOTVISIBLE="in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
COPY hw.c /root
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
WORKDIR /root
RUN gcc -o root hw.c
The best way to ssh to a container is by running this commands (this is for your ubuntu container)
docker exec -ti <container_id> bash
the container_id you can get it running docker ps if you didn't setup a fix name
Then you can remove all this lines
RUN mkdir /var/run/sshd
RUN echo 'root:abcd' | chpasswd
RUN sed -i 's/#*PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
RUN sed -i 's#session\s*s*required\s*pam_loginuid.so#session optional pam_loginuid.so#g' /etc/pam.d/sshd
ENV NOTVISIBLE="in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
COPY hw.c /root
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
Remember also that everything you do by ssh on the container will be lost after the container is killed, so always better to add everything on the Dockerfile
i fixed it by deleting all remaining containers!

How do I configure umask in alpine based docker container

I have a Java application that runs in docker based on the cutdown alpine distribution, I want umask to be set to 0000 so that all files created by the application in the configured volume /music are accessible to all users.
The last thing the Dockerfile does is run a script that starts the application
CMD /opt/songkong/songkongremote.sh
This file contains the following
umask 0000
java -XX:MaxRAMPercentage=60 \
-Dcom.mchange.v2.log.MLog=com.mchange.v2.log.jdk14logging.Jdk14MLog\
-Dorg.jboss.logging.provider=jdk \
-Djava.util.logging.config.class=com.jthink.songkong.logging.StandardLogging\ --add-opens java.base/java.lang=ALL-UNNAMED -jar lib/songkong-6.9.jar -r
The application runs, but in the docker container logs I see the following is output to stdout
/opt/songkong/songkongremote.sh: umask: line 1: illegal mode: 0000
indicating the umask command did not work, which I do not understand since that is a valid value for umask. (I have also tried umask 000 at that failed with same error)
I also tried adding
#!/bin/sh
as the first line to the file, but then Docker complained it could not find /bin/sh.
Full Dockerfile is:
FROM adoptopenjdk/openjdk11:alpine-jre
RUN apk --no-cache add \
ca-certificates \
curl \
fontconfig \
msttcorefonts-installer \
tini \
&& update-ms-fonts \
&& fc-cache -f
RUN mkdir -p /opt \
&& curl http://www.jthink.net/songkong/downloads/build1114/songkong-linux-docker.tgz?val=121| tar -C /opt -xzf - \
&& find /opt/songkong -perm /u+x -type f -print0 | xargs -0 chmod a+x
EXPOSE 4567
ENTRYPOINT ["/sbin/tini"]
# Config, License, Logs, Reports and Internal Database
VOLUME /songkong
# Music folder should be mounted here
VOLUME /music
WORKDIR /opt/songkong
CMD /opt/songkong/songkongremote.sh
Your /opt/songkong/songkongremote.sh script has what looks like non-linux newlines (Windows?).
You can view it by running:
$ docker run --rm -it your-image-name vi /opt/songkong/songkongremote.sh
And it is the same reason the #!/bin/sh line did not work, it probably looked like #!/bin/sh^M as well.
You have carriage return characters in your script file:
umask 0000^M
java -XX:MaxRAMPercentage=60 -Dcom.mchange.v2.log.MLog=com.mchange.v2.log.jdk14logging.Jdk14MLog -Dorg.jboss.logging.provider=jdk -Djava.util.logging.config.class=com.jthink.songkong.logging.StandardLoggi
^M
You can add RUN sed -i -e 's/\r//g' /opt/songkong/songkongremote.sh to the Dockerfile or better recreate the script.

creating an RPM package from binary file doesn't package the files into an archive

I'm trying to create an RPM package from node project packaged into a binary file with pkg.
I've created an rpmbuild skeleton in /root/rpmbuild.
The binary package was copied into /root/rpmbuild/SOURCES.
I've created a menlolab-runner.service file in /root/rpmbuild.
I'm skipping the %prep and %build sections in the .spec file. During the install section the binary files is copied to /usr/bin folder. In the %post section the service file is copied to /etc/systemd/system/
%define version %(cat package.json | jq -r '.version')
%define release 1
%define buildroot /root/rpmbuild/BUILDROOT/
Name: %{name}
Version: %{version}
Release: %{release}
Summary: menlolab-runner
Group: Installation Script
License: MIT
Source0: runner
AutoReqProv: no
%description
The agent deployed on private and public infrastructure to manage tasks.
%global debug_package %{nil}
%prep
%build
%pre
getent group menlolab-runner >/dev/null || groupadd -r menlolab-runner
getent passwd menlolab-runner >/dev/null || useradd -r -g menlolab-runner -G menlolab-runner -d / -s /sbin/nologin -c "menlolab-runner" menlolab-runner
%install
mkdir -p %{buildroot}%{_bindir}/
mkdir -p %{buildroot}%{_unitdir}
cp runner %{buildroot}%{_bindir}/menlolab-runner
cp /root/rpmbuild/menlolab-runner.service %{buildroot}%{_unitdir}
%post
systemctl enable %{_unitdir}/menlolab-runner.service
chmod ugo+x /usr/bin/menlolab-runner
mkdir -p '/etc/menlolab-runner/'
chown -R 'menlolab-runner:menlolab-runner' '/etc/menlolab-runner'
chmod 700 '/etc/menlolab-runner'
mkdir -p '/var/lib/menlolab-runner/'
chown -R 'menlolab-runner:menlolab-runner' '/var/lib/menlolab-runner/'
mkdir -p '/var/lib/menlolab-runner/jobs/'
chown -R 'menlolab-runner:menlolab-runner' '/var/lib/menlolab-runner/jobs/'
chmod 700 '/var/lib/menlolab-runner/jobs/'
mkdir -p '/var/log/menlolab-runner/'
chown -R 'menlolab-runner:menlolab-runner' '/var/log/menlolab-runner/'
mkdir -p '/var/cache/menlolab-runner/'
chown -R 'menlolab-runner:menlolab-runner' '/var/cache/menlolab-runner/'
groupadd docker
usermod -aG docker menlolab-runner
%clean
rm -rf %{buildroot}
%files
%{_bindir}/menlolab-runner
%{_unitdir}/menlolab-runner.service
%defattr(644, menlolab-runner, menlolab-runner, 755)
My issue is the fact that .rpm contains no files after executing rpmbuild -ba /path/to/spec/file.
I think it's because I have no entry in the %files section. I'm not sure what to put into this section. If I add the path to binary file there I receive the following error:
error: File not found: /root/rpmbuild/BUILDROOT/menlolab-runner-0.2.5a2-1.x86_64/root/rpmbuild/SOURCES/runner
In your %install section you must place files into $RPM_BUILD_ROOT, so something like:
%install
cp runner $RPM_BUILD_ROOT%{_bindir}/menlolab-runner
Subsequently, the %files section should list the installed files, relative to the $RPM_BUILD_ROOT, e.g.:
%files
%{_bindir}/menlolab-runner

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

Resources