In this post, we will be talking about Docker Secrets. Why do we need Docker secret and how to use it to secure sensitive data. If you are new to Docker, check out the Docker Tutorial.
What is docker Secret?
A secret is a blob of data that should not be transmitted over a network or stored unencrypted in a Dockerfile or in your application’s source code.
- Usernames and passwords
- TLS certificates and keys
- SSH keys
- Other important data such as the name of a database or internal server
- Generic strings or binary content (up to 500 kb in size)
Docker secrets can be used to centrally manage this data and securely transmit it to only those containers that need access to it. Secrets are encrypted during transit and at rest in a Docker swarm. A given secret is only accessible to those services which have been granted explicit access to it, and only while those service tasks are running.
Why use Secrets
Let us consider the following example of docker-compose file which would create a MySQL instance.
version: '3.1' services: db: image: mysql command: --default-authentication-plugin=mysql_native_password restart: always environment: MYSQL_ROOT_PASSWORD: example adminer: image: adminer restart: always ports: - 8080:8080
If you observe the file you can see that the sensitive information like MYSQL_ROOT_PASSWORD environment variable is available in plain text. This practice can be used for the local environment but should not be used in the production environment.
Now let us see how we can use Docket Secrets to solve this.
The first step would be to add a secret to Dockers:
We will use
docker secret create command to create a secret. Consider the example
printf "mySecretPassword" | docker secret create ms_password -
This command reads standard input because the last argument, which represents the file to read the secret from, is set to –
You can refer the following official document in case you want to know more about this command: https://docs.docker.com/engine/reference/commandline/secret_create/
Now let’s modify the stack.yml file to use the secret we just created. To do so, we will do the following modification to the stack.yml
- Add a root element called secrets with a secret called ms_password which is declared as external. It is external because it was created outside of this stack.yml, but exists in the swarm.
- A new secrets element under the DB service, which lists our new ms_password secret. This grants this service access to this secret.
- A new environment variable that stores the path to our new secret. By storing the path to the secret in an environment variable we can rotate the secret later and update the path and the application will need to be updated.
The modified file would look like this:
version: '3.1' services: db: image: mysql command: --default-authentication-plugin=mysql_native_password environment: MYSQL_ROOT_PASSWORD_FILE: /run/secrets/ms_password secrets: - ms_password adminer: image: adminer ports: - 8080:8080 secrets: ms_password: external: true
Now you can deploy this using docker stack command
docker stack deploy --compose-file docker-compose.yml mysql
Once the services startup, you can visit http://127.0.0.1:8080/ and log in using the username “root” and password “mySecretPassword” which we created previously. If you observer the modified file carefully, it does not store sensitive information like passwords in plain text, thus making our environment secure.
I hope you have given you a clear overview of Docker secrets, please share your feedback in the comment below.