Most of the following sample commands have
          container-registry.oracle.com/mysql/community-server
          as the Docker image being used (like with the docker
          pull and docker run commands);
          change that if your image is from another repository—for
          example, replace it with
          container-registry.oracle.com/mysql/enterprise-server
          for MySQL Enterprise Edition images downloaded from the Oracle Container Registry
          (OCR), or mysql/enterprise-server for MySQL Enterprise Edition
          images downloaded from
          My Oracle
          Support.
The Optimized MySQL Installation for Docker
Docker images for MySQL are optimized for code size, which means they only include crucial components that are expected to be relevant for the majority of users who run MySQL instances in Docker containers. A MySQL Docker installation is different from a common, non-Docker installation in the following aspects:
- Only a limited number of binaries are included. 
- All binaries are stripped; they contain no debug information. 
Any software updates or installations users perform to the Docker container (including those for MySQL components) may conflict with the optimized MySQL installation created by the Docker image. Oracle does not provide support for MySQL products running in such an altered container, or a container created from an altered Docker image.
Configuring the MySQL Server
When you start the MySQL Docker container, you can pass configuration options to the server through the docker run command. For example:
docker run --name mysql1 -d container-registry.oracle.com/mysql/community-server:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_col
        The command starts the MySQL Server with
        utf8mb4 as the default character set and
        utf8mb4_col as the default collation for
        databases.
      
Another way to configure the MySQL Server is to prepare a configuration file and mount it at the location of the server configuration file inside the container. See Persisting Data and Configuration Changes for details.
Persisting Data and Configuration Changes
        Docker containers are in principle ephemeral, and any data or
        configuration are expected to be lost if the container is
        deleted or corrupted (see discussions
        here).
        Docker
        volumes provides a mechanism to persist data created
        inside a Docker container. At its initialization, the MySQL
        Server container creates a Docker volume for the server data
        directory. The JSON output from the docker
        inspect command on the container includes a
        Mount key, whose value provides information
        on the data directory volume:
      
$> docker inspect mysql1
...
 "Mounts": [
            {
                "Type": "volume",
                "Name": "4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652",
                "Source": "/var/lib/docker/volumes/4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652/_data",
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
...
        The output shows that the source directory
        /var/lib/docker/volumes/4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652/_data,
        in which data is persisted on the host, has been mounted at
        /var/lib/mysql, the server data directory
        inside the container.
      
        Another way to preserve data is to
        bind-mount
        a host directory using the --mount option when
        creating the container. The same technique can be used to
        persist the configuration of the server. The following command
        creates a MySQL Server container and bind-mounts both the data
        directory and the server configuration file:
      
docker run --name=mysql1 \
--mount type=bind,src=/path-on-host-machine/my.cnf,dst=/etc/my.cnf \
--mount type=bind,src=/path-on-host-machine/datadir,dst=/var/lib/mysql \
-d container-registry.oracle.com/mysql/community-server:tag
        The command mounts
        path-on-host-machine/my.cnf/etc/my.cnfpath-on-host-machine/datadir/var/lib/mysql (the data directory
        inside the container). The following conditions must be met for
        the bind-mounting to work:
- The configuration file - path-on-host-machine/my.cnf- mysql:- [mysqld] user=mysql- You can also include other server configuration options in the file. 
- The data directory - path-on-host-machine/datadir
Running Additional Initialization Scripts
        If there are any .sh or
        .sql scripts you want to run on the
        database immediately after it has been created, you can put them
        into a host directory and then mount the directory at
        /docker-entrypoint-initdb.d/ inside the
        container. For example:
      
docker run --name=mysql1 \
--mount type=bind,src=/path-on-host-machine/scripts/,dst=/docker-entrypoint-initdb.d/ \
-d container-registry.oracle.com/mysql/community-server:tagConnect to MySQL from an Application in Another Docker Container
By setting up a Docker network, you can allow multiple Docker containers to communicate with each other, so that a client application in another Docker container can access the MySQL Server in the server container. First, create a Docker network:
docker network create my-custom-net
        Then, when you are creating and starting the server and the
        client containers, use the --network option to
        put them on network you created. For example:
      
docker run --name=mysql1 --network=my-custom-net -d container-registry.oracle.com/mysql/community-serverdocker run --name=myapp1 --network=my-custom-net -d myapp
        The myapp1 container can then connect to the
        mysql1 container with the
        mysql1 hostname and vice versa, as Docker
        automatically sets up a DNS for the given container names. In
        the following example, we run the mysql
        client from inside the myapp1 container to
        connect to host mysql1 in its own container:
      
docker exec -it myapp1 mysql --host=mysql1 --user=myuser --passwordFor other networking techniques for containers, see the Docker container networking section in the Docker Documentation.
Server Error Log
When the MySQL Server is first started with your server container, a server error log is NOT generated if either of the following conditions is true:
- A server configuration file from the host has been mounted, but the file does not contain the system variable - log_error(see Persisting Data and Configuration Changes on bind-mounting a server configuration file).
- A server configuration file from the host has not been mounted, but the Docker environment variable - MYSQL_LOG_CONSOLEis- true(which is the variable's default state for MySQL 9.1 server containers). The MySQL Server's error log is then redirected to- stderr, so that the error log goes into the Docker container's log and is viewable using the docker logs- mysqld-containercommand.
        To make MySQL Server generate an error log when either of the
        two conditions is true, use the
        --log-error option to
        configure the
        server to generate the error log at a specific location
        inside the container. To persist the error log, mount a host
        file at the location of the error log inside the container as
        explained in
        Persisting Data and Configuration Changes. However,
        you must make sure your MySQL Server inside its container has
        write access to the mounted host file.
Using MySQL Enterprise Backup with Docker
MySQL Enterprise Backup is a commercially-licensed backup utility for MySQL Server, available with MySQL Enterprise Edition. MySQL Enterprise Backup is included in the Docker installation of MySQL Enterprise Edition.
In the following example, we assume that you already have a MySQL Server running in a Docker container (see Section 2.5.6.1, “Basic Steps for MySQL Server Deployment with Docker” on how to start a MySQL Server instance with Docker). For MySQL Enterprise Backup to back up the MySQL Server, it must have access to the server's data directory. This can be achieved by, for example, bind-mounting a host directory on the data directory of the MySQL Server when you start the server:
docker run --name=mysqlserver \
--mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
-d mysql/enterprise-server:9.1
        With this command, the MySQL Server is started with a Docker
        image of the MySQL Enterprise Edition, and the host directory
        /path-on-host-machine/datadir/ has
        been mounted onto the server's data directory
        (/var/lib/mysql) inside the server
        container. We also assume that, after the server has been
        started, the required privileges have also been set up for MySQL Enterprise Backup
        to access the server (see
        Grant MySQL Privileges to Backup Administrator, for details). Use the
        following steps to back up and restore a MySQL Server instance.
      
To back up a MySQL Server instance running in a Docker container using MySQL Enterprise Backup with Docker, follow the steps listed here:
- On the same host where the MySQL Server container is running, start another container with an image of MySQL Enterprise Edition to perform a back up with the MySQL Enterprise Backup command - backup-to-image. Provide access to the server's data directory using the bind mount we created in the last step. Also, mount a host directory (- /path-on-host-machine/backups/in this example) onto the storage folder for backups in the container (- /data/backupsin the example) to persist the backups we are creating. Here is a sample command for this step, in which MySQL Enterprise Backup is started with a Docker image downloaded from My Oracle Support:- $> docker run \ --mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \ --mount type=bind,src=/path-on-host-machine/backups/,dst=/data/backups \ --rm mysql/enterprise-server:9.1 \ mysqlbackup -umysqlbackup -ppassword --backup-dir=/tmp/backup-tmp --with-timestamp \ --backup-image=/data/backups/db.mbi backup-to-image- It is important to check the end of the output by mysqlbackup to make sure the backup has been completed successfully. 
- The container exits once the backup job is finished and, with the - --rmoption used to start it, it is removed after it exits. An image backup has been created, and can be found in the host directory mounted in the last step for storing backups, as shown here:- $> ls /tmp/backups db.mbi
To restore a MySQL Server instance in a Docker container using MySQL Enterprise Backup with Docker, follow the steps listed here:
- Stop the MySQL Server container, which also stops the MySQL Server running inside: - docker stop mysqlserver
- On the host, delete all contents in the bind mount for the MySQL Server data directory: - rm -rf /path-on-host-machine/datadir/*
- Start a container with an image of MySQL Enterprise Edition to perform the restore with the MySQL Enterprise Backup command - copy-back-and-apply-log. Bind-mount the server's data directory and the storage folder for the backups, like what we did when we backed up the server:- $> docker run \ --mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \ --mount type=bind,src=/path-on-host-machine/backups/,dst=/data/backups \ --rm mysql/enterprise-server:9.1 \ mysqlbackup --backup-dir=/tmp/backup-tmp --with-timestamp \ --datadir=/var/lib/mysql --backup-image=/data/backups/db.mbi copy-back-and-apply-log mysqlbackup completed OK! with 3 warnings- The container exits with the message " - mysqlbackup completed OK!" once the backup job is finished and, with the- --rmoption used when starting it, it is removed after it exits.
- Restart the server container, which also restarts the restored server, using the following command: - docker restart mysqlserver- Or, start a new MySQL Server on the restored data directory, as shown here: - docker run --name=mysqlserver2 \ --mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \ -d mysql/enterprise-server:9.1- Log on to the server to check that the server is running with the restored data. 
Using mysqldump with Docker
Besides using MySQL Enterprise Backup to back up a MySQL Server running in a Docker container, you can perform a logical backup of your server by using the mysqldump utility, run inside a Docker container.
        The following instructions assume that you already have a MySQL
        Server running in a Docker container and, when the container was
        first started, a host directory
        /path-on-host-machine/datadir/ has
        been mounted onto the server's data directory
        /var/lib/mysql (see
        bind-mounting
        a host directory on the data directory of the MySQL
        Server for details), which contains the Unix socket file
        by which mysqldump and
        mysql can connect to the server. We also
        assume that, after the server has been started, a user with the
        proper privileges (admin in this example) has
        been created, with which mysqldump can access
        the server. Use the following steps to back up and restore MySQL
        Server data:
      
Backing up MySQL Server data using mysqldump with Docker:
- On the same host where the MySQL Server container is running, start another container with an image of MySQL Server to perform a backup with the mysqldump utility (see documentation of the utility for its functionality, options, and limitations). Provide access to the server's data directory by bind mounting - /path-on-host-machine/datadir/. Also, mount a host directory (- /path-on-host-machine/backups/in this example) onto a storage folder for backups inside the container (- /data/backupsis used in this example) to persist the backups you are creating. Here is a sample command for backing up all databases on the server using this setup:- $> docker run --entrypoint "/bin/sh" \ --mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \ --mount type=bind,src=/path-on-host-machine/backups/,dst=/data/backups \ --rm container-registry.oracle.com/mysql/community-server:9.1 \ -c "mysqldump -uadmin --password='password' --all-databases > /data/backups/all-databases.sql"- In the command, the - --entrypointoption is used so that the system shell is invoked after the container is started, and the- -coption is used to specify the mysqldump command to be run in the shell, whose output is redirected to the file- all-databases.sqlin the backup directory.
- The container exits once the backup job is finished and, with the - --rmoption used to start it, it is removed after it exits. A logical backup been created, and can be found in the host directory mounted for storing the backup, as shown here:- $> ls /path-on-host-machine/backups/ all-databases.sql
Restoring MySQL Server data using mysqldump with Docker:
- Make sure you have a MySQL Server running in a container, onto which you want your backed-up data to be restored. 
- Start a container with an image of MySQL Server to perform the restore with a mysql client. Bind-mount the server's data directory, as well as the storage folder that contains your backup: - $> docker run \ --mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \ --mount type=bind,src=/path-on-host-machine/backups/,dst=/data/backups \ --rm container-registry.oracle.com/mysql/community-server:9.1 \ mysql -uadmin --password='password' -e "source /data/backups/all-databases.sql"- The container exits once the backup job is finished and, with the - --rmoption used when starting it, it is removed after it exits.
- Log on to the server to check that the restored data is now on the server. 
Known Issues
- When using the server system variable - audit_log_fileto configure the audit log file name, use the- looseoption modifier with it; otherwise, Docker cannot start the server.
Docker Environment Variables
        When you create a MySQL Server container, you can configure the
        MySQL instance by using the --env option (short
        form -e) and specifying one or more environment
        variables. No server initialization is performed if the mounted
        data directory is not empty, in which case setting any of these
        variables has no effect (see
        Persisting Data and Configuration Changes), and no
        existing contents of the directory, including server settings,
        are modified during container startup.
      
Environment variables which can be used to configure a MySQL instance are listed here:
- The boolean variables including - MYSQL_RANDOM_ROOT_PASSWORD,- MYSQL_ONETIME_PASSWORD,- MYSQL_ALLOW_EMPTY_PASSWORD, and- MYSQL_LOG_CONSOLEare made true by setting them with any strings of nonzero lengths. Therefore, setting them to, for example, “0”, “false”, or “no” does not make them false, but actually makes them true. This is a known issue.
- MYSQL_RANDOM_ROOT_PASSWORD: When this variable is true (which is its default state, unless- MYSQL_ROOT_PASSWORDis set or- MYSQL_ALLOW_EMPTY_PASSWORDis set to true), a random password for the server's root user is generated when the Docker container is started. The password is printed to- stdoutof the container and can be found by looking at the container’s log (see Starting a MySQL Server Instance).
- MYSQL_ONETIME_PASSWORD: When the variable is true (which is its default state, unless- MYSQL_ROOT_PASSWORDis set or- MYSQL_ALLOW_EMPTY_PASSWORDis set to true), the root user's password is set as expired and must be changed before MySQL can be used normally.
- MYSQL_DATABASE: This variable allows you to specify the name of a database to be created on image startup. If a user name and a password are supplied with- MYSQL_USERand- MYSQL_PASSWORD, the user is created and granted superuser access to this database (corresponding to- GRANT ALL). The specified database is created by a CREATE DATABASE IF NOT EXIST statement, so that the variable has no effect if the database already exists.
- MYSQL_USER,- MYSQL_PASSWORD: These variables are used in conjunction to create a user and set that user's password, and the user is granted superuser permissions for the database specified by the- MYSQL_DATABASEvariable. Both- MYSQL_USERand- MYSQL_PASSWORDare required for a user to be created—if any of the two variables is not set, the other is ignored. If both variables are set but- MYSQL_DATABASEis not, the user is created without any privileges.Note- There is no need to use this mechanism to create the root superuser, which is created by default with the password set by either one of the mechanisms discussed in the descriptions for - MYSQL_ROOT_PASSWORDand- MYSQL_RANDOM_ROOT_PASSWORD, unless- MYSQL_ALLOW_EMPTY_PASSWORDis true.
- MYSQL_ROOT_HOST: By default, MySQL creates the- 'root'@'localhost'account. This account can only be connected to from inside the container as described in Connecting to MySQL Server from within the Container. To allow root connections from other hosts, set this environment variable. For example, the value- 172.17.0.1, which is the default Docker gateway IP, allows connections from the host machine that runs the container. The option accepts only one entry, but wildcards are allowed (for example,- MYSQL_ROOT_HOST=172.*.*.*or- MYSQL_ROOT_HOST=%).
- MYSQL_LOG_CONSOLE: When the variable is true (which is its default state for MySQL 9.1 server containers), the MySQL Server's error log is redirected to- stderr, so that the error log goes into the Docker container's log and is viewable using the docker logs- mysqld-containercommand.Note- The variable has no effect if a server configuration file from the host has been mounted (see Persisting Data and Configuration Changes on bind-mounting a configuration file). 
- MYSQL_ROOT_PASSWORD: This variable specifies a password that is set for the MySQL root account.Warning- Setting the MySQL root user password on the command line is insecure. As an alternative to specifying the password explicitly, you can set the variable with a container file path for a password file, and then mount a file from your host that contains the password at the container file path. This is still not very secure, as the location of the password file is still exposed. It is preferable to use the default settings of - MYSQL_RANDOM_ROOT_PASSWORDand- MYSQL_ONETIME_PASSWORDboth being true.
- MYSQL_ALLOW_EMPTY_PASSWORD. Set it to true to allow the container to be started with a blank password for the root user.Warning- Setting this variable to true is insecure, because it is going to leave your MySQL instance completely unprotected, allowing anyone to gain complete superuser access. It is preferable to use the default settings of - MYSQL_RANDOM_ROOT_PASSWORDand- MYSQL_ONETIME_PASSWORDboth being true.