Skip to content

Commit 4fd121d

Browse files
authored
Merge pull request #531 from docker/feat/docs
feat: refine docs
2 parents 37a8a12 + f0417af commit 4fd121d

8 files changed

Lines changed: 174 additions & 129 deletions

File tree

plugins/pass/command.go

Lines changed: 11 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package pass
1616

1717
import (
1818
"context"
19+
_ "embed"
1920
"errors"
2021
"os"
2122
"strings"
@@ -49,82 +50,22 @@ Examples:
4950
{{.Example}}{{end}}
5051
`
5152

52-
const rootExample = `
53-
### Using keychain secrets in containers
54-
55-
Create a secret:
56-
57-
` + "```" + `console
58-
$ docker pass set GH_TOKEN=123456789
59-
` + "```" + `
60-
61-
Create a secret from STDIN:
62-
63-
` + "```" + `console
64-
echo "my_val" | docker pass set GH_TOKEN
65-
` + "```" + `
66-
67-
Run a container that uses the secret:
68-
69-
` + "```" + `console
70-
$ docker run -e GH_TOKEN= -dt --name demo busybox
71-
` + "```" + `
72-
73-
Inspect the secret from inside the container:
74-
75-
` + "```" + `console
76-
$ docker exec demo sh -c 'echo $GH_TOKEN'
77-
123456789
78-
` + "```" + `
79-
80-
Explicitly assign a secret to a different environment variable:
81-
82-
` + "```" + `console
83-
$ docker run -e GITHUB_TOKEN=se://GH_TOKEN -dt --name demo busybox
84-
` + "```" + `
85-
86-
### Using keychain secrets in Compose
87-
88-
Store the secrets:
89-
90-
` + "```" + `console
91-
$ docker pass set myapp/anthropic/api-key=sk-ant-...
92-
$ docker pass set myapp/postgres/password=s3cr3t
93-
` + "```" + `
94-
95-
` + "```" + `yaml
96-
services:
97-
api:
98-
image: service1
99-
environment:
100-
- ANTHROPIC_API_KEY=se://myapp/anthropic/api-key
101-
- POSTGRES_PASSWORD=se://myapp/postgres/password
102-
103-
worker:
104-
image: service2
105-
command: worker
106-
environment:
107-
- ANTHROPIC_API_KEY=se://myapp/anthropic/api-key
108-
109-
db:
110-
image: postgres:17
111-
environment:
112-
- POSTGRES_PASSWORD=se://myapp/postgres/password
113-
` + "```"
53+
//go:embed examples.md
54+
var rootExample string
11455

11556
// Root returns the root command for the docker-pass CLI plugin
11657
func Root(ctx context.Context, s store.Store, info commands.VersionInfo) *cobra.Command {
11758
cmd := &cobra.Command{
11859
Use: "pass set|get|ls|rm|run",
11960
Short: "Manage your local OS keychain secrets.",
120-
Long: `Docker Pass is a helper for securely storing secrets in your local OS keychain and injecting them into containers when needed.
121-
It uses platform-specific credential storage:
122-
123-
- Windows: Windows Credential Manager API
124-
- macOS: Keychain services API
125-
- Linux: org.freedesktop.secrets API (requires DBus + gnome-keyring or kdewallet)
126-
127-
Secrets can be injected into running containers at runtime using the se:// URI scheme.`,
61+
Long: "Docker Pass is a helper for securely storing secrets in your local OS keychain and injecting them into containers when needed.\n" +
62+
"It uses platform-specific credential storage:\n" +
63+
"\n" +
64+
" - Windows: Windows Credential Manager API\n" +
65+
" - macOS: Keychain services API\n" +
66+
" - Linux: `org.freedesktop.secrets` API (requires DBus + `gnome-keyring` or `kdewallet`)\n" +
67+
"\n" +
68+
"Secrets can be injected into running containers at runtime using the `se://` URI scheme.",
12869
Example: strings.TrimSpace(rootExample),
12970
SilenceUsage: true,
13071
TraverseChildren: true,

plugins/pass/commands/rm.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package commands
1616

1717
import (
1818
"context"
19+
_ "embed"
1920
"errors"
2021
"fmt"
2122
"io"
@@ -27,6 +28,9 @@ import (
2728
"github.com/docker/secrets-engine/store"
2829
)
2930

31+
//go:embed rm_example.md
32+
var rmExample string
33+
3034
type rmOpts struct {
3135
All bool
3236
}
@@ -37,15 +41,8 @@ func RmCommand(kc store.Store) *cobra.Command {
3741
Use: "rm name1 name2 ...",
3842
Aliases: []string{"delete", "erase", "remove"},
3943
Short: "Remove secrets from local keychain.",
40-
Long: "Removes one or more named secrets from the local OS keychain.\nUse --all to remove every stored secret at once.",
41-
Example: `### Remove a specific secret:
42-
docker pass rm GH_TOKEN
43-
44-
### Remove multiple secrets:
45-
docker pass rm GH_TOKEN NPM_TOKEN
46-
47-
### Remove all secrets:
48-
docker pass rm --all`,
44+
Long: "Removes one or more named secrets from the local OS keychain. Use `--all` to remove every stored secret at once.",
45+
Example: strings.Trim(rmExample, "\n"),
4946
RunE: func(cmd *cobra.Command, args []string) error {
5047
idList, err := validateArgs(args, opts)
5148
if err != nil {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
### Remove a specific secret:
2+
3+
```console
4+
$ docker pass rm GH_TOKEN
5+
```
6+
7+
### Remove multiple secrets:
8+
9+
```console
10+
$ docker pass rm GH_TOKEN NPM_TOKEN
11+
```
12+
13+
### Remove all secrets:
14+
15+
```console
16+
$ docker pass rm --all
17+
```

plugins/pass/commands/run.go

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package commands
1616

1717
import (
1818
"context"
19+
_ "embed"
1920
"errors"
2021
"fmt"
2122
"maps"
@@ -48,19 +49,8 @@ func (e *ExitCodeError) Error() string {
4849
return fmt.Sprintf("child exited with code %d", e.Code)
4950
}
5051

51-
const runExample = `
52-
### Run a command with one secret in its environment:
53-
SE_TOKEN=se://gh-token docker pass run -- gh repo list
54-
55-
### Multiple references:
56-
DB_PASSWORD=se://myapp/postgres/password API_KEY=se://myapp/anthropic/api-key docker pass run -- ./my-binary
57-
58-
### Resolve references from a dotenv file:
59-
docker pass run --env-file .env -- ./my-binary
60-
61-
### Multiple files (later overrides earlier; files override the process environment):
62-
docker pass run --env-file .env --env-file .env.local -- ./my-binary
63-
`
52+
//go:embed run_example.md
53+
var runExample string
6454

6555
type runOpts struct {
6656
envFiles []string
@@ -70,16 +60,16 @@ func RunCommand() *cobra.Command {
7060
opts := runOpts{}
7161
cmd := &cobra.Command{
7262
Use: "run -- CMD [ARGS...]",
73-
Short: "Run a command with se:// environment references resolved.",
74-
Long: `Scans the current environment (plus any --env-file inputs) for variables
75-
whose value is exactly se://NAME. Each reference is resolved through the
76-
secrets-engine daemon and the resolved value is passed to the child process.
77-
The child inherits stdin, stdout, and stderr.
78-
79-
Requires the secrets-engine daemon (Docker Desktop) to be running.
80-
81-
If any reference cannot be resolved, the command fails before the child is
82-
started and exits non-zero.`,
63+
Short: "Run a command with `se://` environment references resolved.",
64+
Long: "Scans the current environment (plus any `--env-file` inputs) for variables\n" +
65+
"whose value is exactly `se://<ID|pattern>`. Each reference is resolved through the\n" +
66+
"secrets-engine daemon and the resolved value is passed to the child process.\n" +
67+
"The child inherits stdin, stdout, and stderr.\n" +
68+
"\n" +
69+
"Requires the secrets-engine daemon (Docker Desktop) to be running.\n" +
70+
"\n" +
71+
"If any reference cannot be resolved, the command fails before the child is\n" +
72+
"started and exits non-zero.",
8373
Example: strings.Trim(runExample, "\n"),
8474
Args: cobra.MinimumNArgs(1),
8575
RunE: func(cmd *cobra.Command, args []string) error {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
### Run a command with one secret in its environment:
2+
3+
```console
4+
$ SE_TOKEN=se://gh-token docker pass run -- gh repo list
5+
```
6+
7+
### Multiple references:
8+
9+
```console
10+
$ DB_PASSWORD=se://myapp/postgres/password API_KEY=se://myapp/anthropic/api-key docker pass run -- ./my-binary
11+
```
12+
13+
### Resolve references from a dotenv file:
14+
15+
```console
16+
$ docker pass run --env-file .env -- ./my-binary
17+
```
18+
19+
### Multiple files (later overrides earlier; files override the process environment):
20+
21+
```console
22+
$ docker pass run --env-file .env --env-file .env.local -- ./my-binary
23+
```

plugins/pass/commands/set.go

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package commands
1616

1717
import (
1818
"context"
19+
_ "embed"
1920
"encoding/json"
2021
"fmt"
2122
"io"
@@ -29,23 +30,8 @@ import (
2930
"github.com/docker/secrets-engine/x/secrets"
3031
)
3132

32-
const setExample = `
33-
### Set a secret:
34-
docker pass set POSTGRES_PASSWORD=my-secret-password
35-
36-
### Or pass the secret via STDIN:
37-
echo my-secret-password > pwd.txt
38-
cat pwd.txt | docker pass set POSTGRES_PASSWORD
39-
40-
### Set a secret with metadata:
41-
docker pass set POSTGRES_PASSWORD=my-secret-password --metadata owner=alice --metadata expiry=2027-03-01
42-
43-
### Or pass a JSON payload with secret and metadata via STDIN:
44-
echo '{"secret":"my-secret-password","metadata":{"owner":"alice"}}' | docker pass set POSTGRES_PASSWORD
45-
46-
### Overwrite an existing secret:
47-
docker pass set POSTGRES_PASSWORD=new-secret-password --force
48-
`
33+
//go:embed set_example.md
34+
var setExample string
4935

5036
type setOpts struct {
5137
metadata []string // raw "key=value" strings from --metadata flag
@@ -63,16 +49,16 @@ func SetCommand(kc store.Store) *cobra.Command {
6349
Use: "set id[=value]",
6450
Aliases: []string{"store", "save"},
6551
Short: "Set a secret",
66-
Long: `Stores a secret in the local OS keychain. The secret value can be provided inline (NAME=VALUE) or piped via STDIN.
67-
68-
Behavior when a secret with the same id already exists is platform-dependent:
69-
- macOS (Keychain): the command fails with a duplicate-item error.
70-
- Linux (Secret Service) and Windows (Credential Manager): the existing
71-
value is silently overwritten.
72-
73-
Pass --force to overwrite an existing secret. On Linux and Windows the
74-
replacement is performed atomically. On macOS the Keychain API requires
75-
a delete-then-add sequence.`,
52+
Long: "Stores a secret in the local OS keychain. The secret value can be provided inline (`NAME=VALUE`) or piped via STDIN.\n" +
53+
"\n" +
54+
"Behavior when a secret with the same id already exists is platform-dependent:\n" +
55+
" - macOS (Keychain): the command fails with a duplicate-item error.\n" +
56+
" - Linux (Secret Service) and Windows (Credential Manager): the existing\n" +
57+
" value is silently overwritten.\n" +
58+
"\n" +
59+
"Pass `--force` to overwrite an existing secret. On Linux and Windows the\n" +
60+
"replacement is performed atomically. On macOS the Keychain API requires\n" +
61+
"a delete-then-add sequence.",
7662
Example: strings.Trim(setExample, "\n"),
7763
Args: cobra.ExactArgs(1),
7864
RunE: func(cmd *cobra.Command, args []string) error {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
### Set a secret:
2+
3+
```console
4+
$ docker pass set POSTGRES_PASSWORD=my-secret-password
5+
```
6+
7+
### Or pass the secret via STDIN:
8+
9+
```console
10+
$ echo my-secret-password > pwd.txt
11+
$ cat pwd.txt | docker pass set POSTGRES_PASSWORD
12+
```
13+
14+
### Set a secret with metadata:
15+
16+
```console
17+
$ docker pass set POSTGRES_PASSWORD=my-secret-password --metadata owner=alice --metadata expiry=2027-03-01
18+
```
19+
20+
### Or pass a JSON payload with secret and metadata via STDIN:
21+
22+
```console
23+
$ echo '{"secret":"my-secret-password","metadata":{"owner":"alice"}}' | docker pass set POSTGRES_PASSWORD
24+
```
25+
26+
### Overwrite an existing secret:
27+
28+
```console
29+
$ docker pass set POSTGRES_PASSWORD=new-secret-password --force
30+
```

plugins/pass/examples.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
### Using keychain secrets in containers
2+
3+
Create a secret:
4+
5+
```console
6+
$ docker pass set GH_TOKEN=123456789
7+
```
8+
9+
Create a secret from STDIN:
10+
11+
```console
12+
echo "my_val" | docker pass set GH_TOKEN
13+
```
14+
15+
Run a container that uses the secret:
16+
17+
```console
18+
$ docker run -e GH_TOKEN= -dt --name demo busybox
19+
```
20+
21+
Inspect the secret from inside the container:
22+
23+
```console
24+
$ docker exec demo sh -c 'echo $GH_TOKEN'
25+
123456789
26+
```
27+
28+
Explicitly assign a secret to a different environment variable:
29+
30+
```console
31+
$ docker run -e GITHUB_TOKEN=se://GH_TOKEN -dt --name demo busybox
32+
```
33+
34+
### Using keychain secrets in Compose
35+
36+
Store the secrets:
37+
38+
```console
39+
$ docker pass set myapp/anthropic/api-key=sk-ant-...
40+
$ docker pass set myapp/postgres/password=s3cr3t
41+
```
42+
43+
```yaml
44+
services:
45+
api:
46+
image: service1
47+
environment:
48+
- ANTHROPIC_API_KEY=se://myapp/anthropic/api-key
49+
- POSTGRES_PASSWORD=se://myapp/postgres/password
50+
51+
worker:
52+
image: service2
53+
command: worker
54+
environment:
55+
- ANTHROPIC_API_KEY=se://myapp/anthropic/api-key
56+
57+
db:
58+
image: postgres:17
59+
environment:
60+
- POSTGRES_PASSWORD=se://myapp/postgres/password
61+
```

0 commit comments

Comments
 (0)