Skip to content

Instantly share code, notes, and snippets.

@mkfares
Created August 15, 2020 14:45
Show Gist options
  • Save mkfares/6d243bbdc488c3b862751126e735f7cd to your computer and use it in GitHub Desktop.
Save mkfares/6d243bbdc488c3b862751126e735f7cd to your computer and use it in GitHub Desktop.
Docker Swarm - Managing Secrets

Docker Swarm - Managing Secrets

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.

Create a secret

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

List secrets

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.

Inspect a secret

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

Remove a secret

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.

Use of secrets in applications

The secrets are specified during the creation of services either using the command line interface or within the docker compose file.

Example 1: Using the command line interface

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

Example 2: Using docker compose file

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment