Using Docker to Run MySQL on WSL2

Situation

Your development environment is a Linux distribution made available on Windows through Windows Subsystem For Linux 2 (WSL2). You need to stand up a MySQL (or other) database that is persistent, available to your WSL2-enabled development environment, and accessible to database management systems (DBMS) natively installed on your Windows host.

Solution

We can containerize a MySQL (or other) database. I accomplished this using docker-compose, but you can probably easily modify this to run from a standalone Dockerfile if you wish.

docker-compose.yml

version: "3.9"

services:
  mysql-dev:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: my-secret-pw
    ports:
      - "3306:3306"
    volumes:
      - ./data:/var/lib/mysql

This should be saved in the directory that you intend to execute docker-compose from. Then, from the terminal, run:

$ docker-compose up --build -d

Explanation

  1. We create a container called mysql-dev using the mysql (latest tag implied) image hosted on the official mysql Docker hub registry.
  2. We run the command specified in the Mysql official Docker image documentation: --default-authentication-plugin=mysql_native_password. According to the MySQL 8.0 documentation, mysql_native_password is a plugin that implements authentication based on the password hashing method in use from before the introduction of plugable authentication.
  3. We set restart to always -- this is user preference, but generally I would like my database to restart automatically if it crashes.
  4. We set MYSQL_ROOT_PASSWORD in the environmental variables of the container. Since this is for development, the password doesn't really matter. Please do not use this password in production!
  5. We then map port 3306 (the standard port address of MySQL) of the host system to port 3306 of the container. This allows us to connect to the service running on the container using the host's IP address.
  6. We mount our local data directory, ./data, as a volume to the container's default MySQL data directory, /var/lib/mysql. This allows us to persist the data created in the database even if the container is destroyed.
  7. docker-compose up --build -d will run the container in "detached" mode--that is, it will be run as a background process and you will still have access to your teminal. You can validate that the container is running by using docker ps.

Connecting to MySQL

  • From the WSL2 terminal, we can connect to the container using localhost:3306 as our address.
  • From the Windows host, we can connect to the container using the WSL2 distros private IP address. To find this, from the WSL2 terminal, run ip a show eth0 (your interface may vary--if you receive no results, simply do ip a to show all interfaces).

Conclusion

I found it challenging to connect to a Windows MySQL instance from WSL2, which is why I researched the methodology shown above. I personally like the container approach because it can allow me to easily migrate the database in the future and it is portable in the event that I decide to develop from a different workstation.

Note: I used MySQL for this exercise, but perhaps you could achieve similar results with another database. Docker Hub supports images for most databases--find the system you prefer, read the documentation on the image, and apply the steps shown above to (hopefully) create a portable, persistent, development database.