100

I'm trying to build a custom tcserver docker image. But I'm having some problems starting the webserver and the tomcat.
As far as I understand I should use ENTRYPOINT to run the commands I want.
The question is, is it possible to run multiple commands with ENTRYPOINT?
Or should I create a small bash script to start all?

Basically what I would like to do is:

ENTRYPOINT /opt/pivotal/webserver/instance1/bin/httpdctl start && /opt/pivotal/webserver/instance2/bin/httpdctl start && /opt/pivotal/pivotal-tc-server-standard/standard-4.0.1.RELEASE/tcserver start instance1 -i /opt/pivotal/pivotal-tc-server-standard && /opt/pivotal/pivotal-tc-server-standard/standard-4.0.1.RELEASE/tcserver start instance2 -i /opt/pivotal/pivotal-tc-server-standard

But I don't know if that is a good practice or if that would even work.

3
  • 1
    Possible duplicate of How to run multiple processes in a single docker container Commented Jan 10, 2019 at 2:19
  • 2
    Your approach with && should work, as it can actually be considered a single command. However, it is better practice to create a bash script. But, as a general rule, you should use a single process per container if you want the benefits of containers. Commented Jan 10, 2019 at 2:23
  • 1
    why not using like ENTRYPOINT ["entry1", "exec1", "entry2", "exec2"] Commented Jan 10, 2019 at 2:29

4 Answers 4

114

In case you want to run many commands at entrypoint, the best idea is to create a bash file. For example commands.sh like this

#!/bin/bash
mkdir /root/.ssh
echo "Something"
cd tmp
ls
...

And then, in your DockerFile, set entrypoint to commands.sh file (that execute and run all your commands inside)

COPY commands.sh /scripts/commands.sh
RUN ["chmod", "+x", "/scripts/commands.sh"]
ENTRYPOINT ["/scripts/commands.sh"]

After that, each time you start your container, commands.sh will be execute and run all commands that you need. You can take a look here https://github.com/dangminhtruong/drone-chatwork

Sign up to request clarification or add additional context in comments.

5 Comments

I have one more question. If I use this build as a base (ie: tcserver_build) and later I want to import a new .war file to the tomcat webapps directory. I will create a new build (ie: webapp_build) with just the COPY or the .war file to the tomcat webapps directory. I will need to put a new ENTRYPOINT to start the webserver and tomcat or it will use the one from the base build (tcserver_build)?
> I will need to put a new ENTRYPOINT to start the webserver and tomcat or it will use the one from the base build (tcserver_build)? Docker will use all instructions from the base image, unless you override them in your image.
What if you are part of an organization that is averse to incorporating shell scripts into their infrastructure? How does one simply chain a pair of commands? For example, suppose I mount a drive that requires the docker image to install particular versions, or at least run through a requirements file and verify the versions are in order before running a command? Suppose I am at the docker compose level?
If one is mounting an application folder in docker-compose, is there then any reason to copy the commands.sh file into the container first? Doesn't that just complicate things because you then have to rebuild every time you make a change in it? Couldn't one just do ENTRYPOINT ["/mounted/folder/commands.sh"]?
Note that if you are using secrets, they are only available after the entry point. You would have to use CMD instead of ENTRYPOINT if you want to copy or link your secret at startup
99

You can use something like this:

ENTRYPOINT ["/bin/sh", "-c" , "<command A> && <command B> && <command C>"]

5 Comments

Do I have to escape & caracter if I want to run the first command in background? E.g.: ENTRYPOINT ["/bin/sh", "-c" , "service1 & && service2"] where service1 should run in the background and service2 in foreground.
Works perfectly if you cannot add a custom shell script (for a pre-built image)
Does this gracefully terminate (handle SIGTERM)?
This will execute the commands in the shell. But all parameters in the CMD[] directive after ENTRYPOINT will not be included in the command. How it works : ` ENTRYPOINT ["command","param1","param2"] CMD["param3"] ` => Projection exec command param1 param2 param3. In your case ENTRYPOINT ["/bin/sh","-c", "commandA && commandB"] CMD ["param"] => Projection exec /bin/sh -c "commandA && commandB". commandB will not receive parameters. if entrypoint as exec, CMD[]` default params entrypoints. Replaced by console parameters run image param1 param2.
@MarkSowul Shell does not forward SIGTERM, but you can prepend your last command with exec which will replace the shell process and receive SIGTERM
2

I personally encountered a problem where I needed to preserve the behavior of the parent image. My solution Example : Dockerfile (PARENT)

RUN ...
RUN ...
COPY ./entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
CMD ["default_param1"]

Dockerfile (CHILD)

RUN mv /entrypoint.sh /parent-entrypoint.sh
COPY ./entrypoint.sh /

#Optional. If the entry point is through a different script name
#ENTRYPOINT ["/entrypoint.sh"] 

#Indicate if the entry point has changed
#CMD ["default_param1"] 

/entrypoint.sh (child)

#!/bin/sh
/runMyscript.sh ; /parent-entrypoint.sh $@

Comments

-16

You can use npm concurrently package.

For e.g.

ENTRYPOINT ["npx","concurrently","command1","command2"]

It will run them in parallel.

2 Comments

This doesn't work if your final container is not Node. Such as when you're building an angular application and hosting it on nginx.
@RoboticRenaissance wth npm, pnpm and npx you can run not only node scripts, but any stackoverflow.com/questions/34937724/… So this answer not the best, but shouldn't be that flagged.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.