Here are two approaches to handle passwords, keys, etc in docker compose files.

1. Docker secrets using external files (easier)

In this example you can store your sensitive data in external files.

Original file containing a secret token:

version: "3.9"
services:

  duckdns:
    image: linuxserver/duckdns:latest
    container_name: duckdns
    environment:
      - TZ=Europe/Madrid
      - SUBDOMAINS=mydomain1.duckdns.org,mydomain2.duckdns.org
      - TOKEN=mysecrettokenexample
    restart: unless-stopped

networks:
  net_rp:

New file without my sensitive data. You will need to store mysecrettokenexample into the file duckdns_token.key.

version: "3.9"
services:

  duckdns:
    image: linuxserver/duckdns:latest
    container_name: duckdns
    environment:
      - TZ=Europe/Madrid
      - SUBDOMAINS=mydomain1.duckdns.org,mydomain2.duckdns.org
      - TOKEN=/run/secrets/duckdns_token
    restart: unless-stopped
    secrets:
      - duckdns_token

secrets:
  duckdns_token:
    file: ./duckdns_token.key

networks:
  net_rp:

2. Docker secrets (standard)

Here instead you store your sensitive data in docker secrets.

1 - Check if Swarm is enabled (it is disabled by default).

$ docker info | grep Swarm
 Swarm: inactive

2 - If it’s disabled, enable it with:

docker swarm init

3 - Let’s create our first secret tagged myfirstkey:

printf mysecretpassword | docker secret create myfirstkey -

You can also create a random password easily with:

openssl rand -base64 16 | docker secret create secure-key -

You can also use the password that is stored in a file:

docker secret create secure-key myfile.key

4 - You can verify your secret is created with:

docker secret ls

5 - Once the secret is created, you need to create a service that gives you access to that secret. For example:

$ docker service create --name redis_for_duckdns --secret="duckdns_token" redis:alpine
txof7ceq2kwxmn0cfkvvjvpu7
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged

All containers in this service will be able to access the secret.

6 - You can verify the service is created with

~$ docker service ls
ID             NAME                MODE         REPLICAS   IMAGE          PORTS
txof7ceq2kwx   redis_for_duckdns   replicated   1/1        redis:alpine

7 - Deploy a stack.

$ docker stack deploy --compose-file docker-compose.yml redis_for_duckdns

8 - In this case the secret is no longer stored in an external file so we can remove file: ./duckdns_token.key from the docker-compose file:

version: "3.9"
services:

  duckdns:
    image: linuxserver/duckdns:latest
    container_name: duckdns
    environment:
      - TZ=Europe/Madrid
      - SUBDOMAINS=mydomain1.duckdns.org,mydomain2.duckdns.org
      - TOKEN=/run/secrets/duckdns_token
    restart: unless-stopped
    secrets:
      - duckdns_token

secrets:
  duckdns_token:

networks:
  net_rp:

3. Also good to know

How to remove a secret

You can remove a secret with docker secret rm but if its in use by a service you will get the following error:

$ docker secret rm myfirstkey
Error response from daemon: rpc error: code = InvalidArgument desc = secret 'myfirstkey' is in use by the following service: redis

This is because you first need to remove the secret from the service that’s using it:

$ docker service update --secret-rm myfirstkey redis
redis
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged

Then if you wish you can remove the secret and the service:

$ docker secret rm myfirstkey
myfirstkey
$ docker service rm redis

Check what secrets are in a specific service

$ docker ps --filter name=redis
CONTAINER ID   IMAGE          COMMAND                  CREATED       STATUS       PORTS      NAMES
5b9be8e5af67   redis:alpine   "docker-entrypoint.s…"   6 hours ago   Up 6 hours   6379/tcp   redis.1.glnjn4p3y03re7aupgf9wcaw5

$ docker ps --filter name=redis -q
5b9be8e5af67

$ docker container exec $(docker ps --filter name=redis -q) ls -l /run/secrets
total 4
-r--r--r--    1 root     root             4 Oct 24 13:58 myfirstkey

Check that a container has access to a secret

$ docker container exec $(docker ps --filter name=redis -q) cat /run/secrets/myfirstkey
hola