Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to run .sh file when container is running using dockerfile

I'm making a dockerfile to install elasticsearch:6.5.4 and add few files to required locations and run a script named test.sh to create a new index in elasticsearch while elasticsearch is running.

I'm not sure whether i should use RUN, CMD or ENTRYPOINT to do that.

I've successfully built an image and run a container by commenting my last line (containing RUN/CMD/ENTRYPOINT test.sh). I was able to run the test.sh from bash of container and get the desired result.

but when i try to build an image for same process, i get the following error:

$ docker build -t es .
Sending build context to Docker daemon  7.499MB
Step 1/8 : FROM elasticsearch:6.5.4
 ---> 93109ce1d590
Step 2/8 : WORKDIR /app
 ---> Running in 6b6412093d53
Removing intermediate container 6b6412093d53
 ---> a374ab69eb1a
Step 3/8 : ADD . /app
 ---> 6ed98ee7ad49
Step 4/8 : COPY test.sh .
 ---> 42184ec64c09
Step 5/8 : ADD analysis /usr/share/elasticsearch/config/analysis
 ---> 5a96f2098dd7
Step 6/8 : EXPOSE 9202
 ---> Running in 6c44b54dcc77
Removing intermediate container 6c44b54dcc77
 ---> d8723189c843
Step 7/8 : EXPOSE 9200
 ---> Running in c571b4cba1fa
Removing intermediate container c571b4cba1fa
 ---> 8fa11b03051e
Step 8/8 : RUN "sh test.sh"
 ---> Running in cf2e8cb3fd37
/bin/sh: sh test.sh: command not found
The command '/bin/sh -c "sh test.sh"' returned a non-zero code: 127

I've tried different combinations of RUN, CMD and ENTRYPOINT for STEP 8

my dockerfile is as follows :

FROM elasticsearch:6.5.4
WORKDIR /app
ADD . /app
COPY test.sh .
ADD analysis /usr/share/elasticsearch/config/analysis

EXPOSE 9202
EXPOSE 9200

RUN "sh test.sh"

I want to run elasticsearch in container and make a new index for elasticsearch

like image 369
Irfan Harun Avatar asked Dec 18 '22 16:12

Irfan Harun


1 Answers

At a purely mechanical level, the quotes are causing trouble. When you say

RUN "sh test.sh"

it tries to run a single command named sh\ test.sh; it does not try to run sh with test.sh as a parameter. Any of the following will actually run the script

RUN ["sh", "test.sh"]
RUN sh test.sh
RUN chmod +x test.sh; ./test.sh

At an operational level you'll have a lot of trouble running that command in the server container at all. The big problem is that you need to run that command after the server is already up and running. So you can't run it in the Dockerfile at all (no services are ever running in a RUN command). A container runs a single process and you need that process to be the Elasticsearch server itself, so you can't do this directly in ENTRYPOINT or CMD either.

The easiest path is to run this command from the host:

docker build -t my/elasticsearch .
docker run -d --name my-elasticsearch -p 9200:9200 my/elasticsearch
curl http://localhost:9200  # is it alive?
./test.sh

If you have a Docker Compose setup, you could also run this from a separate container, or you could run it as part of the startup of your application container. There are some good examples of running database migrations in an ENTRYPOINT script for your application container running around, and that's basically the pattern you're looking for.

(It is theoretically possible to run this in an entrypoint script. You have to start the server, wait for it to be up, run your script, stop the server, and then finally exec "$@" to run the CMD. This is trickier for Elasticsearch, where you might need to connect to other servers in the same Elasticsearch cluster lest your state get out of sync. The official Docker Hub mysql does this, for a non-clustered database server; see its rather involved entrypoint script for ideas.)

like image 98
David Maze Avatar answered Jan 05 '23 01:01

David Maze