@@ -341,6 +341,10 @@ public function imageList($all = false)
341341 * Will resolve with an array of all progress events. These can also be
342342 * accessed via the Promise progress handler.
343343 *
344+ * Pulling a private image from a remote registry will likely require authorization, so make
345+ * sure to pass the $registryAuth parameter, see `self::authHeaders()` for
346+ * more details.
347+ *
344348 * @param string|null $fromImage name of the image to pull
345349 * @param string|null $fromSrc source to import, - means stdin
346350 * @param string|null $repo repository
@@ -349,7 +353,7 @@ public function imageList($all = false)
349353 * @param array|null $registryAuth AuthConfig object (to send as X-Registry-Auth header)
350354 * @return Promise Promise<array> stream of message objects
351355 * @link https://docs.docker.com/reference/api/docker_remote_api_v1.15/#create-an-image
352- * @see self::imageCreateStream()
356+ * @uses self::imageCreateStream()
353357 */
354358 public function imageCreate ($ fromImage = null , $ fromSrc = null , $ repo = null , $ tag = null , $ registry = null , $ registryAuth = null )
355359 {
@@ -369,6 +373,10 @@ public function imageCreate($fromImage = null, $fromSrc = null, $repo = null, $t
369373 * Please note that the resulting stream does not emit any "data" events, so
370374 * you will not be able to pipe() its events into another `WritableStream`.
371375 *
376+ * Pulling a private image from a remote registry will likely require authorization, so make
377+ * sure to pass the $registryAuth parameter, see `self::authHeaders()` for
378+ * more details.
379+ *
372380 * @param string|null $fromImage name of the image to pull
373381 * @param string|null $fromSrc source to import, - means stdin
374382 * @param string|null $repo repository
@@ -378,6 +386,7 @@ public function imageCreate($fromImage = null, $fromSrc = null, $repo = null, $t
378386 * @return ReadableStreamInterface
379387 * @link https://docs.docker.com/reference/api/docker_remote_api_v1.15/#create-an-image
380388 * @see self::imageCreate()
389+ * @uses self::authHeaders()
381390 */
382391 public function imageCreateStream ($ fromImage = null , $ fromSrc = null , $ repo = null , $ tag = null , $ registry = null , $ registryAuth = null )
383392 {
@@ -417,11 +426,16 @@ public function imageHistory($image)
417426 * Will resolve with an array of all progress events. These can also be
418427 * accessed via the Promise progress handler.
419428 *
429+ * Pushing to a remote registry will likely require authorization, so make
430+ * sure to pass the $registryAuth parameter, see `self::authHeaders()` for
431+ * more details.
432+ *
420433 * @param string $image image ID
421434 * @param string|null $tag (optional) the tag to associate with the image on the registry
422435 * @param string|null $registry (optional) the registry to push to (e.g. `registry.acme.com:5000`)
423436 * @param array|null $registryAuth (optional) AuthConfig object (to send as X-Registry-Auth header)
424437 * @return Promise Promise<array> list of image push messages
438+ * @uses self::imagePushStream()
425439 * @link https://docs.docker.com/reference/api/docker_remote_api_v1.15/#push-an-image-on-the-registry
426440 */
427441 public function imagePush ($ image , $ tag = null , $ registry = null , $ registryAuth = null )
@@ -442,11 +456,16 @@ public function imagePush($image, $tag = null, $registry = null, $registryAuth =
442456 * Please note that the resulting stream does not emit any "data" events, so
443457 * you will not be able to pipe() its events into another `WritableStream`.
444458 *
459+ * Pushing to a remote registry will likely require authorization, so make
460+ * sure to pass the $registryAuth parameter, see `self::authHeaders()` for
461+ * more details.
462+ *
445463 * @param string $image image ID
446464 * @param string|null $tag (optional) the tag to associate with the image on the registry
447465 * @param string|null $registry (optional) the registry to push to (e.g. `registry.acme.com:5000`)
448466 * @param array|null $registryAuth (optional) AuthConfig object (to send as X-Registry-Auth header)
449467 * @return ReadableStreamInterface stream of image push messages
468+ * @uses authHeaders()
450469 * @link https://docs.docker.com/reference/api/docker_remote_api_v1.15/#push-an-image-on-the-registry
451470 */
452471 public function imagePushStream ($ image , $ tag = null , $ registry = null , $ registryAuth = null )
@@ -568,6 +587,29 @@ private function json($data)
568587 return json_encode ($ data );
569588 }
570589
590+ /**
591+ * Helper function to send an AuthConfig object via the X-Registry-Auth header
592+ *
593+ * If your API call returns a "500 Internal Server Error" response with the
594+ * message "EOF", it probably means that the endpoint requires authorization
595+ * and you did not supply this header.
596+ *
597+ * Description from Docker's docs (see links):
598+ *
599+ * AuthConfig, set as the X-Registry-Auth header, is currently a Base64
600+ * encoded (JSON) string with the following structure:
601+ * ```
602+ * {"username": "string", "password": "string", "email": "string", "serveraddress" : "string", "auth": ""}
603+ * ```
604+ *
605+ * Notice that auth is to be left empty, serveraddress is a domain/ip without
606+ * protocol, and that double quotes (instead of single ones) are required.
607+ *
608+ * @param array $registryAuth
609+ * @return array
610+ * @link https://docs.docker.com/reference/api/docker_remote_api/ for details about the AuthConfig object
611+ * @link https://github.com/docker/docker/issues/9315 for error description
612+ */
571613 private function authHeaders ($ registryAuth )
572614 {
573615 $ headers = array ();
0 commit comments