mirror of https://github.com/docker/docs.git
194 lines
8.5 KiB
Markdown
194 lines
8.5 KiB
Markdown
---
|
|
title: Manage secrets
|
|
description: Learn how to manage your passwords, certificates, and other secrets in a secure way with Docker EE
|
|
keywords: UCP, secret, password, certificate, private key
|
|
redirect_from:
|
|
- /ee/ucp/user/secrets/
|
|
---
|
|
|
|
When deploying and orchestrating services, you often need to configure them
|
|
with sensitive information like passwords, TLS certificates, or private keys.
|
|
|
|
Universal Control Plane allows you to store this sensitive information, also
|
|
known as *secrets*, in a secure way. It also gives you role-based access control
|
|
so that you can control which users can use a secret in their services
|
|
and which ones can manage the secret.
|
|
|
|
UCP extends the functionality provided by Docker Engine, so you can continue
|
|
using the same workflows and tools you already use, like the Docker CLI client.
|
|
[Learn how to use secrets with Docker](/engine/swarm/secrets/).
|
|
|
|
In this example, we're going to deploy a WordPress application that's composed of
|
|
two services:
|
|
|
|
* wordpress: The service that runs Apache, PHP, and WordPress
|
|
* wordpress-db: a MySQL database used for data persistence
|
|
|
|
Instead of configuring our services to use a plain text password stored in an
|
|
environment variable, we're going to create a secret to store the password.
|
|
When we deploy those services, we'll attach the secret to them, which creates
|
|
a file with the password inside the container running the service.
|
|
Our services will be able to use that file, but no one else will be able
|
|
to see the plain text password.
|
|
|
|
To make things simpler, we're not going to configure the database service to
|
|
persist data. When the service stops, the data is lost.
|
|
|
|
## Create a secret
|
|
|
|
In the UCP web UI, open the **Swarm** section and click **Secrets**.
|
|
|
|
{: .with-border}
|
|
|
|
Click **Create Secret** to create a new secret. Once you create the secret
|
|
you won't be able to edit it or see the secret data again.
|
|
|
|
{: .with-border}
|
|
|
|
Assign a unique name to the secret and set its value. You can optionally define
|
|
a permission label so that other users have permission to use this secret. Also
|
|
note that a service and secret must have the same permission label, or both
|
|
must have no permission label at all, in order to be used together.
|
|
|
|
In this example, the secret is named `wordpress-password-v1`, to make it easier
|
|
to track which version of the password our services are using.
|
|
|
|
|
|
## Use secrets in your services
|
|
|
|
Before creating the MySQL and WordPress services, we need to create the network
|
|
that they're going to use to communicate with one another.
|
|
|
|
Navigate to the **Networks** page, and create the `wordpress-network` with the
|
|
default settings.
|
|
|
|
{: .with-border}
|
|
|
|
Now create the MySQL service:
|
|
|
|
1. Navigate to the **Services** page and click **Create Service**. Name the
|
|
service "wordpress-db", and for the **Task Template**, use the "mysql:5.7"
|
|
image.
|
|
2. In the left pane, click **Network**. In the **Networks** section, click
|
|
**Attach Network**, and in the dropdown, select **wordpress-network**.
|
|
3. In the left pane, click **Environment**. The Environment page is where you
|
|
assign secrets, environment variables, and labels to the service.
|
|
4. In the **Secrets** section, click **Use Secret**, and in the **Secret Name**
|
|
dropdown, select **wordpress-password-v1**. Click **Confirm** to associate
|
|
the secret with the service.
|
|
5. In the **Environment Variable** section, click **Add Environment Variable** and enter
|
|
the string "MYSQL_ROOT_PASSWORD_FILE=/run/secrets/wordpress-password-v1" to
|
|
create an environment variable that holds the path to the password file in
|
|
the container.
|
|
6. If you specified a permission label on the secret, you must set the same
|
|
permission label on this service. If the secret doesn't have a permission
|
|
label, then this service also can't have a permission label.
|
|
7. Click **Create** to deploy the MySQL service.
|
|
|
|
This creates a MySQL service that's attached to the `wordpress-network` network
|
|
and that uses the `wordpress-password-v1` secret. By default, this creates a file
|
|
with the same name at `/run/secrets/<secret-name>` inside the container running
|
|
the service.
|
|
|
|
We also set the `MYSQL_ROOT_PASSWORD_FILE` environment variable to configure
|
|
MySQL to use the content of the `/run/secrets/wordpress-password-v1` file as
|
|
the root password.
|
|
|
|
{: .with-border}
|
|
|
|
Now that the MySQL service is running, we can deploy a WordPress service that
|
|
uses MySQL as a storage backend:
|
|
|
|
1. Navigate to the **Services** page and click **Create Service**. Name the
|
|
service "wordpress", and for the **Task Template**, use the
|
|
"wordpress:latest" image.
|
|
2. In the left pane, click **Network**. In the **Networks** section, click
|
|
**Attach Network**, and in the dropdown, select **wordpress-network**.
|
|
3. In the left pane, click **Environment**.
|
|
4. In the **Secrets** section, click **Use Secret**, and in the **Secret Name**
|
|
dropdown, select **wordpress-password-v1**. Click **Confirm** to associate
|
|
the secret with the service.
|
|
5. In the **Environment Variable**, click **Add Environment Variable** and enter
|
|
the string "WORDPRESS_DB_PASSWORD_FILE=/run/secrets/wordpress-password-v1" to
|
|
create an environment variable that holds the path to the password file in
|
|
the container.
|
|
6. Add another environment variable and enter the string
|
|
"WORDPRESS_DB_HOST=wordpress-db:3306".
|
|
7. If you specified a permission label on the secret, you must set the same
|
|
permission label on this service. If the secret doesn't have a permission
|
|
label, then this service also can't have a permission label.
|
|
8. Click **Create** to deploy the WordPress service.
|
|
|
|
{: .with-border}
|
|
|
|
This creates the WordPress service attached to the same network as the MySQL
|
|
service so that they can communicate, and maps the port 80 of the service to
|
|
port 8000 of the cluster routing mesh.
|
|
|
|
{: .with-border}
|
|
|
|
Once you deploy this service, you'll be able to access it using the
|
|
IP address of any node in your UCP cluster, on port 8000.
|
|
|
|
{: .with-border}
|
|
|
|
## Update a secret
|
|
|
|
If the secret gets compromised, you'll need to rotate it so that your services
|
|
start using a new secret. In this case, we need to change the password we're
|
|
using and update the MySQL and WordPress services to use the new password.
|
|
|
|
Since secrets are immutable in the sense that you can't change the data
|
|
they store after they are created, we can use the following process to achieve
|
|
this:
|
|
|
|
1. Create a new secret with a different password.
|
|
2. Update all the services that are using the old secret to use the new one
|
|
instead.
|
|
3. Delete the old secret.
|
|
|
|
Let's rotate the secret we've created. Navigate to the **Secrets** page
|
|
and create a new secret named `wordpress-password-v2`.
|
|
|
|
{: .with-border}
|
|
|
|
This example is simple, and we know which services we need to update,
|
|
but in the real world, this might not always be the case.
|
|
|
|
Click the **wordpress-password-v1** secret. In the details pane,
|
|
click **Inspect Resource**, and in the dropdown, select **Services**.
|
|
|
|
{: .with-border}
|
|
|
|
Start by updating the `wordpress-db` service to stop using the secret
|
|
`wordpress-password-v1` and use the new version instead.
|
|
|
|
The `MYSQL_ROOT_PASSWORD_FILE` environment variable is currently set to look for
|
|
a file at `/run/secrets/wordpress-password-v1` which won't exist after we
|
|
update the service. So we have two options:
|
|
|
|
1. Update the environment variable to have the value
|
|
`/run/secrets/wordpress-password-v2`, or
|
|
2. Instead of mounting the secret file in `/run/secrets/wordpress-password-v2`
|
|
(the default), we can customize it to be mounted in`/run/secrets/wordpress-password-v1`
|
|
instead. This way we don't need to change the environment variable. This is
|
|
what we're going to do.
|
|
|
|
When adding the secret to the services, instead of leaving the **Target Name**
|
|
field with the default value, set it with `wordpress-password-v1`. This will make
|
|
the file with the content of `wordpress-password-v2` be mounted in
|
|
`/run/secrets/wordpress-password-v1`.
|
|
|
|
Delete the `wordpress-password-v1` secret, and click **Update**.
|
|
|
|
{: .with-border}
|
|
|
|
Then do the same thing for the WordPress service. After this is done, the
|
|
WordPress application is running and using the new password.
|
|
|
|
## Managing secrets through the CLI
|
|
|
|
You can find additional documentation on managing secrets through the CLI at [How Docker manages secrets](/engine/swarm/secrets/#read-more-about-docker-secret-commands).
|
|
|
|
|