Docker Swarm Series: #6th Managing config and secret objects
Tags: docker, swarm
Published: 2023-07-18 06:27:32

--- series: Swarm ---

# Inception

Hello everyone, This article is part of The Swarm series, The knowledge in this series is built in sequence, Check out The [Swarm series](https://mohamed-eleraky.hashnode.dev/series/docker-swarm).

In the [last article](https://mohamed-eleraky.hashnode.dev/docker-swarm-series-5th-troubleshooting), we covered the way of troubleshooting and find out how to find the exact issue and fix it, using Docker CLI, And [Play-with-docker](https://labs.play-with-docker.com/) lab.

---

# Overview

In This article, We will complete The Swarm tutorials by explaining how to use and manage **config objects** and how to **store secrets** securely and use them in your deployment. in this lab Also will use the [Play-with-docker](https://labs.play-with-docker.com/) lab.

---

# Docker Config Overview

In Fact, The Config object is a file that stores some configs that you want to share among multiple container services, This config file can store [any type of data](https://www.amazon.com/Learn-Docker-Month-Lunches-Stoneman/dp/1617297054/ref=sr_1_1?keywords=month+of+lunch+docker&link_code=qs&qid=1689585935&sourceid=Mozilla-search&sr=8-1) (e.g. JSON, Key value, XML)

The value behind the usage of the config file is to ensure consistency across all the services and containers that use the same configuration data. This helps to avoid configuration errors and reduces the risk of downtime, Surface the [docker config Docs](https://docs.docker.com/engine/reference/commandline/config/).

---

# Docker Secret Overview

Secrets are almost exactly like config, "*Secrets are encrypted throughout their lifetime in the cluster. The data is stored encrypted in the database shared by the managers, and secrets are only delivered to nodes that are scheduled to run replicas that need the secret. Secrets are encrypted in transit from the manager node to the worker, and they are only unencrypted inside the container, where they appear with the original file contents."*

*"The key difference with secrets is that you can only read them in plain text at one point in the workflow: inside the container when they are loaded from the Swarm."*  
[*\-Docker in a month of lunches-*](https://www.amazon.com/Learn-Docker-Month-Lunches-Stoneman/dp/1617297054/ref=sr_1_1?keywords=month+of+lunch+docker&link_code=qs&qid=1689585935&sourceid=Mozilla-search&sr=8-1)

---

# Deployment Example

In This example will deploy **MongoDB** and **Mongo\_Express** container services and store the **configs** and **secrets** in external files and load them to the **swarm database** to ensure that the secret is secure and not appears in **clear text,** And will be using [Play-with-Docker](https://labs.play-with-docker.com/) labs, Docker Swarm mode, Docker-compose file, config & secret files, and Docker CLI.



* open [Play-with-Docker](https://labs.play-with-docker.com/) labs, and create the below environment:
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689622709143/9b04a5fd-b89f-420e-9d83-3443d905ed9c.png)<br><br>
    


* Create a config file object called `mongo_config.txt` that have the common configs including the username and the path to the password file.
    
    ```bash
    MONGO_INITDB_ROOT_USERNAME=admin
    MONGO_INITDB_ROOT_PASSWORD_FILE=/run/secrets/mongo_password
    ```
    

 <br>   
* Create a secret object file with the MongoDB password called `mongo_password.txt` with the following content
    
```bash
supersecretpassword
```
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689623063787/8c405dd9-dd39-448d-8bd8-18f5b9f89bcd.png)<br><br>



* Create a secret object from the secret file created:
    
    ```
    $ docker secret create mongo_password mongo_password.txt
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689623213344/a3d67e9d-c769-4cac-96ba-711fbbb92f11.png)<br><br>
    


* Create a config object from the config file created:
    
    ```bash
    docker config create mongo_config mongo_config.txt
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689623329299/df709655-9dbe-4165-a66a-f513dff5449d.png)<br><br>
    


* Check the Secrets in the cluster
    
    ```bash
    docker secret ls
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689623461461/d83e4433-04c7-4e55-ba39-6777350d6fb4.png)<br><br>
    



* Check the config in the cluster
    
    ```bash
    docker config ls
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689623507856/6e3e36cd-f2c3-4136-9d94-5a35b6ebb32a.png)<br><br>
    


* inspect the secret with a pretty flag using the following:
    
    ```bash
    docker secret inspect --pretty mongo_password
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689623674044/3537a50e-8e06-4192-8508-2efb5454c8e5.png)
    

<mark>note that the inspection doesn't print out the secret file content</mark><br><br>



* inspect the config with a pretty flag using the following:
    
    ```bash
    docker config inspect --pretty mongo_config
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689623841096/825d5f50-e7f2-4b39-af0c-6cdc113c018e.png)
    

note that the inspection print out the content of the config file due to the config file isn't secured as secrets.<br><br>



* Create a Docker Compose file called *docker-compose.yml* with the **MongoDB** and **Mongo\_Express** services, and reference the **config** and **secret** objects.
    

```yaml
version: "3.7"
services:
  mongo:
    image: mongo:4.4
    configs:
      - source: mongo_config
        target: /docker-entrypoint-initdb.d/mongo_config.txt
    environment:
      MONGO_INITDB_DATABASE: test
    secrets:
      - mongo_password
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager

  mongo-express:
    image: mongo-express:0.54
    ports:
      - "8081:8081"
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME_FILE: /run/secrets/mongo_admin_username
      ME_CONFIG_MONGODB_ADMINPASSWORD_FILE: /run/secrets/mongo_password
      ME_CONFIG_MONGODB_SERVER: mongo
      ME_CONFIG_BASICAUTH_USERNAME_FILE: /run/secrets/me_username
      ME_CONFIG_BASICAUTH_PASSWORD_FILE: /run/secrets/me_password
    secrets:
      - mongo_password
      - mongo_admin_username
      - me_username
      - me_password
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager

secrets:
  mongo_password:
    external: true
  mongo_admin_username:
    external: true
  me_username:
    external: true
  me_password:
    external: true

configs:
  mongo_config:
    external: true
```



* Just an important hint, once you create the secret you cannot update it, So will deploy the other secrets that are mentioned in the YAML file as below:
    

```bash
echo "mongo_pass" | docker secret create me_password -
echo "mongo_user" | docker secret create me_username -
echo "admin" | docker secret create mongo_admin_username -
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689625172417/0939cc66-6709-435c-8c09-ee30dc448480.png)<br><br>


* Deploy the stack to the Swarm cluster using the following
    

```bash
$ docker stack deploy -c docker-compose.yml myapp
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689624877272/6b7ee774-1bbb-4e8e-9321-1c5f3c8c9a8b.png)<br><br>



* Get Stack services
    
    ```bash
    docker stack ls
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689625280085/b81198f4-eb63-4f64-a7be-ed0e159710c5.png)<br><br>
    



* Get Stack services
    
    ```bash
    docker stack services myapp
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689625364989/e8345b58-cd4e-4944-9d8e-a2746c830ee1.png)<br><br>
    


* More info about services
    
    ```bash
    docker stack ps myapp
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1689625456568/3a290873-ca57-484f-baef-423b8b5686d6.png)
    

As Cleared the container services up and running.

---

# Steps summarization

* Create a config object file.
    
* Create a secret object file.
    
* Create a secret object from the file content.
    
* Create a config object from the file content.
    
* list and inspect our config and secret and ensure that the secret is secured and does not appear as clear text.
    
* Create a Docker-compose YAML file for the stack deployment.
    
* Manually create the missing secrets due to once you create the secret you cannot update it.
    
* Deploy the stack using the docker-compose YAML file and Docker CLI.
    
* print out the deployed services and ensure the services are up and running.

---

**References**

- [Learn Docker in a Month of Lunches](https://www.amazon.com/Learn-Docker-Month-Lunches-Stoneman/dp/1617297054/ref=sr_1_1?keywords=learn+docker+in+a+month+of+lunches&link_code=qs&qid=1689766789&sourceid=Mozilla-search&sr=8-1)   

---

That's it, Very straightforward, very fast🚀. Hope this article inspired you and will appreciate your feedback. Thank you.