3

I am trying to deploy an docker image, which is located inside the gitlab.com registry, to an external docker host. The docker host was created using docker-machine.

I am using a shared runner and the registry is private, so I will need to login first. To build the images and to run docker I'm using docker in docker.

Here is what I have so far:

---
services:
- name: docker:dind
  command: ["--experimental"]

stages:
#- build # Redacted
- deploy

variables:
  PHP_IMAGE_REF: ${CI_REGISTRY_IMAGE}/php:${CI_BUILD_REF_NAME}
  PHP_IMAGE_LATEST: ${CI_REGISTRY_IMAGE}/php:latest
  NGINX_IMAGE_REF: ${CI_REGISTRY_IMAGE}/nginx:${CI_BUILD_REF_NAME}
  NGINX_IMAGE_LATEST: ${CI_REGISTRY_IMAGE}/nginx:latest
  LETS_ENCRYPT_MAIL: "security@example.com"

# Cache composer dependencies
cache:
  paths:
  - api/vendor

#################################
##   Scripts for development   ##
#################################

# Deploy development to staging
deploy-staging:
  stage: deploy
  image: tmaier/docker-compose
  variables:
    SERVERNAME: staging.example.com
    EMAIL: $LETS_ENCRYPT_MAIL
    STAGE_DOCKER_HOST: "tcp://159.xxx.xxx.xxx:2376"
  cache: {}
  dependencies: []
  before_script:
  # Echo env vars for LetsEncrypt into .env
  - echo "VIRTUAL_HOST=$SERVERNAME" >> .env; echo "LETSENCRYPT_HOST=$SERVERNAME" >> .env; echo "LETSENCRYPT_EMAIL=$EMAIL" >> .env; echo "PHP_IMAGE=$PHP_IMAGE_REF" >> .env; echo "NGINX_IMAGE=$NGINX_IMAGE_REF" >> .env
  script:
  # Login to gitlab registry
  - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} registry.gitlab.com

  # Setup connection to server
  - mkdir -p ~/docker/certs
  - echo ${STAGE_CA} > ~/docker/certs/ca.pem
  - echo ${STAGE_CLIENT_CERT} > ~/docker/certs/cert.pem
  - echo ${STAGE_CLIENT_KEY} > ~/docker/certs/key.pem

  # Shutdown services
  - docker-compose --file docker-compose.prod.yml --verbose --host $STAGE_DOCKER_HOST --tlsverify --tlscacert ~/docker/certs/ca.pem --tlscert ~/docker/certs/cert.pem --tlskey ~/docker/certs/key.pem down -v

  # Remove old and pull new (nginx) image
  - docker rmi $NGINX_IMAGE_REF || echo "nginx image not exist"
  - docker pull $NGINX_IMAGE_REF

  # Remove old and pull new (php+app) image
  - docker rmi $PHP_IMAGE_REF || echo "php image not exist"
  - docker pull $PHP_IMAGE_REF

  # Recreate services
  - docker-compose--file docker-compose.prod.yml --verbose --host $STAGE_DOCKER_HOST --tlsverify --tlscacert ~/docker/certs/ca.pem --tlscert ~/docker/certs/cert.pem --tlskey ~/docker/certs/key.pem up -d
  environment:
    name: staging
    url: https://staging.example.com
  only:
  - development

Unfortunately does the above result in the following error and the pipeline does not succeed. When I run the command: docker-compose --file docker-compose.prod.yml --verbose --host $STAGE_DOCKER_HOST --tlsverify --tlscacert ~/docker/certs/ca.pem --tlscert ~/docker/certs/cert.pem --tlskey ~/docker/certs/key.pem down -v on my local windows machine it works using the same certificates.

urllib3.connectionpool._new_conn: Starting new HTTPS connection (1): 159.xxx.xxx.xxx
Traceback (most recent call last):
  File "/usr/bin/docker-compose", line 11, in <module>
    sys.exit(main())
  File "/usr/lib/python2.7/site-packages/compose/cli/main.py", line 71, in main
    command()
  File "/usr/lib/python2.7/site-packages/compose/cli/main.py", line 124, in perform_command
    project = project_from_options('.', options)
  File "/usr/lib/python2.7/site-packages/compose/cli/command.py", line 41, in project_from_options
    compatibility=options.get('--compatibility'),
  File "/usr/lib/python2.7/site-packages/compose/cli/command.py", line 121, in get_project
    host=host, environment=environment
  File "/usr/lib/python2.7/site-packages/compose/cli/command.py", line 95, in get_client
    version_info = six.iteritems(client.version())
  File "/usr/lib/python2.7/site-packages/docker/api/daemon.py", line 181, in version
    return self._result(self._get(url), json=True)
  File "/usr/lib/python2.7/site-packages/docker/utils/decorators.py", line 46, in inner
    return f(self, *args, **kwargs)
  File "/usr/lib/python2.7/site-packages/docker/api/client.py", line 198, in _get
    return self.get(url, **self._set_request_timeout(kwargs))
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 521, in get
    return self.request('GET', url, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 508, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 618, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/adapters.py", line 506, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='159.xxx.xxx.xxx', port=2376): Max retries exceeded with url: /v1.30/version (Caused by SSLError(SSLError(0, u'unknown error (_ssl.c:3027)'),))
ERROR: Job failed: exit code 1

I'm farily new to devops, so:

  1. what options do I have?
  2. is there another/better way to deploy docker images to a remote docker host?
  3. ~could I solve the problem by using my own runner?~ Tried that. Results more or less in the same.

Note: As far as I understood does dind use the same docker version Ref.

  • 1
    - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} registry.gitlab.com Are you sure this worked for you? docs.gitlab.com/ee/ci/variables as per this documentation the variable names have changed. Can you try passing it in command line manually? – bi0s.kidd0 Oct 10 '18 at 15:02
  • Thanks for pointing that out, unfortunately that wasn't it. – Tom Oct 10 '18 at 15:26
  • Just in case, is your host and the dind image at the same version ? This looks like a cypher mismatch and I assume the dind image doesn't use the allowed cyphers on the remote host – Tensibai Oct 12 '18 at 13:40
  • @Tensibai As far as I understood does dind use the same docker version. Ref: github.com/jpetazzo/dind#which-version-of-docker-does-it-run – Tom Oct 12 '18 at 14:31
  • I won't swear, I'm still unsure why you need dind to use a remote host, I really can't find a reasons for that. But to debug further add a docker info at start of your script and check with the target host docker version – Tensibai Oct 12 '18 at 16:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.