4

I'm using this docker image https://hub.docker.com/_/mongo/. That image provides a way of initializing a mongodb root database user with env variables which I can specify in the compose file as follows:

environment:
  - MONGO_INITDB_DATABASE=db
  - MONGO_INITDB_ROOT_USERNAME=root
  - MONGO_INITDB_ROOT_PASSWORD=pass

It seems storing the password in config files is not very secure. How can I use more secure ways (i.e. docker secrets) to init the root user in this case? Same thing for initdb files, which I need to copy to the container and may as well contain more credentials.

I wonder if anyone here found a more secure way of handling this.

1

Secrets support for mongo is built in. You can see in that image's entrypoint script that if you add _FILE to end of username/password values it will pull from those secret files.

As for .js files, if you're storing decrypted passwords in those files, you'd need to make a custom entrypoint script or something that will take envvars you're passing in for which secrets to use and run a jq or sed on the file to replace I guess. You can store the .js files themselves in a secret as longas its smaller than 500Kb (max size of a secret).

2

Here's a solution I've used in cases like this - I utilize Ansible to manage Docker containers, and Ansible Vault to store secrets for those containers.

Ansible Playbook to run MongoDB container

Your playbook.yml may look something like this:

- name: run mongodb docker container
  docker_container:
    name: mongo-container
    image: mongo
    ports:
      - "27017:27017"
    env:
      MONGO_INITDB_DATABASE: "{{secret_db_name}}"
      MONGO_INITDB_ROOT_USERNAME: "{{secret_db_user}}"
      MONGO_INITDB_ROOT_PASSWORD: "{{secret_db_pass}}"
  • As you might notice, the docker_container syntax looks a lot like what you'd write in a Docker Compose YML file.
  • The difference is that your secrets are managed in variables (the {{}} is Ansible Jinja2 variables).
  • Here's a list of Ansible Modules for interacting with Docker.

Vault file to manage your mongodb secrets

The vault.yml file would contain the definitions of your secrets in an encrypted form.

secret_db_name: foodb
secret_db_user: foo
secret_db_pass: bar@123

You can use ansible-vault commands to create encrypted files (for e.g in version-control).

Getting it all together

When you want to run your Docker container, you would run an Ansible command

ansible-playbook playbook.yml --ask-vault-pass

Which would

  • ask you for your vault password file,
  • decrypt the vault file and pass the variables to the playbook;
  • run the docker mongodb container with your secret credentials

All whilst ensuring your credentials are not publicly visible.

Notes

  • I've used this approach to provision Dockerized databases on remote managed servers in a declarative way.
  • You introduce one more tool, a 'wrapper' around Docker. In my experience DevOps toolchains work better than utilizing single tools. However, this may or may not be a constraint for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.