Docker-Compose persistent data MySQL

I can’t seem to get MySQL data to persist if I run $ docker-compose down with the following .yml

version: '2'
services:
  # other services

  data:
    container_name: flask_data
    image: mysql:latest
    volumes:
      - /var/lib/mysql
    command: "true"

  mysql:
    container_name: flask_mysql
    restart: always
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: 'test_pass' # TODO: Change this
      MYSQL_USER: 'test'
      MYSQL_PASS: 'pass'
    volumes_from:
      - data
    ports:
      - "3306:3306"

My understanding is that in my data container using volumes: - /var/lib/mysql maps it to my local machines directory where mysql stores data to the container and because of this mapping the data should persist even if the containers are destroyed. And the mysql container is just a client interface into the db and can see the local directory because of volumes_from: - data

  • User-data script not executed when starting EC2 instance from AWS CLI
  • Practically, what is the difference between docker run -dit vs docker run -d?
  • Why is MariaDB data persistent in my Docker container? I don't have any volumes
  • node.js in a dockerfile cant connect to mongolabs via mongoose: getaddrinfo ESRCH
  • In a Docker Compose multi-container application, how to prevent Postgres from running statements previously issued
  • Installation of OpenFOAM throws read-only file system error while using Docker
  • Attempted this answer and it did not work. Docker-Compose Persistent Data Trouble

    EDIT

    Changed my .yml as shown below and created a the dir ./data but now when I run docker-compose up --build the mysql container wont start throws error saying

      data:
        container_name: flask_data
        image: mysql:latest
        volumes:
          - ./data:/var/lib/mysql
        command: "true"
    
      mysql:
        container_name: flask_mysql
        restart: always
        image: mysql:latest
        environment:
          MYSQL_ROOT_PASSWORD: 'test_pass' # TODO: Change this
          MYSQL_USER: 'test'
          MYSQL_PASS: 'pass'
        volumes_from:
          - data
        ports:
          - "3306:3306"
    
    
    flask_mysql | mysqld: Can't create/write to file '/var/lib/mysql/is_writable' (Errcode: 13 - Permission denied)
    flask_mysql | 2016-08-26T22:29:21.182144Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
    flask_mysql | 2016-08-26T22:29:21.185392Z 0 [ERROR] --initialize specified but the data directory exists and is not writable. Aborting.
    

  • Nginx Docker 400 Bad Request
  • Bash command to return a free port
  • Docker: how to set up file ownership in a data-only container?
  • Docker stop responding under load
  • Using docker image on local file
  • Filebeat multiline parsing of Java exception in docker container not working
  • 3 Solutions collect form web for “Docker-Compose persistent data MySQL”

    The data container is an superfluous workaround. Data-volumes would do the trick for you. Alter your docker-compose.yml to:

    version: '2'
    services:
      mysql:
        container_name: flask_mysql
        restart: always
        image: mysql:latest
        environment:
          MYSQL_ROOT_PASSWORD: 'test_pass' # TODO: Change this
          MYSQL_USER: 'test'
          MYSQL_PASS: 'pass'
        volumes:
          - my-datavolume:/var/lib/mysql
    volumes:
      my-datavolume:
    

    Docker will create the volume for you in the /var/lib/docker/volumes folder. This volume persist as long as you are not typing docker-compose down -v

    There are 3 ways:

    First. You need specify directory to store mysql data on your host machine. You can remove data container. Your mysql data will be saved on you local filesystem.

    Mysql container definition must looks like this

    mysql:
      container_name: flask_mysql
      restart: always
      image: mysql:latest
      environment:
        MYSQL_ROOT_PASSWORD: 'test_pass' # TODO: Change this
        MYSQL_USER: 'test'
        MYSQL_PASS: 'pass'
    volumes:
     - /opt/mysql_data:/var/lib/mysql
    ports:
      - "3306:3306"
    

    Second way is commit data container before typing docker-compose down:

    docker commit my_data_container
    docker-compose down
    

    Third way. Also you can use docker-compose stop instead of docker-compose down (then you don’t need commit container)

    You have to create an separate volume for mysql data.

    So it will look like this:

    volumes_from:
      - data
    volumes:
      - ./mysql-data:/var/lib/mysql
    

    And no, /var/lib/mysql is a path inside your mysql container and has nothing to do with a path on your host machine. Your host machine may even have no mysql at all. So the goal is to persist an internal folder from a mysql container.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.