Introduction
This repository complements Part 1 of the Docker Swarm series, focusing on securely managing sensitive data such as database credentials, API keys, and more. By leveraging Docker Swarm secrets, you can separate sensitive information from your container images, enhancing the security posture of your applications.
Understanding Docker Swarm Secrets
Docker Swarm secrets allow you to store sensitive information outside of container images, preventing accidental exposure or unauthorized access. Secrets are managed as key-value pairs and can be referenced securely within your containers.
Prerequisites
Create 1 master node and 2 worker nodes and connect master worker nodes using docker swarm
create IAM user with administrator access role attached and create access and secret keys
Creating Secrets
Here are two common methods to create Docker Swarm secrets:
1. File-Based Secrets
Create a file containing your sensitive data. For example, create a file named
credentials
and store your access keys and secret keys within it.[default] aws_access_key_id=AAAAAAAAAAAAAAAAAA aws_secret_access_key=ASASASASASASASA
Convert the file into a secret using the following command:
docker secret create <secret_name> <file_path>
Replace
<secret_name>
with a descriptive name (e.g.,aws_creds
) and<file_path>
with the file path (e.g.,.credentials
).
2. Environment Variable Secrets
Define environment variables during container creation to provide secrets directly:
docker run -e <environment_variable_name>=<secret_value> <image_name>
Replace
<environment_variable_name>
with a variable name (e.g.,DB_PASSWORD
) and<secret_value>
with your actual password.
Mounting Secrets
Once you've created your secret, you can mount it within your containers for secure access.
Create a
aws-cli.yml
file defining your service configuration:version: '3.3' services: cli: image: imkiran13/notes-app:latest secrets: - source: aws_creds target: /root/.aws/credentials uid: '1000' gid: '1000' mode: 0700 deploy: replicas: 1 placement: constraints: [node.role != manager] resources: reservations: memory: 128M limits: memory: 512M environment: AWS_DEFAULT_REGION: us-east-1 networks: - appnet secrets: aws_creds: external: true networks: appnet:
Deploy the service:
docker stack deploy -c aws-cli.yml AWS_CLI
Verifying Secrets
Use
docker service ps
to check the status of your deployed serviceSecurity Caution: Connect to a worker node (not the manager) to enhance security
install aws cli once you enter into docker container
Verify access using commands like
env
,aws s3 ls
, andaws describe-vpc | jq
Delete resources
Security Best Practices
Always use strong passwords and access keys.
Regularly rotate secrets.
Consider tools like Vault or AWS Secrets Manager for advanced secret management.
Example: Using Secrets in MySQL
Create secrets and deploy a MySQL service using Docker Swarm:
1️⃣ Create an Overlay Network for Swarm
docker network create --driver overlay appnet
2️⃣ Create Docker Secrets for MySQL Passwords
openssl rand -base64 12 | docker secret create db_root_password -
openssl rand -base64 12 | docker secret create db_dba_password -
✅ These commands generate random passwords and store them as Docker secrets.
3️⃣ Create a db.yml
File
Create a Docker Swarm stack file (e.g., db.yml
) with MySQL using secrets:
version: '3.3'
services:
db:
image: mysql:8.0
secrets:
- db_root_password
- db_dba_password
- source: db_root_password
target: ROOT_PASSWORD
- source: db_dba_password
target: DB_PASSWORD
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
resources:
reservations:
memory: 128M
cpus: '0.25'
limits:
memory: 512M
cpus: '1'
ports:
- 3306:3306
environment:
MYSQL_USER: dba
MYSQL_DATABASE: mydb
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
MYSQL_PASSWORD_FILE: /run/secrets/db_dba_password
networks:
- appnet
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "datavol:/var/lib/mysql"
adminer:
image: adminer
ports:
- 8888:8080
networks:
- appnet
utils:
image: imkiran13/notes-app:latest
deploy:
replicas: 1
placement:
constraints: [node.role != manager]
networks:
- appnet
secrets:
db_root_password:
external: true
db_dba_password:
external: true
networks:
appnet:
external: true
saikiran:
sai:
volumes:
datavol:
📌 Important Notes:
Secrets are mounted as files in
/run/secrets/
, not directly as environment variables.You must use
_FILE
suffix (e.g.,MYSQL_ROOT_PASSWORD_FILE
) to read from the secrets file.
4️⃣ Deploy the Stack
docker stack deploy -c db.yml DB
Go to the master node, copy the public IP, and access port 8888.
Retrieve the password for root user
Now you are logged In
✅ This deploys the MySQL service inside Docker Swarm.
5️⃣ Install MySQL Client & Connect
Verify on which node app is running and go inside that node
To access MySQL from a worker/manager node:
docker exec -it DB_utils.1.2d1nfgz0g5t8bqs8ittehjoui bash
apt-get update && apt-get install -y default-mysql-client
Now, connect to MySQL inside Swarm:
mysql -h DB -u root -p
When prompted, use the password stored in the db_root_password
secret.
🛑 Remove the Stack
If you need to stop and remove everything:
docker stack rm my_stack
docker secret rm db_root_password db_dba_password
docker network rm appnet