I'm getting the error docker: command not found while running the following CI script inside gitlab-ci. This error is happening during before_script for the deploy phase.
services:
- docker:dind
stages:
- build
- test
- deploy
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
build:
stage: build
image: docker:latest
script:
- docker info
- docker version
- docker build --pull -t $SERVICE_NAME:$CI_COMMIT_REF_NAME .
- docker image list
- docker tag $SERVICE_NAME:$CI_COMMIT_REF_NAME $CI_REGISTRY_IMAGE/$SERVICE_NAME:$CI_COMMIT_REF_NAME
- docker push $CI_REGISTRY_IMAGE/$SERVICE_NAME:$CI_COMMIT_REF_NAME
test:
image: docker:latest
stage: test
script:
- docker pull $CI_REGISTRY_IMAGE/$SERVICE_NAME:$CI_COMMIT_REF_NAME
- docker image list
- docker run $CI_REGISTRY_IMAGE/$SERVICE_NAME:$CI_COMMIT_REF_NAME npm test
deploy:
image: google/cloud-sdk
stage: deploy
environment: Production
script:
- echo $DEPLOY_KEY_FILE_PRODUCTION > /tmp/GCLOUD_KEYFILE.json
- gcloud auth activate-service-account --key-file /tmp/GCLOUD_KEYFILE.json
- rm /tmp/GCLOUD_KEYFILE.json
- gcloud info
- gcloud components list
only:
- master
I'm a bit confused, because I'm runing docker-in-docker (docker:dind) as a service so the docker command should be made available to all stages (if I understand this correctly), however it's clearly not.
Is it due to an interaction with google/cloud-sdk ?
You probably misunderstood what services mean. From the doc,
The services keyword defines just another docker image that is run during your job and is linked to the docker image that the image keyword defines.
What you need is a custom docker executor that uses dind image and preinstalled with gcloud sdk. You can build such an image with this Dockerfile:
FROM docker:latest
RUN apk add --no-cache \
bash \
build-base \
curl \
git \
libffi-dev \
openssh \
openssl-dev \
python \
py-pip \
python-dev
RUN pip install docker-compose fabric
RUN curl https://sdk.cloud.google.com | bash -s -- --disable-prompts
The question was asked almost 5 years ago, I am unsure if by that time the image google/cloud-sdk shipped without docker binaries, I can't think of anything else for a docker: command not found error more than it was not available in the standard location. Anyways, today 2022 google/cloud-sdk comes with docker and it can interact with the docker service, and since I ended up here several times after running into problems trying to use docker:dind and google/cloud-sdk, I will add the following:
Is possible to use docker from the google/cloud-sdk image, there is no need to create a custom image for your Gitlab CI. The problem is that docker in google/cloud-sdk tries to connect to the socket in /var/run/docker.sock as is presented in the logs:
$ docker build -t gcr.io/$GCP_PROJECT_ID/test:$CI_COMMIT_SHORT_SHA .
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
Anyways you can also checks in your logs of the service docker:dind that docker listens in a socket (not reachable from the job container) and a tcp port (reachable via the hostname docker). So, you just need to use the tcp port in your docker commands, either by setting the env variable DOCKER_HOST or adding a -H tcp://docker:2375 as in
$ docker -H tcp://docker:2375 build -t gcr.io/$GCP_PROJECT_ID/test:$CI_COMMIT_SHORT_SHA .
Step 1/8 : FROM python:latest
You forgot to inform the image tag at the top.
image: docker:latest
services:
- docker:dind
...
Works for me! :)
See: https://docs.gitlab.com/ce/ci/docker/using_docker_build.html
Related
I have docker-compose file which is working fine locally on my computer. I register gitlab-runner on the same pc and every pipeline where I use any docker command fails with an error: "docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?". I believe I've tried all proposed solutions - nothing works. I use private company network with VPN, maybe it is the issue.
My gitlab-ci.yml
build:docker:
image: docker:19.03.12-dind
variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
DOCKER_PRIVILEGED: "true"
services:
- name: docker:19.03.12-dind
alias: docker
command: ["--tls=false"]
before_script:
- apk update
- apk upgrade
- apk add py3-pip docker
- apk add --no-cache bash python3
- docker build -t $CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME:${CI_COMMIT_REF_SLUG}_server.$CI_PIPELINE_ID ./server/
- docker run -d -p 80:80 docker/getting-started
# - docker-compose -f docker-compose.yml up
my gitlab-runner created as a docker container
using docker exe
If someone faced the same problem please help me understand what am I missing here.
i have a job that starts android UI-tests on GitLab CI/CD. It somehow runs a container from image android-uitests:1.0 from registry. I don't know where and how Gitlab CI/CD runs that image using command "docker run ...", but i need to extend that command and i want to pass some variables (or arguments) in this command.
Here below example of command that i want Gitlab to do:
docker run -d \
-t \
--privileged \
-e "SNAPSHOT_DISABLED"="true" \
-e "QTWEBENGINE_DISABLE_SANDBOX"=1 \
-e "WINDOW"="true" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
-p 5555:5555 -p 5554:5554 -p 5901:5901 \
--name emulator \
android-uitest:1.0
this is a stage and its job with image
ui-tests:
image: registry.myproject:5000/android-uitests:1.0
stage: ui-tests
only:
- merge_requests
- schedules
when: manual
script:
- bash /run-emulator.sh
- adb devices
- adb shell input keyevent 82
- adb shell settings put global window_animation_scale 0 &
- adb shell settings put global transition_animation_scale 0 &
- adb shell settings put global animator_duration_scale 0 &
- ./gradlew mobile:connectedDevDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.package=app.online.tests.uitests
tags:
- androidtest
So another words i want to configure that "under the hood docker run command" that runs my image.
Tell me please how to do that?
Considering you're using a Docker container, I'll assume you're using a Gitlab Runner on Docker executor mode, which means you're essentially running a similar script to this when you don't specify a docker image to run the CI job:
image: docker:19.03.13
variables:
DOCKER_TLS_CERTDIR: "/certs"
services:
- docker:19.03.13-dind
script:
- (your commands)
To understand what's going on, let's break it in multiple steps:
image: docker:19.03.13
(...)
services:
- docker:19.03.13-dind
docker-19.03.13-dind, what's the difference to docker:19.03.13?
why is it a service instead of an image?
DIND means Docker-in-Docker, this part of Gitlab's documentation can explain it in further technical details, but what is important to understand from this part is what is a service on Gitlab's CI context and why they have to specify an additional Docker image when already using a Docker image as a default environment. When you write a service on Gitlab CI, you are able to use its command while you're inside an existing container. e.g. when you want to connect a PostgreSQL (database) container to a backend container you're building, but without having to set up a docker-compose or multiple containers.
Using a docker service to run together with a docker image, it means you can directly use docker run within your job without any additional setup. This previous StackOverflow question explains this question further.
Back to your code, instead of deploying your registry image as a job directly:
ui-tests:
image: registry.myproject:5000/android-uitests:1.0
You may want to first, build your container and upload it to your registry:
image: docker:19.03.12
services:
- docker:19.03.12-dind
variables:
# Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker push $CI_REGISTRY_IMAGE:latest
This snippet will build your Dockerfile in the root folder of your repository and upload it to your Gitlab private (or public, if your project is set as public) image registry. Now you can specify an additional job specifically to do what you want:
Final example
image: docker:19.03.12
stages:
- build
- release
services:
- docker:19.03.12-dind
variables:
# Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
build:
stage: build
script:
- docker pull $CI_REGISTRY_IMAGE:latest || true
- docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker push $CI_REGISTRY_IMAGE:latest
deploy:
stage: release
script:
- docker pull $CI_REGISTRY_IMAGE:latest || true
- docker run -d -t --privileged -e "SNAPSHOT_DISABLED"="true" -e "QTWEBENGINE_DISABLE_SANDBOX"=1 -e "WINDOW"="true" --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" -p 5555:5555 -p 5554:5554 -p 5901:5901 --name emulator $CI_REGISTRY_IMAGE:latest
Why are you using $VARIABLES?
In case of an environment variable may sound confusing, here's the list of default environment variables Gitlab generates for every job it creates.
The last example I cited will result in a Docker container running in the same machine your executor is registered, with the environment variables you have specified.
If you need a practical example, you can use this gitlab-ci.yml of a project of mine as reference.
I want to upload my frontend to sentry, but I need to get the folder using docker commands. However when I use image: getsentry/sentry-cli
docker doesn't works and e.g. in before_script I get error that docker doesn't exist
sentry_job:
stage: sentry_job
image: getsentry/sentry-cli
services:
- docker:18-dind
before_script:
- docker login -u gitlab-ci-token -p "$CI_JOB_TOKEN" registry.gitlab.cz
script:
# script...
. # Get the dist folder from the image
- mkdir frontend_dist
- docker run --rm -v $PWD/frontend_dist:/mounted --entrypoint="" $IMAGE /bin/sh -c "cp /frontend/dist /mounted"
- ls frontend_dist
tags:
- dind
How do I fix that?
To achieve what you want, you need to use a single job (to have the same build context) and specify docker:stable as the job image (along with docker:stable-dind as a service).
This setup is called docker-in-docker and this is the standard way to allow a GitLab CI script to run docker commands (see doc).
Thus, you could slightly adapt your .gitlab-ci.yml code like this:
sentry_job:
stage: sentry_job
image: docker:stable
services:
- docker:stable-dind
variables:
IMAGE: "${CI_REGISTRY_IMAGE}:latest"
before_script:
- docker login -u gitlab-ci-token -p "${CI_JOB_TOKEN}" registry.gitlab.cz
script:
- git pull "$IMAGE"
- mkdir -v frontend_dist
- docker run --rm -v "$PWD/frontend_dist:/mounted" --entrypoint="" "$IMAGE" /bin/sh -c "cp -v /frontend/dist /mounted"
- ls frontend_dist
- git pull getsentry/sentry-cli
- docker run --rm -v "$PWD/frontend_dist:/work" getsentry/sentry-cli
tags:
- dind
Note: the git pull commands are optional (they ensure Docker will use the latest version of the images).
Also, you may need to change the definition of variable IMAGE.
I Integrated Google Kubernetes Engine with my Gitlab repo and created a cluster from gitlab.
Now I am trying to build my docker image using gitlab-ci and push it to Google Container Registry.
But I keep getting this error:
Running with gitlab-runner 11.2.0 (35e8515d)
on gitlab runner vm instance 4e6e33ed
Using Docker executor with image docker:latest ...
Starting service docker:dind ...
Pulling docker image docker:dind ...
Using docker image sha256:edbe3f3ad406799b528fe6633c5553725860566b638cdc252e0520010436869f for docker:dind ...
Waiting for services to be up and running...
*** WARNING: Service runner-4e6e33ed-project-8016623-concurrent-0-docker-0 probably didn't start properly.
Health check error:
ContainerStart: Error response from daemon: Cannot link to a non running container: /runner-4e6e33ed-project-8016623-concurrent-0-docker-0 AS /runner-4e6e33ed-project-8016623-concurrent-0-docker-0-wait-for-service/service (executor_docker.go:1305:0s)
Service container logs:
2018-11-14T13:02:37.917684152Z mount: permission denied (are you root?)
2018-11-14T13:02:37.917743944Z Could not mount /sys/kernel/security.
2018-11-14T13:02:37.917747902Z AppArmor detection and --privileged mode might break.
2018-11-14T13:02:37.917750733Z mount: permission denied (are you root?)
*********
Pulling docker image docker:latest ...
Using docker image sha256:062267097b77e3ecf374b437e93fefe2bbb2897da989f930e4750752ddfc822a for docker:latest ...
Running on runner-4e6e33ed-project-8016623-concurrent-0 via gitlab-runners..
###
# Running before_script commands here
###
# Error Comes on Docker build command
Cannot connect to the Docker daemon at tcp://localhost:2375. Is the docker daemon running?
ERROR: Job failed: exit code 1
This is my gitlab-ci.yml.
services:
- docker:dind
before_script:
- apk update && apk upgrade && apk add --no-cache bash openssh
variables:
DOCKER_DRIVER: overlay2
stages:
- build
build:
stage: build
image: docker:latest
variables:
DOCKER_HOST: tcp://localhost:2375
before_script:
# Pre-requisites required to install google cloud sdk on gitlab runner
- export COMMIT_SHA=$(echo $CI_COMMIT_SHA | cut -c1-8)
- apk update
- apk upgrade
- apk add --update ca-certificates
- apk add --update -t deps curl
- apk del --purge deps
- rm /var/cache/apk/*
script:
# Build our image using docker
- docker build -t $GCP_PROJECT_ID/$CI_PROJECT_NAME:$COMMIT_SHA .
# Write our GCP service account private key into a file
- echo $GCLOUD_SERVICE_KEY | base64 -d > ${HOME}/gcloud-service-key.json
# Download and install Google Cloud SDK
- wget https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz
- tar zxvf google-cloud-sdk.tar.gz && ./google-cloud-sdk/install.sh --usage-reporting=false --path-update=true
# Update gcloud components
- google-cloud-sdk/bin/gcloud --quiet components update
# Give access to gcloud project
- google-cloud-sdk/bin/gcloud auth activate-service-account --key-file ${HOME}/gcloud-service-key.json || die "unable to authenticate service account for gcloud"
# Get current projects credentials to access it
- google-cloud-sdk/bin/gcloud container clusters get-credentials gitlab-kube --zone cluster-zone --project project-id
# Configure container registry to push using docker
- docker login -u _json_key --password-stdin https://gcr.io < ${HOME}/gcloud-service-key.json
# Push the image using docker
- docker push $GCP_PROJECT_ID/$CI_PROJECT_NAME:$COMMIT_SHA
The docker image is building on local.
Also I saw on various posts to update the config.toml file but I dont have one in my project. Where to add that file?
Thanks
First of all : You don't need gcloud to push your images to GCP. The authentication by service account (like you do) is enough. (see: https://cloud.google.com/container-registry/docs/advanced-authentication#json_key_file)
However... If you really want to use the Gloud SDK, use the google/gcloud-sdk image instead of the docker image in your job (Docker is already present inside the google/gcloud-sdk image)
Next, to use the docker deamon, you need to specify the good endpoint. You use the docker:dind service so, the Docker Host will be tcp://docker:2375/ (docker is the hostname of your service)
Finally, your runner will need the "privilegied" mode (To do DIND). (See: https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-docker-executor)
This is a quick example (sorry, not tested), to do that :
stages:
- build
build:
stage: build
image: google/cloud-sdk
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375/
before-script:
- echo $GCLOUD_SERVICE_KEY | base64 -d > ${HOME}/gcloud-service-key.json
script:
- docker build -t $GCP_PROJECT_ID/$CI_PROJECT_NAME:$COMMIT_SHA .
- docker login -u _json_key --password-stdin https://gcr.io < ${HOME}/gcloud-service-key.json
- docker push $GCP_PROJECT_ID/$CI_PROJECT_NAME:$COMMIT_SHA
you should just set privilege = true in gitlab-runner config file, and restart it.
Uncomment the following from values.yaml:
privilege = true
RBAC = true
And then deploy Helm for GKE.
Runners Helmchart values.yaml
I have a custom gitlab ci that I want to compile a Golang app and build a docker image. I have decided to use alpine docker image for the gitlab runner. I can't seam to get docker started. I have tried to manually start docker and get an error ( * WARNING: docker is already starting ) and if I don't manually start the docker service I get (Fails (Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?) Any one else experience this?
This would not be a duplicate question. Gitlab runner runs the docker alpine container in root (verified by running whoami). For the sake of trying I did try usermod -aG docker $(whoami) and had the same output.
.gitlab-ci.yml
image: alpine
variables:
GO_PROJECT: linkscout
before_script:
- apk add --update go git libc-dev docker openrc
- mkdir -p ~/go/src/${GO_PROJECT}
- cp -r ${CI_PROJECT_DIR}/* ~/go/src/${GO_PROJECT}/
- cd ~/go/src/${GO_PROJECT}
- service docker start # * WARNING: docker is already starting
stages:
- compile
- build
compile:
stage: compile
script:
- go get
- go build -a
build:
stage: build
script:
- docker version # If I don't run (service docker start) I get this message: Fails (Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?)
By default you cannot use Docker-in-docker. You should configure your runner like this. Then, as stated in the explanation also use docker:latest as image instead of alpine.