Using Docker secrets with MySQL in Docker Compose
1 min read

Using Docker secrets with MySQL in Docker Compose

Prefacing this that Docker secrets were built for Docker Swarm and not for single containers. From the docs:

Note: Docker secrets are only available to swarm services, not to standalone containers. To use this feature, consider adapting your container to run as a service. Stateful containers can typically run with a scale of 1 without changing the container code.

Also, this is not completely secure as we will be using files on the host machine to feed at the build time, so if you're considering commiting this to your repository, commit just the secrets' file structure with no content.

Initial docker container that I used for a Laravel application:

mysql:
    image: mysql:8.0.22
    container_name: mysql
    restart: unless-stopped
    tty: true
    volumes:
      - ./mysql:/var/lib/mysql
    ports:
      - "3307:3306"
    environment:
      MYSQL_DATABASE: db_name
      MYSQL_USER: user_name
      MYSQL_PASSWORD: db_password
      MYSQL_ROOT_PASSWORD: db_root_password
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
  

To use Docker Secrets, we need to create two files (for two passwords). I created it in the same level as the docker-compose.yml inside a folder secrets named db_password.txt and db_root_password.txt (commit at this point) and then add the passwords inside them.

Now let's change the docker container definition to this:

mysql:
    image: mysql:8.0.22
    container_name: mysql
    restart: unless-stopped
    tty: true
    volumes:
      - ./mysql:/var/lib/mysql
    ports:
      - "3307:3306"
    environment:
      MYSQL_DATABASE: db_name
      MYSQL_USER: db_user
      MYSQL_PASSWORD_FILE: /run/secrets/db_password
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    secrets:
      - db_password
      - db_root_password
      
  
secrets:
  db_password:
    file: ./secrets/db_password.txt
  db_root_password:
    file: ./secrets/db_root_password.txt

Define a secrets section on your docker-compose.yml with the file locations and then in the mysql section, we'll just use those without the extension during runtime.

Important thing to note is that MYSQL_PASSWORD and MYSQL_ROOT_PASSWORD have been replaced by MYSQL_PASSWORD_FILE and MYSQL_ROOT_PASSWORD_FILE

Run docker-compose up -d and your MySQL installation should be using these passwords from the files :)