0

In order to facilitate a remote CICD process for our applications I am trying to access our Docker Hub/Registry to be able to list, tag and push images. Starting with the basics using the following from a bash script:

TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${UNAME}'", "password": "'${UPASS}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)

I created some cURL in PHP, trying to get a token for Docker Hub:

$user = 'xxxxxxxx';
$pass = 'xxxxxxxx';
$namespace = 'xxxxxxxx';
$headers = array();
$headers[] = 'Content-Type: application/json';

$url = "https://hub.docker.com/v2/users/login/";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, "$user:$pass");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

$return = curl_exec($ch);
curl_close ($ch);

var_dump($return);

The response:

bool(false)

If I enter the URL https://regsitry.hub.docker.com/v2/users/login/ directly into the address bar of the browser I get:

{"username": ["This field is required."], "password": ["This field is required."]}

If I eliminate the username and password from the cURL request I still get the bool(false) response. There is very little (actually I found next to nothing) for using PHP to interact with the Docker Hub/Registry API(s). There are no errors in my error logs.

Am I missing something obvious? Or is there no way to interact with the Docker API via PHP?

RïshïKêsh Kümar
  • 4,734
  • 1
  • 24
  • 36
Jay Blanchard
  • 34,243
  • 16
  • 77
  • 119
  • Hi i guess set -e is a pipeline and stops the execution of a script if a command or pipeline has an error but with curl in PHP the pipeline isn't garanted as a lot bug reported about this option on CURL but take a look if you can add this CURLMOPT_PIPELINING no sure of the result. –  Sep 26 '17 at 17:29
  • Why did you turn the JSON auth payload into HTTP auth? – Sammitch Sep 26 '17 at 17:53
  • `set -e` is for environment variables @headmax – Jay Blanchard Sep 26 '17 at 18:13
  • As @Sammitch posted the answer, what you are trying is for sites with Basic Auth and not for a JSON payload. – Tarun Lalwani Sep 26 '17 at 18:45
  • @Jay Blanchard Yes and set -e is using to send the credentials on the shell pipeline you can to set -o pipefail which can be used to propagate errors. https://stackoverflow.com/questions/19622198/what-does-set-e-mean-in-a-bash-script. –  Sep 26 '17 at 18:53

1 Answers1

2

This:

curl_setopt($ch, CURLOPT_USERPWD, "$user:$pass");

is not equivalent to:

-d '{"username": "'${UNAME}'", "password": "'${UPASS}'"}'

but this is:

curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['username'=>$user, 'password'=>$pass]));

and it works.

Sammitch
  • 30,782
  • 7
  • 50
  • 77