I have a gitlab runner inside a docker container, runs fine if I run an image like nginx. But now I tried to run docker in docker (dind) inside the gitlab runner and I want to run docker-compose inside the dind. Docker info runs fine, but if I try to run docker-compose I get an permission-denied error.
I linked the /usr/local/bin/docker-compose file to the gitlab runner container and enter it in the volumes parameter in the runner config.toml file.
If I try to run sudo it ends with an unknown command error, so that could not be the solution.
Do I have to link some file more or are the to many nested containers?
One of the (many!) features of Docker 0.6 is the new “privileged” mode for containers. It allows you to run some containers with (almost) all the capabilities of their host machine, regarding kernel features and device access.
GitLab Runner can use Docker to run jobs on user provided images. This is possible with the use of Docker executor. The Docker executor when used with GitLab CI, connects to Docker Engine and runs each build in a separate and isolated container using the predefined image that is set up in .
GitLab Runner can also run inside a Docker container or be deployed into a Kubernetes cluster.
In order to have docker-compose
, you need to install it for image docker, which is of version 18.09.6, build 481bc77 at the time of writing.
Since docker-compose version 1.24.0, you also need the following dependencies for docker-compose to be installed on alpine:
apk add py-pip python3-dev libffi-dev openssl-dev gcc libc-dev make
Here is a sample .gitlab-ci.yml
:
image: docker:stable
stages:
- deploy
services:
- docker:dind
before_script:
- apk update
- apk add py-pip python3-dev libffi-dev openssl-dev gcc libc-dev make
- pip install docker-compose
deploy_app:
stage: deploy
script:
- docker-compose down
- docker-compose up -d
if you are using dind it means docker is working OK, now you just have to install docker-compose that is just simple python package and you can do it in before_script
.gitlab-ci.yml
image: docker:latest
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
stages:
- test
before_script:
- apk add --no-cache py-pip
- pip install docker-compose
- docker info
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN docker.registry.com
test:
stage: test
script:
- cp .env.sample .env # copy environement variable
- docker-compose up -d
# run some test here
The best choice for running docker-compose inside docker in docker is using the docker/compose image as bellow:
job-x:
image: docker/compose
script:
- docker-compose version
A real and full example of this is using docker-compose to deploy with specific installed runner on a server as bellow:
image: docker:stable
services:
- docker:dind
stages:
- build
- deploy
before_script:
# resolve TAG
# Default branch leaves tag latest
# All other branches are tagged with the escaped branch name (commit ref slug)
- |
if [[ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]]; then
TAG="latest"
echo "Running on default branch '$CI_DEFAULT_BRANCH': tag = '$TAG'"
else
TAG="$CI_COMMIT_REF_SLUG"
echo "Running on branch '$CI_COMMIT_BRANCH': tag = $TAG"
fi
docker-build:
stage: build
script:
- echo "user ${CI_REGISTRY_USER}"
- echo "registry ${CI_REGISTRY}"
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from "$CI_REGISTRY_IMAGE:${TAG}" -t "$CI_REGISTRY_IMAGE:${TAG}" .
- docker push "$CI_REGISTRY_IMAGE:${TAG}"
when: manual
deploy-staging:
image: docker/compose
stage: deploy
variables:
IMAGE: $CI_REGISTRY_IMAGE
TAG: $TAG
HOST_PORT: $HOST_PORT
script:
- docker-compose version
- docker-compose -f docker-compose.yml up -d --no-build
when: manual
The docker-compose.yml file seems like:
version: "3.7"
services:
web:
image: $IMAGE:$TAG
build:
context: .
ports:
- $HOST_PORT:8000
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With