Run multiple shell scripts in Dockerfile

25 Views Asked by At

I have to execute a shell script log-agent.sh inside my docker container.

Dockerfile

FROM openjdk:11-jre
LABEL org.opencontainers.image.authors="[email protected]"

# Install AWS CLI
RUN apt-get update && \
    apt-get install -y awscli && \
    apt-get clean

VOLUME /tmp
ARG JAR_FILE
ARG PROFILE
ADD ${JAR_FILE} app.jar
ENV PROFILE_ENV=${PROFILE}
EXPOSE 8080
COPY entrypoint.sh /
COPY log-agent.sh /

# Set permissions for log-agent.sh
RUN chmod +x /log-agent.sh

# Use entrypoint.sh as the entry point
ENTRYPOINT ["/entrypoint.sh"]

# Execute log-agent.sh
# RUN /bin/bash -c '/logs/log-agent.sh'
CMD ["/bin/bash", "-c", "/log-agent.sh"]

entrypoint.sh

#!/bin/bash

# Run your script
/bin/bash /log-agent.sh

# Checking for lead detection level
if [ -z "$LEAK_DETECTION_LEVEL" ]
then
  LEAK_DETECTION_LEVEL=advanced
fi

# Start the Spring Boot application
java -Dspring.profiles.active=${PROFILE_ENV} -XX:+UseG1GC -Dio.netty.leakDetection.level=${LEAK_DETECTION_LEVEL} -Djava.security.egd=file:/dev/./urandom -Dloader.main=com.adtech.DemoApplication -jar app.jar

The application startup is successful, but the container is not executing the script. No errors in the logs as well. Here is what I have already verified:

  1. File location.
  2. File permissions.
  3. Validated the shell script for correctness. (proper shebang operator)
  4. Script is executing correctly if executed manually from the container using the docker exec command

Any suggestions?

1

There are 1 best solutions below

0
JRichardsz On BEST ANSWER

Why is not running?

Basically, is not usual to use CMD and ENTRYPOINT together. If you do that, the cmd instructions are appended to the entrypoint as simple arguments. In your case something like this:

ENTRYPOINT["/entrypoint.sh", "/bin/bash", "-c", "/log-agent.sh"]

More details here

Explanation

In docker, only one foreground process can run. Several processes in just one container is not a good practice.

Docker official web says :

It is generally recommended that you separate areas of concern by using one service per container

Also to have several processes inside of one container is called: Fat container

Anyway you have these alternatives:

#1 Supervisor

With supervisor, you can run several process in one container. For example: postgress + java. In your case, the supervisor config file could be like this

[program:java]
command=/entrypoint.sh
autorestart=false
autostart=true
process_name=java-app

[program:java]
command=/log-agent.sh
autorestart=false
autostart=true
process_name=agent

More details here:

How to package several services in one docker image?

#2 Send agent to background

  • First the java and agent launch should be in your entrypoint.sh
  • The agent should be launched to the background before java

Something like this

#launch agent                   
bash /log-agent.sh > /dev/null 2>&1 &

#launch java app
java -jar ....
  • And your Dockerfile should end with ENTRYPOINT ["/entrypoint.sh"]

Notes: