Restore Docker MySQL database - mysql

I'm new to Docker and learning about it. I'm using a Docker container of MySQL and I have created two databases with populated tables.
I've pushed the image to Docker Hub so I can use it on another device but I've tried several times whenever I pull my MySQL repository and run it I don't see any of my databases. I think I'm doing it the wrong way.
Mysql Databases from the pulled image
How can I push the MySQL image with its two databases to Docker Hub the right way?

Rather than have the database included in your image, you can have SQL scripts in your image that creates the database and populates it with initial data.
If you put files ending in .sh, .sql or .sql.gz in the /docker-entrypoint-initdb.d directory in the image, they will be run the first time the container is run.
If you have an SQL script to initialize your database, you can include it in the image by having a Dockerfile like this
FROM mysql:latest
COPY initialize-database.sql /docker-entrypoint-initdb.d/
Then you can run the container and map /var/lib/mysql to a docker volume that will store the database like this
docker run --rm -e MYSQL_ROOT_PASSWORD=password -v mysql:/var/lib/mysql <my-image-name>

Related

Move MySQL /var/lib/mysql to shared volume

I'm running a container with MySQL 8.0.18 in Docker on a Synology nas. I'm just using it to support another container (Mediawiki) on that box. MySQL has one volume mounted at path /var/lib/mysql. I would like to move that to a shared volume so i can access it with File Station and also periodically back it up. How can i move it to the docker share shown below without breaking MySQL?
Here are available shares on the Synology nas.
Alternatively, is there a way i can simply copy that /var/lib/mysql to the shared docker folder? That should work as well for periodic backups.
thanks,
russ
EDIT: Showing result after following Zeitounator's plan. Before running the docker command (2.) i created the mediawiki_mysql_backups and 12-29-2019 folders in File Station. After running 2. and 3. all the files from mysql are here and i now have a nice backup!
Stop your current container to make sure mysql is not running.
Create a dummy temp container where you mount the 2 needed volumes. I tend to user busybox for this kind of tasks => docker run -it --rm --name temp_mysql_copy -v mediaviki-mysql:/old-mysql -v /path/to/ttpe/docker:/new-mysql busybox:latest
Copy all files => cp -a /old-mysql/* /new-mysql/
Exit the dummy container (which will cleanup by itself if you used my above command)
Create a new container with mysql:8 image mounting the new folder in /var/lib/mysql (you probably need to do this in your syno docker gui).
If everything works as expected, delete the old mediaviki-mysql volume

Unexpected behaviour when extending the mysql Dockerfile

I created the following Dockerfile:
FROM mysql:5.7
ADD assets/geograph.cnf /etc/mysql/conf.d
ENV MYSQL_DATABASE=geograph \
MYSQL_RANDOM_ROOT_PASSWORD=yes
ADD http://data.geograph.org.uk/dumps/gridimage_base_sample.mysql.gz /docker-entrypoint-initdb.d/gridimage_base_sample.sql.gz
I then created an image from this Dockerfile:
docker build --tag geograph:latest .
I then created a container from this image:
docker run --name geograph -e MYSQL_USER=geograph -e MYSQL_PASSWORD=geograph --detach geograph:latest
However, I've noticed some unexpected behaviour:
The container starts and then stops. (I've compared docker ps and docker ps --all.)
The geograph database doesn't contain the data from gridimage_base_sample.sql.gz, which was created by mysqldump. (I've verified the database dump.)
I expected the container to behave like the base MySQL image (mysql:5.7), with some additional configuration and some data. What am I doing wrong?
Some context: I'd like to use the database for analysis, ensuring that the results of my analysis are repeatable. I'm not going to be creating/deleting records and host/guest will probably be on the same machine. I've experimented with using another image/container to curl the database dump into a volume and then mounting this volume when creating the geograph container. This solves #2 but not #1. (It also seems a bit unnecessary to have two images/containers but that's not terribly important: if two are required, then two are required!)
Thanks in advance for any help.
Whilst the above image could ADD the database dump, the MySQL image couldn't unzip it because of a permissions error. (The user didn't have permission to write to /docker-entrypoint-initdb.d.) Seemingly this was enough to cause the container to stop (#1) and explains why the geograph database didn't contain the data from gridimage_base_sample.sql.gz (#2).

docker best way to run mysql

I'm new in docker, and i have two microservices running in two containers and i would like to create simple database for them.
i created it like that:
docker run --net=kajsnetwork -d -e MYSQL_ROOT_PASSWORD='mypassword' -v /storage/mysql1/mysql-datadir:/var/lib/mysql mysql
i enter the container using
docker exec -it containernumber /bin/bash
and then i created database... But when i went to /var/lib/mysql mysql on host i haven't there nothing new - no database which i created from docker file. Did i something wrong ?
I would like to have database with data stored on host, but running in a docker container (is it good solution?) ? How to do it correctly?
You should not have to docker exec to create an instance: the container should already have one.
The doc mentions:
The -v /my/own/datadir:/var/lib/mysql part of the command mounts the /my/own/datadir directory from the underlying host system as /var/lib/mysql inside the container, where MySQL by default will write its data files.
So the order matters.
The docker cmd option -v /storage/mysql1/mysql-datadir:/var/lib/mysql indicates that you are mounting host directory /storage/mysql1/mysql-datadir to /var/lib/mysql as a data volume of the container.
So if you check /var/lib/mysql from the container your should see the same contents as /storage/mysql1/mysql-datadir in your host machine.
More details:
https://docs.docker.com/engine/tutorials/dockervolumes/#mount-a-host-directory-as-a-data-volume

How Wordpress should be runned on Docker

I am very newbie on all of this stuff of Docker. I've read on some sites that should exist one image per each application is running. This means that for run wordpress I would need at least 2 images: One for MySQL and another for Wordpress (and apache). In fact, the official Wordpress docker image does not include MySQL, requires an external connection.
But I've found some images in which MySQL is embedded on the image among wordpress and Apache. This gives you a more portable image because you only need that to deploy on any server. But if in the system is already running an image of docker you are wasting resources.
So, my question is if Wordpress should be runned on a same image with MySQL or not. And if not, how it should be done to move all data on MySQL to a different location.
The standart way is having a container per service, so you will have a container for MySQL and another one for Apache/PHP with the application.
If your are going to use the official MySQL container, and you want to persist the data, you just can to mount a volume from your host to the datadir in the mysql container:
$ docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
This will create a folder in the /my/own/datadir path of your host with all the content of MySQL.
You can find more information about that in that link:
https://github.com/docker-library/docs/tree/master/mysql#where-to-store-data

Can I use fig to initialise a persisting database in docker?

I am trying to automate the installation and running of set of linked docker containers using fig. The configuration is composed of a container running RStudio linked to a container running MySQL, such that I can query the MySQL database from RStudio.
On first run, I would like to create the MySQL container from the base MySQL image, and populate it with a user and database. From the command line, something like this:
#Get the latest database file
wget -P /tmp http://ergast.com/downloads/f1db.sql.gz && gunzip -f /tmp/f1db.sql.gz
#Create the database container with user, password and database
docker run --name ergastdb -e MYSQL_USER=ergast -e MYSQL_ROOT_PASSWORD=mrd -e MYSQL_DATABASE=f1db -d mysql
#Populate the database
docker run -it --link=ergastdb:mysql -v /tmp:/tmp/import --rm mysql sh -c 'exec mysql -h$MYSQL_PORT_3306_TCP_ADDR -P$MYSQL_PORT_3306_TCP_PORT -uergast -pmrd f1db < /tmp/import/f1db.sql'
#Fire up RStudio and link to the MySQL db
docker run --name f1djd -p 8788:8787 --link ergastdb:db -d rocker/hadleyverse
If I could get hold of a database image with the data preloaded, I guess that something like the following fig.yml script could link the elements?
gdrive:
command: echo created
image: busybox
volumes:
- "~/Google Drive/shareddata:/gdrive"
dbdata:
image: mysql_preloaded
environment:
MYSQL_USER=ergast
MYSQL_ROOT_PASSWORD=mrd
MYSQL_DATABASE=f1db
rstudio:
image: rocker/hadleyverse
links:
- dbdata:db
ports:
- "8788:8787"
volumes_from:
- gdrive
My question is, can I use a one-shot fig step to create the dbdata container, then perhaps mount a persistent volume, link to it and initialise the database, presumably as part of an initial fig up. If I then start and stop containers, I don't want to run the db initialisation step again, just link to the data volume container that contains the data I previously installed.
I also notice that the MySQL docker image looks like it will support arbitrary datadir definitions (Update entrypoints to read DATADIR from the MySQL configuration directly instead of assuming /var/lib/docker). As I understand it, the current definition of the MySQL image prevents mounting (and hence persisting) the database contents within the database container. I guess this might make it possible to create a mysql_preloaded image, but I don't think the latest version of the MySQL docker script has been pushed to dockerhub just yet and I can't quite think my way to how fig might then be able to make use of this alternative pathway?
Some options:
Edit the fig.yml to run a custom command that is different than the default image command/entrypoint.
From http://www.fig.sh/yml.html (example):
command: bundle exec thin -p 3000
Start the container locally, modify it and then commit it as a new image.
Modify the MySQL image docker-entrypoint.sh file to do your custom initialization.
https://github.com/docker-library/mysql/blob/567028d4e177238c58760bcd69a8766a8f026e2a/5.7/docker-entrypoint.sh
Couldn't you just roll your own version of the MySQL docker image? The official one from MySQL "upstream" is available at https://github.com/mysql/mysql-docker/blob/mysql-server/5.7/Dockerfile
What if you simply make your own copy of that, remove the VOLUME line (line 11) and then you can
docker build -t my_mysql .
docker run -d --name=empty_db my_mysql ...
# add data to the database running in the container
docker commit empty_db primed_db
docker rm -v empty_db
docker run -d --name=instance1 primed_db
docker run -d --name=instance2 primed_db
which should leave you with two running "identical" but fully isolated instances.