Triggering Docker Hub builds from CircleCI

nodejs
docker
circle.yml

#1

Hey there, I’m currently trying to setup a workflow where CircleCI tests our npm front end code, then if the test is successful it should trigger our Docker Hub build.(currently we’re just spoofing it till we can get deployment to work correectly.)

So our stack is basically:
CircleCI --> Docker Hub --> Docker Cloud

What we want to do is give our developers more instantaneous feedback instead of having to wait on a Docker Image to build and then deploy before we know if their code is broken or not.

My circle.yml file looks as follow:

machine:
  node:
    version: 5.10.1

dependencies:
  cache_directories:
    - node_modules
#  override:
#    - npm prune && npm install
#    - npm run build
test:
  override:
    - echo "Testing docker hub build trigger"


deployment:
  staging:
    branch: develop
    commands:
      - $TRIGGER

So that’s the gist of the current circle.yml file.

The TRIGGER environment variable is declared manually on the CircleCI web front.
It looks as follow:
curl -H "Content-Type: application/json" --data '{"docker_tag": "${CIRCLE_BRANCH}"}' -X POST https://registry.hub.docker.com/u/[censored]/trigger/[censored trigger]/

I have tried escaping double quotes:
curl -H \"Content-Type: application/json\" --data '{\"docker_tag\": \"${CIRCLE_BRANCH}\"}' -X POST https://registry.hub.docker.com/u/[censored again]/trigger/[just cause its a private repo]/

All in all I’ve tried adding the -g tag to the cURL command as well but it seems like I get the same errors from CircleCI which are:

curl: (6) Could not resolve host: application
curl: (3) [globbing] unmatched close brace/bracket in column 10
OK

So what happens then in the end is it literally triggers either no builds, or all of the builds. Obviously with Docker Cloud running off of my Docker Hub images and automatically continuously deploying my images as they update I don’t want to randomly just update my latest release or master branches if I’m pushing code to my develop branch.

Any ideas perhaps on how I could go about fixing this? I have gone as far as trying to use a ./deploy.sh script but the idea is to not add any extra files to the repository if possible…


#2

Hi @anton-dealmeida. Facing something similar to your problem (but with Docker cloud).

Were you able to resolve your issue? If you were, mind sharing how you fixed it.

Cheers, and thanks in advance.
Dela.


#3

Hi @deyoungster,

Yes. I did figure this out. So, using NPM I went about creating a deploy.js file that I run when deploying.

I still used the trigger but I made it a bit more verbose. I’ll answer my question with an example.


#4

So, I found a workaround for my NodeJS projects.

In the root of my project, I just create a deploy.js file. Then, for deployment or as my last step or deployment job, depending on the CircleCI version we are looking at, I make use of the node environment to deploy my project. CircleCI has a lot of environment variables that it exports when starting a container, so I just make use of as many of them as possible, I place the auth token for the repo on Docker Hub / Registry inside of an environment variable and then we get a reusable idempotent script like the one below.

var request = require('request');

var project = process.env.CIRCLE_PROJECT_REPONAME;
var token = process.env.DOCKER_HUB_TOKEN;

var headers = {
  'Content-Type': 'application/json'
};

var dataString = `{"docker_tag": "${process.env.CIRCLE_BRANCH}"}`;

var options = {
  url: 'https://registry.hub.docker.com/u/responsive/' + project + '/trigger/' + token + '/',
  method: 'POST',
  headers: headers,
  body: dataString
};

function callback(error, response, body) {
  if (!error && response.statusCode == 200) {
    console.log(body);
  }
}

request(options, callback);

All you need to do then is in your package.json file, add a command:

  "scripts": {
   # other random scripts up here
    "deploy": "node deploy.js",
   # or down here
  },

Then, lastly for my circle.yml file or .circleci/config.yml file I just make sure to run this shell command:

npm run deploy

#5

Thanks for the update @anton-dealmeida. Really appreciate your detailed solution! :slight_smile:


#6

My pleasure!

Let me know if you have any other questions :slight_smile:


#7