From 2f206fff3c25053f3d4ec28999db646cb6301b35 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Mon, 2 Sep 2024 12:03:45 +0200 Subject: [PATCH 1/2] docs: update docker login reference Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- cli/command/registry/login.go | 4 +- docs/reference/commandline/docker.md | 2 +- docs/reference/commandline/login.md | 183 ++++++++++++++++++--------- 3 files changed, 129 insertions(+), 60 deletions(-) diff --git a/cli/command/registry/login.go b/cli/command/registry/login.go index ed99c506e5..b709415dad 100644 --- a/cli/command/registry/login.go +++ b/cli/command/registry/login.go @@ -34,8 +34,8 @@ func NewLoginCommand(dockerCli command.Cli) *cobra.Command { cmd := &cobra.Command{ Use: "login [OPTIONS] [SERVER]", - Short: "Log in to a registry", - Long: "Log in to a registry.\nIf no server is specified, the default is defined by the daemon.", + Short: "Authenticate to a registry", + Long: "Authenticate to a registry.\nDefaults to Docker Hub if no server is specified.", Args: cli.RequiresMaxArgs(1), RunE: func(cmd *cobra.Command, args []string) error { if len(args) > 0 { diff --git a/docs/reference/commandline/docker.md b/docs/reference/commandline/docker.md index c8806878ac..bfa86b8b1d 100644 --- a/docs/reference/commandline/docker.md +++ b/docs/reference/commandline/docker.md @@ -29,7 +29,7 @@ The base command for the Docker CLI. | [`inspect`](inspect.md) | Return low-level information on Docker objects | | [`kill`](kill.md) | Kill one or more running containers | | [`load`](load.md) | Load an image from a tar archive or STDIN | -| [`login`](login.md) | Log in to a registry | +| [`login`](login.md) | Authenticate to a registry | | [`logout`](logout.md) | Log out from a registry | | [`logs`](logs.md) | Fetch the logs of a container | | [`manifest`](manifest.md) | Manage Docker image manifests and manifest lists | diff --git a/docs/reference/commandline/login.md b/docs/reference/commandline/login.md index f61043a1dd..45260ccb0b 100644 --- a/docs/reference/commandline/login.md +++ b/docs/reference/commandline/login.md @@ -1,60 +1,51 @@ # login -Log in to a registry. -If no server is specified, the default is defined by the daemon. +Authenticate to a registry. +Defaults to Docker Hub if no server is specified. ### Options -| Name | Type | Default | Description | -|:--------------------------------------|:---------|:--------|:-----------------------------| -| `-p`, `--password` | `string` | | Password | -| [`--password-stdin`](#password-stdin) | `bool` | | Take the password from stdin | -| `-u`, `--username` | `string` | | Username | +| Name | Type | Default | Description | +|:---------------------------------------------|:---------|:--------|:-----------------------------| +| `-p`, `--password` | `string` | | Password | +| [`--password-stdin`](#password-stdin) | `bool` | | Take the password from stdin | +| [`-u`](#username), [`--username`](#username) | `string` | | Username | ## Description -Log in to a registry. +Authenticate to a registry. -## Examples +You can authenticate to any public or private registry for which you have +credentials. Authentication may be required for pulling and pushing images. +Other commands, such as `docker scout` and `docker build`, may also require +authentication to access subscription-only features or data related to your +Docker organization. -### Login to a self-hosted registry +Authentication credentials are stored in the configured [credential +store](#credential-stores). If you use Docker Desktop, credentials are +automatically saved to the native keychain of your operating system. If you're +not using Docker Desktop, you can configure the credential store in the Docker +configuration file, which is located at `$HOME/.docker/config.json` on Linux or +`%USERPROFILE%/.docker/config.json` on Windows. If you don't configure a +credential store, Docker stores credentials in the `config.json` file in a +base64-encoded format. This method is less secure than configuring and using a +credential store. -If you want to log in to a self-hosted registry you can specify this by -adding the server name. +`docker login` also supports [credential helpers](#credential-helpers) to help +you handle credentials for specific registries. -```console -$ docker login localhost:8080 -``` +### Authentication methods -### Provide a password using STDIN (--password-stdin) - -To run the `docker login` command non-interactively, you can set the -`--password-stdin` flag to provide a password through `STDIN`. Using -`STDIN` prevents the password from ending up in the shell's history, -or log-files. - -The following example reads a password from a file, and passes it to the -`docker login` command using `STDIN`: - -```console -$ cat ~/my_password.txt | docker login --username foo --password-stdin -``` - -### Privileged user requirement - -`docker login` requires you to use `sudo` or be `root`, except when: - -- Connecting to a remote daemon, such as a `docker-machine` provisioned `docker engine`. -- The user is added to the `docker` group. This will impact the security of your system; the `docker` group is `root` equivalent. See [Docker Daemon Attack Surface](https://docs.docker.com/engine/security/#docker-daemon-attack-surface) for details. - -You can log in to any public or private repository for which you have -credentials. When you log in, the command stores credentials in -`$HOME/.docker/config.json` on Linux or `%USERPROFILE%/.docker/config.json` on -Windows, via the procedure described below. +You can authenticate to a registry using a username and access token or +password. Docker Hub also supports a web-based sign-in flow, which signs you in +to your Docker account without entering your password. For Docker Hub, the +`docker login` command uses a device code flow by default, unless the +`--username` flag is specified. The device code flow is a secure way to sign +in. See [Authenticate to Docker Hub using device code](#authenticate-to-docker-hub-using-device-code). ### Credential stores @@ -75,6 +66,10 @@ Helpers are available for the following credential stores: - Microsoft Windows Credential Manager - [pass](https://www.passwordstore.org/) +With Docker Desktop, the credential store is already installed and configured +for you. Unless you want to change the credential store used by Docker Desktop, +you can skip the following steps. + #### Configure the credential store You need to specify the credential store in `$HOME/.docker/config.json` @@ -94,22 +89,22 @@ the credentials from the file and run `docker login` again. #### Default behavior By default, Docker looks for the native binary on each of the platforms, i.e. -"osxkeychain" on macOS, "wincred" on windows, and "pass" on Linux. A special -case is that on Linux, Docker will fall back to the "secretservice" binary if -it cannot find the "pass" binary. If none of these binaries are present, it -stores the credentials (i.e. password) in base64 encoding in the config files -described above. +`osxkeychain` on macOS, `wincred` on Windows, and `pass` on Linux. A special +case is that on Linux, Docker will fall back to the `secretservice` binary if +it cannot find the `pass` binary. If none of these binaries are present, it +stores the base64-encoded credentials in the `config.json` configuration file. #### Credential helper protocol -Credential helpers can be any program or script that follows a very simple protocol. -This protocol is heavily inspired by Git, but it differs in the information shared. +Credential helpers can be any program or script that implements the credential +helper protocol. This protocol is inspired by Git, but differs in the +information shared. The helpers always use the first argument in the command to identify the action. There are only three possible values for that argument: `store`, `get`, and `erase`. The `store` command takes a JSON payload from the standard input. That payload carries -the server address, to identify the credential, the user name, and either a password +the server address, to identify the credential, the username, and either a password or an identity token. ```json @@ -149,10 +144,10 @@ will show if there was an issue. ### Credential helpers -Credential helpers are similar to the credential store above, but act as the -designated programs to handle credentials for specific registries. The default -credential store (`credsStore` or the config file itself) will not be used for -operations concerning credentials of the specified registries. +Credential helpers are similar to [credential stores](#credential-stores), but +act as the designated programs to handle credentials for specific registries. +The default credential store will not be used for operations concerning +credentials of the specified registries. #### Configure credential helpers @@ -162,19 +157,93 @@ the credentials from the default store. Credential helpers are specified in a similar way to `credsStore`, but allow for multiple helpers to be configured at a time. Keys specify the registry domain, and values specify the suffix of the program to use -(i.e. everything after `docker-credential-`). -For example: +(i.e. everything after `docker-credential-`). For example: ```json { "credHelpers": { - "registry.example.com": "registryhelper", - "awesomereg.example.org": "hip-star", - "unicorn.example.io": "vcbait" + "myregistry.example.com": "secretservice", + "docker.internal.example": "pass", } } ``` +## Examples + +### Authenticate to Docker Hub with web-based login + +By default, the `docker login` command authenticates to Docker Hub, using a +device code flow. This flow lets you authenticate to Docker Hub without +entering your password. Instead, you visit a URL in your web browser, enter a +code, and authenticate. + +```console +$ docker login + +USING WEB BASED LOGIN +To sign in with credentials on the command line, use 'docker login -u ' + +Your one-time device confirmation code is: LNFR-PGCJ +Press ENTER to open your browser or submit your device code here: https://login.docker.com/activate + +Waiting for authentication in the browser… +``` + +After entering the code in your browser, you are authenticated to Docker Hub +using the account you're currently signed in with on the Docker Hub website or +in Docker Desktop. If you aren't signed in, you are prompted to sign in after +entering the device code. + +### Authenticate to a self-hosted registry + +If you want to authenticate to a self-hosted registry you can specify this by +adding the server name. + +```console +$ docker login registry.example.com +``` + +By default, the `docker login` command assumes that the registry listens on +port 443 or 80. If the registry listens on a different port, you can specify it +by adding the port number to the server name. + +```console +$ docker login registry.example.com:1337 +``` + +> [!NOTE] +> Registry addresses should not include URL path components, only the hostname +> and (optionally) the port. Registry addresses with URL path components may +> result in an error. For example, `docker login registry.example.com/foo/` +> is incorrect, while `docker login registry.example.com` is correct. +> +> The exception to this rule is the Docker Hub registry, which may use the +> `/v1/` path component in the address for historical reasons. + +### Authenticate to a registry with a username and password + +To authenticate to a registry with a username and password, you can use the +`--username` or `-u` flag. The following example authenticates to Docker Hub +with the username `moby`. The password is entered interactively. + +```console +$ docker login -u moby +``` + +### Provide a password using STDIN (--password-stdin) + +To run the `docker login` command non-interactively, you can set the +`--password-stdin` flag to provide a password through `STDIN`. Using +`STDIN` prevents the password from ending up in the shell's history, +or log-files. + +The following example reads a password from a file, and passes it to the +`docker login` command using `STDIN`: + +```console +$ cat ~/my_password.txt | docker login --username foo --password-stdin +``` + ## Related commands * [logout](logout.md) From 81744d7aa8db51d9381790eebb50a5f82addd260 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Tue, 3 Sep 2024 11:38:16 +0200 Subject: [PATCH 2/2] copynit: s/WEB BASED/WEB-BASED/ Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- cli/internal/oauth/manager/manager.go | 2 +- docs/reference/commandline/login.md | 2 +- e2e/registry/login_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/internal/oauth/manager/manager.go b/cli/internal/oauth/manager/manager.go index a39612a2a4..82f541f48b 100644 --- a/cli/internal/oauth/manager/manager.go +++ b/cli/internal/oauth/manager/manager.go @@ -92,7 +92,7 @@ func (m *OAuthManager) LoginDevice(ctx context.Context, w io.Writer) (*types.Aut return nil, ErrDeviceLoginStartFail } - _, _ = fmt.Fprintln(w, aec.Bold.Apply("\nUSING WEB BASED LOGIN")) + _, _ = fmt.Fprintln(w, aec.Bold.Apply("\nUSING WEB-BASED LOGIN")) _, _ = fmt.Fprintln(w, "To sign in with credentials on the command line, use 'docker login -u '") _, _ = fmt.Fprintf(w, "\nYour one-time device confirmation code is: "+aec.Bold.Apply("%s\n"), state.UserCode) _, _ = fmt.Fprintf(w, aec.Bold.Apply("Press ENTER")+" to open your browser or submit your device code here: "+aec.Underline.Apply("%s\n"), strings.Split(state.VerificationURI, "?")[0]) diff --git a/docs/reference/commandline/login.md b/docs/reference/commandline/login.md index 45260ccb0b..3a360c4b25 100644 --- a/docs/reference/commandline/login.md +++ b/docs/reference/commandline/login.md @@ -180,7 +180,7 @@ code, and authenticate. ```console $ docker login -USING WEB BASED LOGIN +USING WEB-BASED LOGIN To sign in with credentials on the command line, use 'docker login -u ' Your one-time device confirmation code is: LNFR-PGCJ diff --git a/e2e/registry/login_test.go b/e2e/registry/login_test.go index 523e00d065..8cc353e4af 100644 --- a/e2e/registry/login_test.go +++ b/e2e/registry/login_test.go @@ -30,7 +30,7 @@ func TestOauthLogin(t *testing.T) { assert.NilError(t, err) output, _ := io.ReadAll(p) - assert.Check(t, strings.Contains(string(output), "USING WEB BASED LOGIN"), string(output)) + assert.Check(t, strings.Contains(string(output), "USING WEB-BASED LOGIN"), string(output)) } func TestLoginWithEscapeHatch(t *testing.T) {