docker unzip file on run - docker

Here is my Dockerfiles which work, but my image is heavy.
I would like to unzip only on start! How can I do that?
I would like to execute dockerStatScript.sh just on start, and after "pm2-runtime", "pm2_conf.json"
I have try everything... I don't get it
thank for your help
FROM keymetrics/pm2:12-alpine
RUN apk add --no-cache --upgrade bash && \
apk add postgresql-libs libpq zip unzip tree
WORKDIR /app
COPY docker/dockerStatScript.sh .
RUN chmod +x dockerStatScript.sh
ENV NODE_ENV=production
COPY app_prod/build/2.6.3/app.zip Zapp.zip
COPY app_prod/build/2.6.3/node_modules.zip Znode_modules.zip
COPY app_prod/build/2.6.3/config.zip Zconfig.zip
RUN ["/bin/bash","dockerStatScript.sh"]
CMD [ "pm2-runtime", "pm2_conf.json" ]
EXPOSE 8080

To compress immage use
docker image build --compress {rest-of-the-build-arguments-here}
to start dockerStatScript.sh after "pm2-runtime", "pm2_conf.json"
you will have to create a wrapper shell script like startup.sh with content
./pm2-runtime.sh pm2_conf.json
./dockerStatScript.sh
add it to the docker image like you did for dockerStatScript.sh. i.e.
COPY docker/startup.sh .
RUN chmod +x startup.sh
and than replace these:
RUN ["/bin/bash","dockerStatScript.sh"]
CMD [ "pm2-runtime", "pm2_conf.json" ]
with this:
ENTRYPOINT ["/bin/bash","/app/startup.sh"]
and start container with out parameters because entrypoint going to "startup.sh" on each container start.
here is a helpful link which explains startup options:
https://dev.to/lasatadevi/docker-cmd-vs-entrypoint-34e0.
hope i didn't do any typos :)
UPDATE:
you can use
ENTRYPOINT ["/bin/bash","/app/startup.sh"]
or
CMD ["/bin/bash","/app/startup.sh"]
or omit entrypoint and cmd and just start container with /app/startup.sh as parameter. i.e. docker run image-name "/app/startup.sh" - i am usually using this wa because it gives more flexibility what to run during debug time.
Make sure that your sh file doesn't exit until you need your container to stop.

Related

How to use env variables set from build phase in run. (Docker)

I want to preface this in saying that I am very new to docker and have just got my feet wet with using it. In my Docker file that I run to build the container I install a program that sets some env variables. Here is my Docker file for context.
FROM python:3.8-slim-buster
COPY . /app
RUN apt-get update
RUN apt-get install wget -y
RUN wget http://static.matrix-vision.com/mvIMPACT_Acquire/2.40.0/install_mvGenTL_Acquire.sh
RUN wget http://static.matrix-vision.com/mvIMPACT_Acquire/2.40.0/mvGenTL_Acquire-x86_64_ABI2-2.40.0.tgz
RUN chmod +x ./install_mvGenTL_Acquire.sh
RUN ./install_mvGenTL_Acquire.sh -u
RUN apt-get install -y python3-opencv
RUN pip3 install USSCameraTools
WORKDIR /app
CMD python3 main.py
After executing the build docker command the program "mvGenTL_Acquire.sh" sets env inside the container. I need these variables to be set when executing the run docker command. But when checking the env variables after running the image it is not set. I know I can pass them in directly but would like to use the ones that are set from the install in the build.
Any help would be greatly appreciated, thanks!
For running a bash script when your container is creating:
make an script.sh file:
#!/bin/bash
your commands here
If you are using an alpine image, you must use #!/bin/sh instead of #!/bin/bash on the first line of your bash file.
Now in your Dockerfile copy your bash file in the container and use the ENTRYPOINT instruction for running this file when the container is creating:
.
.
.
COPY script.sh /
RUN chmod +x /script.sh
.
.
.
ENTRYPOINT ["/script.sh"]
Notice that in the ENTRYPOINT instruction use your bash file address in your image.
Now when you create a container, the script.sh file will be executed.

Running multiple CMD commands at once

Wondering what I may be doing wrong, currently trying to revise this CMD to the proper format but it's not running right. The original w/ no edit is running good, but using the array version is not. Does combining commands not work in the proper format, or what may I be missing? Modified version when run immediately exits once it starts
Original:
CMD sshd & cd /app && npm start
Modified:
CMD ["sshd", "&", "cd", "/app", "&&", "npm", "start"]
My complete dockerfile:
FROM node:10-alpine
WORKDIR /app
COPY . /app
RUN npm install && npm cache clean --force
# CMD sshd & cd /app && npm start
# CMD ["sshd", "&", "cd", "/app", "&&", "npm", "start"]
You should:
Delete sshd: it's not installed in your image, it's unnecessary, and it's all but impossible to set up securely.
Delete the cd part, since the WORKDIR declaration above this has already switched into that directory.
Then your CMD is just a simple command.
FROM node:10-alpine
# note, no sshd, user accounts, host keys, ...
WORKDIR /app # does the same thing as `cd /app`
COPY . /app
RUN npm install && npm cache clean --force
CMD ["npm", "start"]
If you want to run multiple commands or attempt to launch an unmanaged background process, all of these things require a shell to run and you can't usefully use the CMD exec form. In the form you show in the question the main command is sshd only, and it takes 6 arguments including the literal strings & and &&.
Define a script and put all of your commands into this script.
Eg: I call this script is startup.sh
#!/bin/bash
sshd
cd /app
npm start
And call this script in CMD
COPY startup.sh /app/data/startup.sh
CMD ["/app/data/startup.sh"]

Dockerfile accept multiple args and choose an action

I have a python image that launches a web app and I'm wondering if it's possible to run pytest from container - I would like to choose if I want to run the app or run the tests.
Is possible?
My dockerfile looks like:
FROM python:3.7-slim-buster
COPY ./ ./x
WORKDIR ./x
RUN pip install -r requirements.txt
EXPOSE 5000
CMD ["gunicorn", "-b", "0.0.0.0:5000", "--log-level=info", "app:app"]
Is possible to run something like docker run x --someargumenttolaunchtests?
You can set an ARGS value in your dockerfile which is an argument that you provided during build time. If you want to provide an arguement in run time, you can set an environment variable via docker run -e some_environment.
Then, you can, with a bash script, choose what you want to run. So your bash script provides your if some_eivonrment = ? then etc. You would have to make this bash script prior to run time and either COPY it to your dockerfile or bind it on run time.
So here is an example of a bash script.
#!bin/bash
ENVIRONMENT=$(export some_environment)
if("$ENVIRONMENT" = "test") ; then
python run_test.py
else
python main.py
fi
Before I forget, you need to set the permissions for this bash script.
So in your dockerfile:
COPY ./bash_script.sh /app
WORKDIR /app
RUN chmod u+x bash_script.sh
You can completely override the entrypoint script and avoid gunicorn. Use something like:
docker run --rm -it --entrypoint bash myimagename pytest

Docker nginx not starting after running custom script

We have an angular app we are trying to run in docker nginx.
I have to run a script on startup that uses an environment variableto replace the app url for each stage. This is needed to connect to the backend.
We do not wish to build the container for each stage. The container will run in Azure docker.
For now i am running it locally. It executes my script and then the app shuts down.
The Docker File:
FROM node:8.11.2-alpine as node
LABEL author="My Online Presence"
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:1.13.12-alpine
COPY /certificates /etc/nginx/
COPY --from=node /usr/src/app/dist /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
ADD run.sh /usr/share/nginx/html/run.sh
RUN apk add --update bash && rm -rf /var/cache/apk/*
RUN chmod +x /usr/share/nginx/html/run.sh
ENTRYPOINT ["/usr/share/nginx/html/run.sh"]
CMD ["nginx", "-g", "daemon off;"]
The run.sh file
#!/bin/sh
FILE_NAME=$(find . -name "main*.js")
sed -i "s/localhost\:4200/${DIGITISE_URL}/g" $FILE_NAME
echo 'File updated with correct url'
i use
docker build -t digitise .
and then
docker run -p 80:80 -p 443:443 -e DIGITISE_URL=digitise.co.za digitise
I got it working simply by adding
exec "$#"
to the end of my script being run
You can also start nginx service in your script.

Why I am bounced from the Docker container?

FROM docker.elastic.co/elasticsearch/elasticsearch:5.5.2
USER root
WORKDIR /usr/share/elasticsearch/
ENV ES_HOSTNAME elasticsearch
ENV ES_PORT 9200
RUN chown elasticsearch:elasticsearch config/elasticsearch.yml
RUN chown -R elasticsearch:elasticsearch data
# install security plugin
RUN bin/elasticsearch-plugin install -b com.floragunn:search-guard-5:5.5.2-16
COPY ./safe-guard/install_demo_configuration.sh plugins/search-guard-5/tools/
COPY ./safe-guard/init-sgadmin.sh plugins/search-guard-5/tools/
RUN chmod +x plugins/search-guard-5/tools/init-sgadmin.sh
ADD ./run.sh .
RUN chmod +x run.sh
RUN chmod +x plugins/search-guard-5/tools/install_demo_configuration.sh
RUN ./plugins/search-guard-5/tools/install_demo_configuration.sh -y
RUN chmod +x sgadmin_demo.sh
RUN yum install tree -y
#RUN curl -k -u admin:admin https://localhost:9200/_searchguard/authinfo
RUN usermod -aG wheel elasticsearch
USER elasticsearch
EXPOSE 9200
#ENTRYPOINT ["nohup", "./run.sh", "&"]
ENTRYPOINT ["/usr/share/elasticsearch/run.sh"]
#CMD ["echo", "hello"]
Once I add either CMD or Entrypoint - "Container is exited with code 0"
#!/bin/bash
exec $#
If I comment ENTRYPOINT or CMD - all is great.
What I am doing wrong???
If you take a look at official 5.6.9 elasticsearch Dockerfile, you will see the following at the bottom:
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["elasticsearch"]
If you do not know the difference between CMD and ENTRYPOINT, read this answer.
What you're doing is you're overwriting those two instructions with something else. What you really need is to extend CMD. What I usually do in my images, I create an sh script and combine different things I need and then indicate the script for CMD. So, you need to run sgadmin_demo.sh, but you need to wait for elasticsearch first. Create a start.sh script:
#!/bin/bash
elasticsearch
sleep 15
sgadmin_demo.sh
Now, add your script to your image and run it on CMD:
FROM: ...
...
COPY start.sh /tmp/start.sh
CMD ["/tmp/start.sh"]
Now it should be executed once you start a container. Don't forget to build :)

Resources