Introduce relative entrypoints and start services after project clone and checkout
Description
~"feature proposal" executordocker
DBish images
- A lot of images which are provided at hub.docker.com allow custom scripts to be executed before the main process starts
- mysql: https://github.com/docker-library/mysql/blob/ad625c64a06e16683e997e5a0147508d115f4989/5.7/docker-entrypoint.sh#L176 executes scripts from
/docker-entrypoint-initdb.d/*
. - postgresql: https://github.com/docker-library/postgres/blob/0aaaf2094034647a552f0b1ec63b1b0ec0f6c2cc/10/docker-entrypoint.sh#L126 executes scripts from
/docker-entrypoint-initdb.d/*
as well. - mongo: https://github.com/docker-library/mongo/blob/621a206bca04c06ad3e0d8459c9d23223ea11a01/3.7/docker-entrypoint.sh#L306 executes scripts from
/docker-entrypoint-initdb.d/*
as well.
- mysql: https://github.com/docker-library/mysql/blob/ad625c64a06e16683e997e5a0147508d115f4989/5.7/docker-entrypoint.sh#L176 executes scripts from
Extending build images
- I now have the case of a Debian based image, which I want to use for executing Ansible scripts for deployments:
- During testing I want to have
make
and thenosetests
python module, in the "production" image I do not want to have this. - However, as the production image starts as
root
but switches to a specific service user in it'sENTRYPOINT
I am not able install additional stuff in thebefore_script
section. - So now I have to create an inherited image just for testing, which looks like an overkill.
- During testing I want to have
Problems
- While I may define
entrypoint
entries for bothservice
andimage
this has two problems:- There is no easy way to reference a simple shell script which could be used as
entrypoint
from the cloned project, because you may not reference the directory where the project is found after cloning. - So all you may do is restricted to execute one command in the
entrypoint
- If you use one of the above DBs for integration-tests, the automatic script execution of
/docker-entrypoint-initdb.d/*
is useless, because the order of execution in the docker-executor looks like this:- pull service image
- create service container
- start service container
- wait for successful start
- pull build image
- create build container
- clone project via the helper image
- checkout
- start build image
- run build
- So while
$CI_PROJECT_DIR
is volume mounted in the service when the service starts, the project is not checked out already. Therefore$CI_PROJECT_DIR
is empty at this point.
- There is no easy way to reference a simple shell script which could be used as
- For the build
image
the situation is a bit better but including a simple shell wrapper asentrypoint
is impossible because you may not reference$CI_PROJECT_DIR
in theentrypoint
.
Proposal
Allow a relative entry point
See mfriedenhagen/gitlab-runner@6071d9e2
Just check whether entrypoint
starts with ./
and prepend $CI_PROJECT_DIR
, so when I create a file ./initialize-mysql.sh
in my project with this content:
#!/bin/sh -e
cp $CI_PROJECT_DIR/mysql-docker-entrypoint-initdb.d/* /docker-entrypoint-initdb.d/
exec /usr/local/bin/docker-entrypoint.sh $*
I may call it like:
image:
name: mysql
entrypoint: ["./initialize-mysql.sh"]
Start services after cloning
- While allowing relative entrypoints would allow an execution of
/docker-entrypoint-initdb.d/
for build images for services the order should be like this so that I may copy my init scripts in./initialize-mysql.sh
as seen above:- pull service image(s)
- create service container(s)
- pull build image
- create build container
- clone project via the helper image
- checkout
- start service container(s)
- wait for successful start
- start build image
- run build
Links to related issues and merge requests / references
- I could imagine that #1462 (closed), #1507 (closed), #1525 and #2826 (closed) would be solved or at least easily work-arounded by this proposal.
- Of course #2625 (closed) is an issue with this approach as well.
Edited by Mirko Friedenhagen