<p>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. </p>

<p>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 <em><a href="https://github.com/jpetazzo/dind" rel="nofollow noreferrer">docker in docker</a></em>. </p>

<p>Here is what I have so far:</p>

<pre><code>---
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" &gt;&gt; .env; echo "LETSENCRYPT_HOST=$SERVERNAME" &gt;&gt; .env; echo "LETSENCRYPT_EMAIL=$EMAIL" &gt;&gt; .env; echo "PHP_IMAGE=$PHP_IMAGE_REF" &gt;&gt; .env; echo "NGINX_IMAGE=$NGINX_IMAGE_REF" &gt;&gt; .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} &gt; ~/docker/certs/ca.pem
  - echo ${STAGE_CLIENT_CERT} &gt; ~/docker/certs/cert.pem
  - echo ${STAGE_CLIENT_KEY} &gt; ~/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
</code></pre>

<p>Unfortunately does the above result in the following error and the pipeline does not succeed. When I run the command: <code>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</code> on my local windows machine it works using the same certificates.</p>

<pre><code>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 &lt;module&gt;
    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
</code></pre>

<h2>I'm farily new to devops, so:</h2>

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

<p>Note: As far as I understood does <em>dind</em> use the same docker version <a href="https://github.com/jpetazzo/dind#which-version-of-docker-does-it-run" rel="nofollow noreferrer">Ref</a>.</p>

CC BY-SA 4.0
2018-10-10T15:02:57.573Z
- docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} registry.gitlab.com 

Are you sure this worked for you?

https://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
CC BY-SA 4.0
2018-10-10T15:26:11.243Z
Thanks for pointing that out, unfortunately that wasn't it.
Tom
CC BY-SA 4.0
2018-10-12T13:40:47.080Z
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
CC BY-SA 4.0
2018-10-12T14:31:08.150Z
@Tensibai As far as I understood does dind use the same docker version. Ref: https://github.com/jpetazzo/dind#which-version-of-docker-does-it-run
Tom
CC BY-SA 4.0
2018-10-12T16:14:44.283Z
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
CC BY-SA 4.0
2018-10-12T17:13:41.197Z
@Tensibai Here is a link to the output of docker info: https://pastebin.com/Anj8MEx9
Do you have a suggestion how to improve the deployment? I tried to setup my own gitlab runner, but that just results in the same error. Even when I set the privileged flag to true and without dind, it fails.
Tom
CC BY-SA 4.0
2018-10-12T21:30:19.110Z
What is the version of the target host? And what is the version of your workstation? This part show a version 18, there's been some work on the tls part for ssl, it could be the root cause.
Tensibai
CC BY-SA 4.0
2018-10-13T11:35:05.740Z
I just checked and the target host, the gitlab shared runner and my workstation are all running on the same version (18.06.1-ce). I also tried to use different servers and running the gitlab runner on one of my machines, without success. @Tensibai should we continue the discussion here? https://chat.stackexchange.com/rooms/54506/chatops
Tom
CC BY-SA 4.0
2019-12-23T09:21:50.390Z
Could you post an answer?
030
CC BY-SA 4.0
2019-12-26T15:35:16.310Z
At the time I never got it running on GitLab.com. What I did was to switch to a own gitlab instance where I've mounted the socket into the container.
Tom
<docker><docker-compose><gitlab-ci-runner>
SSL error when deploying from gitlab runner (GitLab-CI) to remote docker host
Tom
# SSL error when deploying from gitlab runner (GitLab-CI) to remote docker host

(Asked by: username_0 on 2018-10-09)

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 
    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:

what options do I have?
is there another/better way to deploy docker images to a remote docker host?
~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.

**Tags:** docker, docker-compose, gitlab-ci-runner

> **Comments:**
> **username_1**: - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} registry.gitlab.com   Are you sure this worked for you?  https://docs.gitlab.com/ee/ci/variables/  as per this documentation the variable names have changed. Can you try passing it in command line manually?  
> **username_0**: Thanks for pointing that out, unfortunately that wasn't it.  
> **username_2**: 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  
> **username_0**: @username_2 As far as I understood does dind use the same docker version. Ref: https://github.com/jpetazzo/dind#which-version-of-docker-does-it-run  
> **username_2**: 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  
> **username_0**: @username_2 Here is a link to the output of docker info: https://pastebin.com/Anj8MEx9 Do you have a suggestion how to improve the deployment? I tried to setup my own gitlab runner, but that just results in the same error. Even when I set the privileged flag to true and without dind, it fails.  
> **username_2**: What is the version of the target host? And what is the version of your workstation? This part show a version 18, there's been some work on the tls part for ssl, it could be the root cause.  
> **username_0**: I just checked and the target host, the gitlab shared runner and my workstation are all running on the same version (18.06.1-ce). I also tried to use different servers and running the gitlab runner on one of my machines, without success. @username_2 should we continue the discussion here? https://chat.stackexchange.com/rooms/54506/chatops  
> **username_3**: Could you post an answer?  
> **username_0**: At the time I never got it running on GitLab.com. What I did was to switch to a own gitlab instance where I've mounted the socket into the container.  

---

## 0 answers

