I have this Dockerfile
:
FROM ubuntu:24.04
COPY setup.sh /opt/
RUN echo 'echo Hello from .profile' >> /root/.profile
RUN echo 'source /opt/setup.sh' >> /root/.profile
CMD ["/bin/bash", "-l"]
The contents of the setup.sh
is:
#!/bin/bash
echo "Executing setup script"
say_hello() {
echo "Hello World!"
}
I would like to use the Docker image tagged with test
to run the following Gitlab CI testcase:
foo:
image: registry.git.my-domain.com/test
script:
- ls /opt
- say_hello
This test fails. I get the following output:
Using docker image sha256:fff9c67f9 ...
$ ls /opt
setup.sh
$ say_hello
/usr/bin/bash: line 148: say_hello: command not found
It seems that .profile
was not sourced, as the say_hello command should be available if it were. Why does this happen? In my Dockerfile, I am setting up a login shell that should execute .profile
.
Do I really have to manually source setup.sh
in the testcase foo
? I would like to avoid this but to provide a Docker container that does it automatically.
Why does this happen?
That's simple - it is not running a login shell.
In my Dockerfile, I am setting up a login shell that should execute .profile.
You are setting CMD
. Gitlab executes it's own CMD
.
Do I really have to manually source setup.sh in the testcase foo?
No, but that is the best solution, is explicit and readable. Usually put in before_script:
.
I would like to avoid this but to provide a Docker container that does it automatically.
You can use ENTRYPOINT
to set the entrypoint.
You can use BASH_ENV
environment variable to inject anything to any bash session. You can set it with ENV
.
don't think an entrypoint script would work because variables, aliases etc. defined there won't be visible after the script terminates.
Do not terminate entrypoint. You can export a function in Bash with export -f
.