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
makeand thenosetestspython module, in the "production" image I do not want to have this. - However, as the production image starts as
rootbut switches to a specific service user in it'sENTRYPOINTI am not able install additional stuff in thebefore_scriptsection. - 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
entrypointentries for bothserviceandimagethis has two problems:- There is no easy way to reference a simple shell script which could be used as
entrypointfrom 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_DIRis volume mounted in the service when the service starts, the project is not checked out already. Therefore$CI_PROJECT_DIRis empty at this point.
- There is no easy way to reference a simple shell script which could be used as
- For the build
imagethe situation is a bit better but including a simple shell wrapper asentrypointis impossible because you may not reference$CI_PROJECT_DIRin 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.shas 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 (closed) 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