Moritz Friedrich
Moritz Friedrich

Reputation: 1481

docker command not available in custom pipe for BitBucket Pipeline

I'm working on a build step that handles common deployment tasks in a Docker Swarm Mode cluster. As this is a common problem for us and for others, we've shared this build step as a BitBucket pipe: https://bitbucket.org/matchory/swarm-secret-pipe/ The pipe needs to use the docker command to work with a remote Docker installation. This doesn't work, however, because the docker executable cannot be found when the pipe runs.

The following holds true for our test repository pipeline:

The pipe is pretty standard and uses a recent Alpine image; nothing special in that regard. The PATH is never overwritten. Now for the fun part: If I do ls /usr/local/bin/docker inside the pipe, it shows an empty directory:

ls /usr/local/bin
total 16K 
drwxr-xr-x 1 root root 4.0K May 13 13:06 .
drwxr-xr-x 1 root root 4.0K Apr 4 16:06 ..
drwxr-xr-x 2 root root 4.0K Apr 29 09:30 docker
ls /usr/local/bin/docker
total 8K 
drwxr-xr-x 2 root root 4.0K Apr 29 09:30 .
drwxr-xr-x 1 root root 4.0K May 13 13:06 ..
ls: /usr/local/bin/docker/docker: No such file or directory

As far as I understand pipelines and Docker, /usr/local/bin/docker should be the docker binary file. Instead, it appears to be an empty directory for some reason. What is going on here?

I've also looked at other, official, pipes. They don't do anything differently, but seem to be using the docker command just fine (eg. the Azure pipe).

Upvotes: 1

Views: 1379

Answers (1)

Moritz Friedrich
Moritz Friedrich

Reputation: 1481

After talking to BitBucket support, I solved the issue. As it turns out, if the docker context is changed, any docker command is sent straight to the remote docker binary, which (on our services) lives at a different path than in BitBucket Pipelines!
As we changed the docker context before using the pipe, and the docker instance mounted into the pipe still has the remote context set, but the pipe searches for the docker binary at another place, the No such file or directory error is thrown.

TL;DR: Always restore the default docker host/context before passing control to a pipe, e.g.:

script:
  - export DEFAULT_DOCKER_HOST=$DOCKER_HOST
  - unset DOCKER_HOST
  - docker context create remote --docker "host=ssh://${DEPLOY_SSH_USER}@${DEPLOY_SSH_HOST}"
  - docker context use remote

  # do your thing

  - export DOCKER_HOST=$DEFAULT_DOCKER_HOST # <------ restore the default host
  - pipe: matchory/swarm-secret-pipe:1.3.16

Upvotes: 0

Related Questions