Home > Software design >  Extending a docker image to run a diff command
Extending a docker image to run a diff command

Time:04-17

I have a docker file as below.

    FROM registry.access.redhat.com/ubi8/ubi
    
    ENV JAVA_HOME /usr/lib/jvm/zulu11
    RUN \
        set -xeu && \
        yum -y -q install https://cdn.azul.com/zulu/bin/zulu-repo-1.0.0-1.noarch.rpm && \
        yum -y -q install python3 zulu11-jdk less && \
        yum -q clean all && \
        rm -rf /var/cache/yum && \
        alternatives --set python /usr/bin/python3 && \
        groupadd trino --gid 1000 && \
        useradd trino --uid 1000 --gid 1000 && \
        mkdir -p /usr/lib/trino /data/trino && \
        chown -R "trino:trino" /usr/lib/trino /data/trino
    
    ARG TRINO_VERSION
    COPY trino-cli-${TRINO_VERSION}-executable.jar /usr/bin/trino
    COPY --chown=trino:trino trino-server-${TRINO_VERSION} /usr/lib/trino
    COPY --chown=trino:trino default/etc /etc/trino
    
    EXPOSE 8080
    USER trino:trino
    ENV LANG en_US.UTF-8
    CMD ["/usr/lib/trino/bin/run-trino"]
    HEALTHCHECK --interval=10s --timeout=5s --start-period=10s \
      CMD /usr/lib/trino/bin/health-check

I would like to extend this Dockerfile and run a run a couple of instructions before running the main command in the Dockerfile? Not sure how to to that.

CodePudding user response:

If you want to run those commands when the container starts, you can use an entrypoint to leave the original command untouched.

The exec $@ will execute the arguments that were passed to the entrypoint with PID 1. Whatever arguments were provided as CMD, those will be in $@, so you essentially execute the CMD after the ENTRYPOINT, doesn't matter what this command might be.

Create an entrypoint script:

#!/usr/bin/env sh
# run some preperation
exec "$@"

And then you copy that into your build and use it.

FROM baseimage
COPY --chmod=755 ./entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]

If you want to run those commands on build, use a FROM instruction and add your run instruction. The new image will use the CMD from the base image. So you don't need to set any CMD.

FROM baseimage
RUN more
RUN stuff

CodePudding user response:

Since you can only have one CMD statement in a Dockerfile (if you have more than one, only the last one is executed), you need to get all your commands into a single CMD statement.

You can use the ability of the shell to chain commands using the && operator, like this

CMD my-first-command && \
    my-second-command && \
    /usr/lib/trino/bin/run-trino

That will run your commands first before running run-trino which is the current CMD.

CodePudding user response:

Whenever you are using a base image, docker throw's away the last layer of the image. So you can extend that image, by writing your own image.

for example: this is my first image (that i get from a third party, just like you)

FROM alpine:latest
CMD echo "hello"

I want to extend it, to output hello world instead of hello, so I extend write another docker file like this

FROM first:latest
CMD echo "hello world"

and when I build the image and run it,

docker build -t second .
docker run second

I get my expected output

hello world

Hopefully that helps

  • Related