run script in Dockerfile - docker

I have to run my .sh script in Dockerfile based on "grafana/grafana" but I'm not sure how to do it.
FROM grafana/grafana
COPY setup.sh /setup.sh
CMD ["/bin/bash", "/setup.sh"]
after docker run my script is not running. I guess it due to in grafana Dockerfile runs another sh script.

Can you please try if that works:
RUN ./setup.sh

There are two ways to do it inside Dockerfile
RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN ["executable", "param1", "param2"] (exec form)

Related

I want to run a script during container run based on env variable that I pass

I want to run a script during run time and not during image build.
The script runs based on env variable that I pass during container run.
Script:
#!/bin/bash
touch $env
Docker file
FROM busybox
ENV env parm
RUN mkdir PRATHAP
ADD apt.sh /PRATHAP
WORKDIR /PRATHAP
RUN chmod 777 apt.sh
CMD sh apt.sh
when I try to run: docker container run -it -e env=test.txt sh
the script is not running
I am just getting the sh terminal. If I remove it the the container is not alive.. Please help me how to achieve it
Your docker run starts sh which overrides your CMD in Dockerfile. To get around this, you need to replicate the original CMD via the command line.
$ docker run -it -e env=test.txt <image:tag> sh -c "./init.sh; sh"
Remember that a Docker container runs a single command, and then exits. If you docker run your image without overriding the command, the only thing the container will do is touch a file inside the isolated container filesystem, and then it will promptly exit.
If you need to do some startup-time setup, a useful pattern is to write it into an entrypoint script. When a container starts up, Docker runs whatever you have named as the ENTRYPOINT, passing the CMD as additional parameters (or it just runs CMD if there is no ENTRYPOINT). You can use the special shell command exec "$#" to run the command. So revisiting your script as an entrypoint script:
#!/bin/sh
# ^^ busybox image doesn't have bash (nor does alpine)
# Do the first-time setup
touch "$env"
# Launch the main container process
exec "$#"
In your Dockerfile set this script to be the ENTRYPOINT, and then whatever long-running command you actually want the container to do to be the CMD.
FROM busybox
WORKDIR /PRATHAP # Also creates the directory
COPY apt.sh . # Generally prefer COPY to ADD
RUN chmod 0755 apt.sh # Not world-writable
ENV env parm
ENTRYPOINT ["./apt.sh"] # Must be JSON-array syntax
# Do not need to name interpreter, since
# it is executable with #! line
CMD sh # Or whatever the container actually does

Run command on entrypoint in docker outputs no file errors

On a simple dockerfile:
FROM python:3
ENV PYTHONUNBUFFERED 1
WORKDIR /code/
If I run:
docker build -t my_image .
docker run -v ~/Downloads/data/:/home -it -d my_image # mount data folder inside home
docker exec -it container_id sh -c "python script.py -i /home/db.sqlite"
Everything runs ok. But I would like to run the script.py on run so that there is no need for an exec command.
So I added to the dockerfile:
ENTRYPOINT ["python script.py -i /home/db.sqlite"]
But when I run my container now it fails with a file or folder not found error at python script.py
I think the problem is how the ENTRYPOINT syntax works. Your using the exec-form and it does not find the binary (it uses the whole command line as path to the binary).
From https://docs.docker.com/engine/reference/builder/#entrypoint:
ENTRYPOINT has two forms:
ENTRYPOINT ["executable", "param1",
"param2"] (exec form, preferred)
ENTRYPOINT command param1 param2
(shell form)
So try either:
ENTRYPOINT ["/path/to/python", "script.py", "-i", "/home/db.sqlite"]
Or
ENTRYPOINT python script.py -i /home/db.sqlite

How to pass dynamic values to Docker container?

I am running a perl script in Dockerfile and I would like to pass dynamic command line arguments to the perl script while running docker image(container).
Ex: CMD perl test.pl <args>. I am new to Docker.
Is there any possible way to pass dynamic values to the docker container like
docker run <image name> <args>?
You could use an Entrypoint script:
$ docker run [OPTIONS] IMAGE[:TAG|#DIGEST] [COMMAND] [ARG...]
and
If the image also specifies an ENTRYPOINT then the CMD or COMMAND get appended as arguments to the ENTRYPOINT.
So depending on your Dockerfile you'd have something like this (python sample app):
FROM jfloff/alpine-python:3.6
# add entrypoint script
USER root
COPY start.sh /
RUN chmod a+x /start.sh
ENTRYPOINT ["/start.sh"]
CMD ["arg1"]
and start.sh:
#!/bin/bash
echo $1
# don't exit
/usr/bin/tail -f /dev/null
Now you can do something like:
15:19 $ docker run f49b567f05f1 Hello
Hello
15:21 $ docker run f49b567f05f1
arg1
Now if your script is set up to take those arguments, you should be able to run it as you want. Reference from Docker is attached, search for "Overriding Dockerfile image defaults" in this and then look in the CMD section.
Or check this Post.
I am not sure whether you can do it with CMD but if you just want to execute the perl script with some passed in arguments use ENTRYPOINT.
ENTRYPOINT ["perl", "test.pl"]
CMD ["default-arg"]
Run the container with:
docker -run <image-name> overriding-arg

Dockerfile run /bin/bash id ENTRYPOINT or CMD fails

I would like to run /bin/bash in the case that the CMD or ENTRYPOINT programs fails.
So: CMD top && /bin/bash
I want that when I close top with cntrl-C I get a shell in the container.
Thank you
This is the way to do it:
CMD bash -c 'top; bash'

Can you pass flags to the command that docker runs?

The documentation for the run command follows the following syntax:
docker run [OPTIONS] IMAGE[:TAG|#DIGEST] [COMMAND] [ARG...]
however I've found at times that I want to pass a flag to [COMMAND].
For example, I've been working with this image, where the [COMMAND] as specified in the Dockerfile is:
CMD ["/bin/bash", "-c", "/opt/solr/bin/solr -f"]
Is there any way to tack on flags to "/opt/solr/bin/solr -f" so that it's in the form "/opt/solr/bin/solr -f [-MY FLAGS]"?
Do I need to edit the DockerFile or is there some built in functionality for this?
There is a special directive ENTRYPOINT which fits your needs. Unlike CMD it will add additional flags at the end of your command.
For example, you can write
ENTRYPOINT ["python"]
and run it with
docker run <image_name> -c "print(1)"
Note, that this only will work if you write command in exec form (via ["...", "..."]), otherwise ENTRYPOINT will invoke shell and pass your args there, not to your script.
More generally, you can combine ENTRYPOINT and CMD
ENTRYPOINT ["ping"]
CMD ["www.google.com"]
Where CMD means default args for your ENTRYPOINT. Now you can run both of
docker run <image_name>
docker run <image_name> yandex.ru
and only CMD will be replaced.
Full reference about how ENTRYPOINT and CMD interact can be found here
The CMD directive of a Dockerfile is the command that would be run when the container starts if no command was specified in the docker run command.
The main purpose of a CMD is to provide defaults for an executing container.
In your case, just use the docker run command as follow to override the default command specified in the Dockerfile:
docker run makuk66/docker-solr /bin/bash -c "/opt/solr/bin/solr -f [your flags]"

Resources