ok, I got to the point I need to do something like this in Gitlab CI :
(Note: I oversimplified it so it has actual purpose running this)
.gitlab-ci.yml
workflow:
rules:
- when: always
image: "docker:20.10.7"
variables:
DOCKER_TLS_CERTDIR: "/certs"
services:
- "docker:20.10.7-dind"
integration-tests:
stage: test
script:
- bin/run
So the Gitlab runner will use docker image and the dind service.
And the bin/run script is :
#!/usr/bin/env sh
# shellcheck disable=SC1091
set -eux
apk update
apk add bind-tools
echo "${DOCKER_HOST:=}"
docker container ls
host docker || true
nc -v docker 2376 || true
docker run --rm \
-v "${DOCKER_CERT_PATH:=}:${DOCKER_CERT_PATH:=}:ro" \
-e DOCKER_HOST="${DOCKER_HOST:=}" \
-e DOCKER_CERT_PATH="${DOCKER_CERT_PATH:=}" \
-e DOCKER_TLS_VERIFY="${DOCKER_TLS_VERIFY:=}" \
--network "host" \
"docker:20.10.7" docker container ls
Here I want to be able to use docker to run a nested docker container and call nested docker functions.
Here is the result :
$ bin/run
+ apk update
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz
v3.13.12-94-g0551adbecc [https://dl-cdn.alpinelinux.org/alpine/v3.13/main]
v3.13.12-94-g0551adbecc [https://dl-cdn.alpinelinux.org/alpine/v3.13/community]
OK: 13912 distinct packages available
+ apk add bind-tools
(1/17) Installing fstrm (0.6.0-r1)
...
(17/17) Installing bind-tools (9.16.33-r0)
Executing busybox-1.32.1-r6.trigger
OK: 24 MiB in 37 packages
+ echo tcp://docker:2376
tcp://docker:2376
+ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+ host docker
Host docker not found: 3(NXDOMAIN)
+ true
+ nc -v docker 2376
docker (172.17.0.3:2376) open
+ docker run --rm -e 'DOCKER_HOST=tcp://docker:2376' --network host docker:20.10.7 docker container ls
Unable to find image 'docker:20.10.7' locally
20.10.7: Pulling from library/docker
...
9d806bc20361: Pull complete
Digest: sha256:bfc499cef26daa22da31b76be1752813a6921ee1fa1dd1f56d4fdf19c701d332
Status: Downloaded newer image for docker:20.10.7
error during connect: Get http://docker:2376/v1.24/containers/json: dial tcp: lookup docker on 169.254.169.254:53: no such host
Cleaning up project directory and file based variables
00:00
ERROR: Job failed: exit code 1
What I don't understand :
Why is the nc command working but the host command failed in the job container ?
Why is docker service not resolved in the nested container ?
Ok I figured out my problem, I was missing the FF_NETWORK_PER_BUILD=true variable.
.gitlab-ci.yml
workflow:
rules:
- when: always
image: "docker:20.10.7"
variables:
DOCKER_TLS_CERTDIR: "/certs"
services:
- "docker:20.10.7-dind"
integration-tests:
stage: test
variables:
FF_NETWORK_PER_BUILD: "true"
script:
- bin/run
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'm installing a personal runner for my projects.
sudo docker run --rm -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register \ --non-interactive \ --executor "docker" \ --docker-image docker:stable \ --url "https://gitlab.com" \ --registration-token "my-token" \
--description "docker-runner privileged" \ --tag-list "docker,aws, gara" \ --run-untagged="true" \ --locked="false" \
--access-level="not_protected" \ --docker-privileged
with this runner i can successfully the step test, build and analysis of my maven projet.
For step docker build, I always have:
Cannot connect to the Docker daemon at tcp://docker:2375. Is the
docker daemon running? ERROR: Job failed: exit code 1
Full log:
Running with gitlab-runner 13.1.1 (6fbc7474) on docker-runner
privileged GYDNagVx Preparing the "docker" executor 00:21 Using Docker
executor with image docker:latest ... Starting service docker:dind ...
Pulling docker image docker:dind ... Using docker image
sha256:b3893e48cf281b58a763fb90904fd5d63595f9e5ae5736ee2d892a2dea6a371a
for docker:dind ... Waiting for services to be up and running...
Pulling docker image docker:latest ... Using docker image
sha256:809cc4dba987efb4641d5b6fef38f47abcde1bc5c5e9850616f0ed3552737e8c
for docker:latest ... Preparing environment 00:04 Running on
runner-gydnagvx-project-15477556-concurrent-0 via e59663817b22...
Getting source from Git repository 00:07 Fetching changes with git
depth set to 50... Reinitialized existing Git repository in
/builds/gara-project/back-end-micro-services/msearch/.git/ Checking
out 80fcdd6e as develop... Removing target/ Skipping Git submodules
setup Downloading artifacts 00:18 Downloading artifacts for
maven-build (788252737)... Downloading artifacts from coordinator...
ok id=788252737 responseStatus=200 OK token=jjUorX2D Executing
"step_script" stage of the job script 00:27 $ docker login -u
"${registry_user}" -p "${registry_pass}" "${registry_url}" WARNING!
Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in
/root/.docker/config.json. Configure a credential helper to remove
this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded $ docker build -t
"${registry_url}/${image_name}:${image_tag}" . Cannot connect to the
Docker daemon at tcp://docker:2375. Is the docker daemon running?
ERROR: Job failed: exit code 1
It seems to be a common error but none of solutions found over internet works for me.
My gitla-ci.yml file:
include:
- local: '/templates/.gitlab-ci-common-template.yml'
variables:
SPRING_PROFILES_ACTIVE: test
MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
DOCKER_TLS_CERTDIR: ""
default:
image: maven:3.6.3-jdk-8-slim
cache:
key: "$CI_COMMIT_REF_NAME"
paths:
- .m2/repository/
- target/
stages:
- test
- build
- analysis
- docker
- scan
- deploy
- delivery
maven-test:
stage: test
extends:
- .ci_only
- .skip_build
script:
- mvn test
artifacts:
reports:
junit:
- target/surefire-reports/TEST-*.xml
maven-build:
stage: build
extends:
- .ci_only
- .skip_build
script:
- "./mvnw -Pint clean install -DskipTests=true"
artifacts:
paths:
- target/*
expire_in: 1 week
docker-build:
image: docker:latest
services:
- docker:19.03.0-dind
cache: {}
before_script:
- docker login -u "${registry_user}" -p "${registry_pass}" "${registry_url}"
stage: docker
dependencies:
- maven-build
extends:
- .skip_build
- .ci_only
script:
- docker build -t "${registry_url}/${image_name}:${image_tag}" .
- docker run -d --name ${image_tag} "${registry_url}/${image_name}:${image_tag}"
- sleep 60 && docker ps && docker logs ${image_tag}
- if [ $(docker inspect -f '{{.State.Running}}' ${image_tag}) = "true" ]; then echo "Application well started"; else exit 1; fi
- docker rm -f ${image_tag}
- docker push "${registry_url}/${image_name}:${image_tag}"
docker_release_image:
image: docker:latest
stage: delivery
before_script:
- docker login -u "${registry_user}" -p "${registry_pass}" "${registry_url}"
# - docker login -u "${registry_prod_user}" -p "${registry_prod_pass}" "${registry_prod_url}"
services:
- docker:19.03.0-dind
script:
- docker pull "${registry_url}/${image_name}:${image_tag}"
- docker tag "${registry_url}/${image_name}:${image_tag}" "${registry_url}/${image_name}:${CI_COMMIT_TAG/*v/}"
- docker tag "${registry_url}/${image_name}:${image_tag}" "${registry_url}/${image_name}:latest"
# - docker tag "${registry_url}/${image_name}:${image_tag}" "${registry_prod_url}/${image_name}:${CI_COMMIT_TAG/*v/}"
- docker push "${registry_url}/${image_name}:${CI_COMMIT_TAG/*v/}"
- docker push "${registry_url}/${image_name}:latest"
# - docker push "${registry_prod_url}/${image_name}:${CI_COMMIT_TAG/*v/}"
- docker rmi "${registry_url}/${image_name}:${image_tag}"
when: manual
extends:
- .only_tag_on_master
Please how could I correct it ?
Thanks
I'm having my first steps into Docker/CI/CD.
For that, I'm trying to deploy a raw create-react-app to my Digital Ocean droplet (Docker One-Click Application) using Gitlab CI. Those are my files:
Dockerfile.yml
# STAGE 1 - Building assets
FROM node:alpine as building_assets_stage
WORKDIR /workspace
## Preparing the image (installing dependencies and building static files)
COPY ./package.json .
RUN yarn install
COPY . .
RUN yarn build
# STAGE 2 - Serving static content
FROM nginx as serving_static_content_stage
ENV NGINX_STATIC_FILE_SERVING_PATH=/usr/share/nginx/html
EXPOSE 80
COPY --from=building_assets_stage /workspace/build ${NGINX_STATIC_FILE_SERVING_PATH}
docker-compose.yml
## Use a Docker image with "docker-compose" installed on top of it.
image: tmaier/docker-compose:latest
services:
- docker:dind
variables:
DOCKER_CONTAINER_NAME: ${CI_PROJECT_NAME}
DOCKER_IMAGE_TAG: ${SECRETS_DOCKER_LOGIN_USERNAME}/${CI_PROJECT_NAME}:latest
before_script:
## Install ssh agent (so we can access the Digital Ocean Droplet) and run it.
- apk update && apk add openssh-client
- eval $(ssh-agent -s)
## Write the environment variable value to the agent store, create the ssh directory and give the right permissions to it.
- echo "$SECRETS_DIGITAL_OCEAN_DROPLET_SSH_KEY" | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
## Make sure that ssh will trust the new host, instead of asking
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
## Test that everything is setup correctly
- ssh -T ${SECRETS_DIGITAL_OCEAN_DROPLET_USER}#${SECRETS_DIGITAL_OCEAN_DROPLET_IP}
stages:
- deploy
deploy:
stage: deploy
script:
## Login this machine into Docker registry, creates a production build and push it to the registry.
- docker login -u ${SECRETS_DOCKER_LOGIN_USERNAME} -p ${SECRETS_DOCKER_LOGIN_PASSWORD}
- docker build -t ${DOCKER_IMAGE_TAG} .
- docker push ${DOCKER_IMAGE_TAG}
## Connect to the Digital Ocean droplet, stop/remove all running containers, pull latest image and execute it.
- ssh -T ${SECRETS_DIGITAL_OCEAN_DROPLET_USER}#${SECRETS_DIGITAL_OCEAN_DROPLET_IP}
- docker ps -q --filter "name=${DOCKER_CONTAINER_NAME}" | grep -q . && docker stop ${DOCKER_CONTAINER_NAME} && docker rm -fv ${DOCKER_CONTAINER_NAME} && docker rmi -f ${DOCKER_IMAGE_TAG}
- docker run -d -p 80:80 --name ${DOCKER_CONTAINER_NAME} ${DOCKER_IMAGE_TAG}
# Everything works, exit.
- exit 0
only:
- master
In a nutshell, on Gitlab CI, I do the following:
(before_install) Install ssh agent and copy my private SSH key to this machine, so we can connect to the Digital Ocean Droplet;
(deploy) I build my image and push it to my public docker hub repository;
(deploy) I connect to my Digital Ocean Droplet via SSH, pull the image I've just built and run it.
The problem is that if I do everything from my computer's terminal, the container is created and the application is deployed successfully.
If I execute it from the Gitlab CI task, the container is generated but nothing is deployed because the container dies right after (click here to see CI job output).
I can guarantee that the container is being erase because if I manually SSH the server and docker ps -a, it doesn't listen anything.
I'm mostly confused by the fact that this image CMD is CMD ["nginx", "-g", "daemon off;"], which shouldn't make my container gets deleted because it has a process running.
What I'm doing wrong? I'm lost.
Thank you in advance.
My question was answered by d g - thank you very much!
The problem relies on the fact that I was connecting to my Digital Ocean Droplet via SSH and executing commands inside using its bash, when I should be passing the entire command to be executed as an argument to the ssh connection instruction.
Changed my .gitlab.yml file from:
## Connect to the Digital Ocean droplet, stop/remove all running containers, pull latest image and execute it.
- ssh -T ${SECRETS_DIGITAL_OCEAN_DROPLET_USER}#${SECRETS_DIGITAL_OCEAN_DROPLET_IP}
- docker ps -q --filter "name=${DOCKER_CONTAINER_NAME}" | grep -q . && docker stop ${DOCKER_CONTAINER_NAME} && docker rm -fv ${DOCKER_CONTAINER_NAME} && docker rmi -f ${DOCKER_IMAGE_TAG}
- docker run -d -p 80:80 --name ${DOCKER_CONTAINER_NAME} ${DOCKER_IMAGE_TAG}
To:
# Execute as follow:
# ssh -t digital-ocean-server "docker cmd1; docker cmd2;
- ssh -T ${SECRETS_DIGITAL_OCEAN_DROPLET_USER}#${SECRETS_DIGITAL_OCEAN_DROPLET_IP} "docker ps -q --filter \"name=${DOCKER_CONTAINER_NAME}\" | grep -q . && docker stop ${DOCKER_CONTAINER_NAME} && docker rm -fv ${DOCKER_CONTAINER_NAME} && docker rmi -f ${DOCKER_IMAGE_TAG}; docker run -d -p 80:80 --name ${DOCKER_CONTAINER_NAME} ${DOCKER_IMAGE_TAG}"
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
I have several php apps with similar requirements, dockerized gitlab runner and one docker image for my apps.
What is the best solution for autostart review apps?
I started runner with connected docker.sock and additionaly added volume with my projects /home/devenv/ for runner attached in gitlab runner config.toml:
[runners.docker]
tls_verify = false
image = "docker:latest"
privileged = true
disable_cache = false
volumes = ["/cache", "/home/devenv:/home/devenv"]
Test and build works fine, using image: myrepo.com/group/image in .gitlab-ci.yml
Then my deploy section fails with error.
Deploy section:
deploy to review:
image: docker:latest
services:
- docker:dind
stage: deploy
script:
- rm -rf /home/devenv/$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME-$CI_BUILD_REF_NAME
- mkdir /home/devenv/$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME-$CI_BUILD_REF_NAME
- cp -r ./* /home/devenv/$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME-$CI_BUILD_REF_NAME/
- docker stop $CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME-$CI_BUILD_REF_NAME
- docker rm $CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME-$CI_BUILD_REF_NAME
- docker run -d --env ENDLESS_RUN="1" --env VIRTUAL_HOST="$CI_BUILD_REF_NAME.$CI_PROJECT_NAME.$CI_PROJECT_NAMESPACE.e.mydomain.com" --name "$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME-$CI_BUILD_REF_NAME" -v /home/devenv/$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME-$CI_BUILD_REF_NAME/httpdocs:/home/web/httpdocs -v /home/devenv/$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME-$CI_BUILD_REF_NAME/logs:/var/logs myrepo.com/group/image
- docker exec $CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME-$CI_BUILD_REF_NAME cd /home/httpdocs/ && npm install && bower install && gulp build
environment:
name: review/$CI_BUILD_REF_NAME
url: http://$CI_BUILD_REF_NAME.$CI_PROJECT_NAME.$CI_PROJECT_NAMESPACE.e.mydomain.com
only:
- branches
except:
- master
Error on run command:
$ docker run -d --env ENDLESS_RUN="1" --env VIRTUAL_HOST="$CI_BUILD_REF_NAME.$CI_PROJECT_NAME.$CI_PROJECT_NAMESPACE.e.mydomain.com" --name "$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME-$CI_BUILD_REF_NAME" -v /home/devenv/$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME-$CI_BUILD_REF_NAME/httpdocs:/home/bitrix/www -v /home/devenv/$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME-$CI_BUILD_REF_NAME/logs:/var/logs myrepo.com/group/image
Unable to find image 'myrepo.com/group/image:latest' locally
latest: Pulling from group/image
90577c79babf: Pulling fs layer
a74e2caa985d: Pulling fs layer
8729c6ccfcfb: Pulling fs layer
f160b3e340fb: Pulling fs layer
9c19c344e2fa: Pulling fs layer
74a07af12073: Pulling fs layer
...
...
Status: Downloaded newer image for myrepo.com/group/image:latest
docker: An error occurred trying to connect: Post http://docker:2375/v1.24/containers/create?name=olimpia-iam-master: EOF.
See 'docker run --help'.
ERROR: Build failed: exit code 125
DIND doesn't allow mounting volumes from one container into another. For what you're trying to do you'll have to share the host docker service with the container