A secret is an information that should be kept hidden from unauthorized users and applications. Examples of secrets include usernames, passwords, private keys, certificates, and resource names and locations.
The aim of secrets is to store sensitive information, that is needed by services, in a secure location. In other words, You should avoid storing these information in docker images and docker compose files in clear text.
Docker engine provides a set of commands to manage secrets and make them available to your applications. These commands should be executed on docker swarm managers.
The docker secrets have the following properties:
- Secrets are encrypted when transmitted and at rest in the docker swarm.
- Secrets are accessed only by authorized services and users.
- Secrets are available only to services but not to regular containers.
- Secrets are accessed when the task is running
Docker provides secrets to services as files mounted to the folder /run/secrets using the tmpfs filesystem. For instance, the mypass secret is stored in file /run/secrets/mypass inside the running container.
The command to create a secret has the following template:
$ docker secret create [options] <secret-name> [filename | -]
A secret can be created in two different ways. The first method uses the standard input to create a secret:
$ echo "secret one content" | docker secret create mysecret1 -
The echo command prints the text provided as parameter to the standard output which it then directed to standard input of the docker secret create command. The hyphen (-) at the end of the command tells the docker command to read from the standard input.
The second method of creating a secret is from a file that stores the secret.
$ echo "secret two content" > secret-file.txt
$ docker secret create mysecret2 ./secret-file.txt
The ls command lists all existing secrets in the docker swarm.
$ docker secret ls
The commands displays the id, name, the creation and update dates of the secrets.
The inspect command displays detailed information about a secret in JSON format. The content of the secret is not displayed.
$ docker secret ls
$ docker secret inspect mysecret1
A human friendly output can be displayed using the --pretty option.
$ docker secret inspect --pretty mysecret1
A specific information can be displayed using the --format option.
$ docker secret inspect --format '{{.UpdatedAt}}' mysecret
The rm command removes a secret from a swarm. The command does not asks for confirmation before removing the secret.
$ docker secret rm myscret1
A secret used by a running service cannot be removed. You may use secret rotation to remove a secret while a service is running.
The secrets are specified during the creation of services either using the command line interface or within the docker compose file.
Create a secret using the command line interface:
$ echo "the password secret" | docker secret create mypass -
$ docker secret ls
$ docker secret inspect mypass
Create a service that uses the secret:
$ docker service create --name mynginx --secret mypass nginx:latest
$ docker service ls
Get the task ID (container ID) that is needed for the docker exec command.
$ docker ps
Display the secret content stored under the folder /run/secrets:
$ docker exec 7be95f99dbad cat /run/secrets/mypass
The above command should display "the password secret" text.
Remove the service and the secret:
$ docker service rm mynginx
$ docker secret rm mypass
Ceate the following docker-compose file:
version: '3.8'
services:
db:
image: postgres:latest
environment:
POSTGRES_USER: webuser
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
POSTGRES_DB: webdatabase
secrets:
- db_password
adminer:
image: adminer:latest
ports:
- 8080:8080
secrets:
db_password:
file: db_password.txt
Create a file that contains the database password:
$ echo mypassword > db_password.txt
Deploy the stack using the docker compose file:
$ docker stack deploy --compose-file docker-compose.yml myapp
To test the deployed stack, browse to the address http://localhost:8080 and login to the adminer using the following parameters:
- System: PostgeSQL
- Server: db
- Username: webuser
- Password: mypassword
- Database: webdatabase
In case the secret db_password is created using the command line:
$ echo mypassword | docker secret create db_password -
$ docker secret ls
The secrets section in the docker compose file should be updated to tell the docker engine that the secret dp_password is created outside the compose file:
secrets:
db_password:
external: true
Redeploy the app and browse to the address http://localhost:8080 to test your stack.
When you are done, you may remove the stack and the secret:
$ docker stack rm myapp
$ docker secret rm db_password