DISCLAIMER: Image is generated using FREE
version of ChatGPT
.
Dockeri Secret
1. Setup
2. Hard Wired Secrets
3. Environment Variables
4. Env File
5. Swarm Mode
Setup
Before we do anything, let’s make sure we have the foundation setup properly.
If you don’t have docker
and docker-compose
installed, please follow the steps below. Otherwise, proceed to the next section.
$ sudo apt update
$ sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Add your user to the docker
group to avoid the need to use sudo for every docker
command:
$ sudo usermod -aG docker $USER
Check the installation:
$ docker --version
Docker version 28.0.1, build 068a01e
Now install the docker-compose
:
$ sudo apt install -y docker-compose
OR
$ sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
Verify the docker-compose
installation:
$ docker-compose --version
docker-compose version 1.29.2, build unknown
I am going to create an alias for docker ps
in the ~/.bashrc
file so that the output is well-formatted.
alias dps='docker ps --format "Container ID: {{.ID}}\nImage: {{.Image}}\nCommand: {{.Command}}\nCreated: {{.CreatedAt}}\nStatus: {{.Status}}\nPorts: {{.Ports}}\nNames: {{.Names}}\n"'
For the demo, I am going to use the latest MongoDB
image.
In this post, I will explore the following options:
1. Hard wired secrets
2. Use of environment variables
3. Use of --env-file flag
4. Secret in swarm mode
Hard Wired Secrets
Well, in this case, we save the secrets in the configuration, though it’s not a good idea.
Here is the configuration file, docker-compose-open.yml
:
version: '3.8'
services:
mongodb:
image: mongo
container_name: mongodb
ports:
- 27017:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=supersecret
Let’s start the container now:
$ docker-compose -f docker-compose-open.yml up -d
Creating mongodb ... done
Check the container status, docker ps
:
$ dps
Container ID: e753a5985c96
Image: mongo
Command: "docker-entrypoint.s…"
Created: 2025-03-20 04:29:16 +0000 GMT
Status: Up 2 seconds
Ports: 0.0.0.0:27017->27017/tcp, [::]:27017->27017/tcp
Names: mongodb
The container is up and running, so far so good.
Let’s connect to the MongoDB
using the same credentials as in the configuration file above:
$ docker exec -it mongodb mongosh --username admin --password supersecret
Current Mongosh Log ID: 67dbc40b54e05a0e5e6b140a
...
...
Using MongoDB: 8.0.5
Using Mongosh: 2.4.2
test>
We’ve passed the first hurdle, we’re inside the container and connected to MongoDB
.
To exit, simply type exit
at the prompt.
Let’s clean up by stopping and removing the container
, so we can move to the next option.
$ docker stop mongodb
mongodb
$ docker rm mongodb
mongodb
Environment Variables
For this, we would create another configuration file, docker-compose-env.yml
:
version: '3.8'
services:
mongodb:
image: mongo
container_name: mongodb
ports:
- 27017:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=${MONGO_ADMIN_USER}
- MONGO_INITDB_ROOT_PASSWORD=${MONGO_ADMIN_PASS}
You have two choices for creating environment variables: either use EXPORT key=value
or define them when creating container:
$ export MONGO_ADMIN_USER=admin
$ export MONGO_ADMIN_PASS=supersecret
$ docker-compose -f docker-compose-env.yml up -d
Creating mongodb ... done
OR
$ MONGO_ADMIN_USER=admin MONGO_ADMIN_PASS=supersecret \
docker-compose -f docker-compose-env.yml up -d
Creating mongodb ... done
Check the container status, docker ps
:
$ dps
Container ID: e753a5985c96
Image: mongo
Command: "docker-entrypoint.s…"
Created: 2025-03-20 04:32:10 +0000 GMT
Status: Up 33 seconds
Ports: 0.0.0.0:27017->27017/tcp, [::]:27017->27017/tcp
Names: mongodb
So all good, let’s connect to MongoDB
:
$ docker exec -it mongodb mongosh --username admin --password supersecret
Current Mongosh Log ID: 67dbc7f7b8d8dedf8d6b140a
...
...
Using MongoDB: 8.0.5
Using Mongosh: 2.4.2
test>
Once that’s done, type exit
at the prompt to exit.
We’ll clean up as before i.e. stop and remove the container
.
$ docker stop mongodb
mongodb
$ docker rm mongodb
mongodb
Env File
Let’s create env file first, docker-compose.env
as below:
$ echo "MONGO_ADMIN_USER=admin" > docker-compose.env
$ echo "MONGO_ADMIN_PASS=supersecret" >> docker-compose.env
Time to start the container with --env-file
flag:
$ docker-compose --env-file docker-compose.env -f docker-compose-env.yml up -d
Creating mongodb ... done
Check the container status, docker ps
:
$ dps
Container ID: d61324270839
Image: mongo
Command: "docker-entrypoint.s…"
Created: 2025-03-20 04:35:11 +0000 GMT
Status: Up 31 seconds
Ports: 0.0.0.0:27017->27017/tcp, [::]:27017->27017/tcp
Names: mongodb
Now it’s up and running. Good.
Let’s connect to MongoDB
again.
$ docker exec -it mongodb mongosh --username admin --password supersecret
Current Mongosh Log ID: 67dbca84408a363eff6b140a
...
...
Using MongoDB: 8.0.5
Using Mongosh: 2.4.2
test>
Type exit
at the prompt to exit so that we can proceed to the final option.
Finally, stop and remove the container
:
$ docker stop mongodb
mongodb
$ docker rm mongodb
mongodb
Swarm Mode
This next part is a bit tricky as you’ll see.
First we need to enable Swarm
mode.
$ docker swarm init
OR
$ docker swarm init --advertise-addr 172.19.28.199
Swarm initialized: current node (qz8w8ns05xvtmpsewhhsp9qiq) is now a manager.
Check if Swarm
mode is active:
$ docker info | grep -i swarm
Swarm: active
Good, Swarm
mode is now active.
Next, we’ll create two secrets one for the user
and another for the password
.
There are two ways to create secrets as shown below:
$ echo "admin" > mongo-user.txt
$ docker secret create mongo_user mongo-user.txt
x3lswvc8mkwh0x5opoyvkucca
and
$ echo "supersecret" | docker secret create mongo_pass -
5efjagekw2driudrs5z7j6ezc
We have created two secrets, let’s list them first:
$ docker secret ls
ID NAME DRIVER CREATED UPDATED
5efjagekw2driudrs5z7j6ezc mongo_pass 42 seconds ago 42 seconds ago
x3lswvc8mkwh0x5opoyvkucca mongo_user About a minute ago About a minute ago
It’s time to create the configuration file, docker-compose-secret.yml
as below:
version: '3.8'
services:
mongo:
image: mongo
container_name: mongodb
secrets:
- mongo_user
- mongo_pass
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME_FILE: /run/secrets/mongo_user
MONGO_INITDB_ROOT_PASSWORD_FILE: /run/secrets/mongo_pass
networks:
- mongo_network
secrets:
mongo_user:
external: true
mongo_pass:
external: true
networks:
mongo_network:
driver: overlay
attachable: true
To create a container in Swarm
mode and use the secrets, we need to create the stack as follows:
$ docker stack deploy -c docker-compose-secret.yml mongo_stack
In a future release, --detach=false will become the default.
Creating network mongo_stack_mongo_network
Creating service mongo_stack_mongo
NOTE: The service name mongo_stack_mongo
, it was auto-generated by Docker
, which is the combination of stack name, mongo_stack
and service name mongo
.
Hang on, why isn’t the service name exactly as in the configuration file?
Well, if Docker
used the service name exactly as defined in the configuration file, it would lead to naming conflicts in a multi-stack environment.
For example:
- Stack A has a service named db.
- Stack B also has a service named db.
If Docker
didn’t prefix the service name with the stack name, both services would be named db
, making it impossible to distinguish them in the Swarm
cluster.
Can you change this behaviour?
No, Docker
doesn’t provide a way to override this behaviour when using docker stack deploy
.
The <stack>_<service>
naming convention is enforced by design.
Check the container status, docker ps
:
$ dps
Container ID: f85e4c9be83a
Image: mongo
Command: "docker-entrypoint.s…"
Created: 2025-03-20 04:37:31 +0000 GMT
Status: Up 19 seconds
Ports: 0.0.0.0:27017->27017/tcp, [::]:27017->27017/tcp
Names: mongodb
Let;s try to connect to MongoDB
:
$ docker exec -it mongodb mongosh --username admin --password supersecret
Current Mongosh Log ID: 67dbcef14a1ae204cf6b140a
...
...
Using MongoDB: 8.0.5
Using Mongosh: 2.4.2
test>
Type exit
at the prompt and to exit.
Finally, we’ll now remove the service.
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
qg8b7aq1a3q3 mongo_stack_mongo replicated 1/1 mongo:latest *:27017->27017/tcp
$ docker service rm qg8b7aq1a3q3
qg8b7aq1a3q3
Last but not least, leave Swarm
mode:
$ docker swarm leave
Keep Hacking !!