Where is my Docker Wordpress Website Storing Data? - mysql

I currently have a Wordpress container set up in Docker, and have it linked to a MySQL database on the same machine (that is not in a Docker container). I played around with editing the website in my browser, deleting the Wordpress container, and creating a new one linked to the same database.
When I did this, the sample posts I made on my website persisted, so I assumed my data was being stored by my database locally. However, I then tried setting up multiple websites using Wordpress Multisite using one Wordpress container. To do this, I had to edit the Wordpress config file inside the Wordpress container.
I deleted this container, and created a new one like before. I tried replicating the config changes in this container, however, when I navigate to my website, it just gives me a white screen. This leads me to think that the MySQL database is pointing to empty tables all of a sudden.
Where are my Wordpress templates/info actually being stored?
EDIT: Below is the command I run
sudo docker run -p 80:80 --name wordpress_local -e WORDPRESS_DB_HOST=(machine's IP address) -e WORDPRESS_DB_USER=user -e WORDPRESS_DB_PASSWORD=password -d wordpress
Note: This is assuming I have a local MySQL database set up that accepts connections from 0.0.0.0 and has a user called user with password password
I know that my container is properly linking to the database from looking at the logs (and the fact that I can access the website--just get a blank page)
EDIT 2: Looking at my Wordpress container filesystem, I can navigate different folders and do see content such as themes/plugins that I have installed. Why is this not being stored on my local machine? (Sorry if this is a dumb question--I am new to both MySQL and Docker)

When you run wordpress container for the first time, the initialization script downloads the wordpress codebase to /var/www/html and then start the web server. Since everything inside a container is ephemeral, the codebase with any changes you make will be lost when you re-run the container (unless you just stop/start the container which is not the best option for this scenario).
What you need is to make this folder have persistent data. To achieve this you have to mount a folder from the host machine inside the container:
sudo docker run -p 80:80 \
--name wordpress_local \
-e WORDPRESS_DB_HOST=(machine's IP address) \
-e WORDPRESS_DB_USER=user \
-e WORDPRESS_DB_PASSWORD=password \
-d \
-v `pwd`/html:/var/www/html \
wordpress
Don't forget, the folder should be already created: mkdir -p data

Related

Restore Docker MySQL database

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>

Are sql dumps moved into docker container `docker-entrypoint-initdb.d` encrypted?

I'm dumping a database into a sql dump:
docker exec mysql sh -c 'exec mysqldump --all-databases -uroot -ppassword' > all-databases.sql
Then I'm using a Dockerfile to build a mysql image and run as a container:
FROM mysql:5.6.41
# needed for intialization
ENV MYSQL_ROOT_PASSWORD=whateverPassword
ADD all-databases.sql /docker-entrypoint-initdb.d/
EXPOSE 3306
When I run the container if I exec into the container, can I access the all-databases.sql file and see the contents of my database in plaintext in the docker image?
Currently if I look into /docker-entrypoint-initdb.d/ it says all-databases.sql but I don't know where that file is stored/if it's encrypted.
If you docker exec into the container, the file will be unencrypted. (It's just a text file and you can look at it with more on most image bases.)
However, if you can run any Docker command at all, then generally it's trivial to get unrestricted root access on the system. (Consider using docker run -v /etc:/host-etc to add yourself to /etc/sudoers or to allow root logins with no password.)
Also remember that anyone who has the image can docker run it and see the file there, if that matters to your security concerns. If you're looking for a single file with root access on the system anyways, you can find it without too much effort in /var/lib/docker. They can also easily run docker history to see the database root password you've set.

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.