Skip to content

Instantly share code, notes, and snippets.

@thaJeztah
Last active January 14, 2024 02:00
Show Gist options
  • Star 94 You must be signed in to star a gist
  • Fork 23 You must be signed in to fork a gist
  • Save thaJeztah/8d0e901bd21329d80cf2 to your computer and use it in GitHub Desktop.
Save thaJeztah/8d0e901bd21329d80cf2 to your computer and use it in GitHub Desktop.
Some docker examples

Commit, clone a container

To 'clone' a container, you'll have to make an image of that container first, you can do so by "committing" the container. Docker will (by default) pause all processes running in the container during commit to preserve data-consistency.

For example;

docker commit --message="Snapshot of my container" my_container my_container_snapshot:yymmdd

Commit my_container as an image called my_container_snapshot, and tag it yymmdd. The "message" is optional and allows adding some extra info to the image.

$ docker images

REPOSITORY            TAG      IMAGE ID      CREATED        VIRTUAL SIZE
my_container_snapshot yymmdd   9496ac4a89a6  5 seconds ago  85.1 MB

To view the "message" we added earlier, inspect the image using docker inspect [imagename], and to get just the message provide a --filter option. In this case:

$ docker inspect --format="{{.Comment}}" my_container_snapshot:yymmdd
Snapshot of my container

You can start a new container from this snapshot;

docker run --name=my_clone my_container_snapshot:yymmdd

This will start a new container called "my_clone", using the snapshot we created earlier.

Volumes

When dealing with database containers, most containers use a volume for data storage. Data in volumes is not considered part of the containers filesystem and will therefore not be included when committing a container (nor will it be when using docker export or docker save).

To check if a container uses volumes and where they are located, use docker inspect. To get just the information about 'volumes', we're providing a --filter;

$ docker inspect --format="{{json .Volumes}}" my_container

{"/var/lib/mysql":"/var/lib/docker/vfs/dir/8274456ae711beb73de3ba0d969931c260a1bf063088f436fb08eb79b546d21d"}

This container, running mysql, is using a volume for /var/lib/mysql, and is stored inside /var/lib/docker/vfs/dir/8274456ae711beb73de3ba0d969931c260a1bf063088f436fb08eb79b546d21d on the host filesystem.

Backing up volume data

To export data inside a volume, use a utility container, for example, to backup the /var/lib/mysql data directory of the example above, do something like this;

docker run --rm --volumes-from=my_container debian tar cvf - /var/lib/mysql | gzip > mysql-data.tar.gz

This instruction will;

  • start a debian container
  • connect to the volumes of my_container and mount those volumes at the same location as inside my_container (ie, /var/lib/mysql)
  • Tar + Gzip the /var/lib/mysql directory to a file called mysql-data.tar.gz in the current directory on the host
  • Perform harakiri (it's a "self destructing" container; setting --rm will destroy the container after the command has completed)

Export a database

To export a database, again use a utility container containing the tool to backup your data, for example, to backup a mysql database;

docker run --rm --link=my_container:db mysql:latest mysqldump --host=db -u root my_database > my_database_dump.sql

This instruction will;

  • start a mysql container (but doesn't start the mysql server, because we're providing a different command)
  • establish a link to my_container and name that link db
  • add an entry to /etc/hosts inside the container for the db link. This enables us to connect to the linked container by using db as hostname.
  • do a mysqldump of the database in the linked container (using db as hostname)
  • export the dump to a file called my_database_dump.sql in the current directory
  • delete the container after the command has completed.

Import the database in a new container

[write]

@prabodhmeshram
Copy link

prabodhmeshram commented Apr 10, 2018

@thaJeztah wow, this gist was super helpful to deal with databases which stores data in volumes. Waiting for your section to import the database. ❤️

Just an update

The command doesn't seem to work now.

$ docker inspect --format="{{json .Volumes}}" my_container

Try instead

$ docker inspect --format="{{json .Mounts}}" my_container

@andruhon
Copy link

Just a couple more examples of how to do a backup and a restore

Backup / Snapshot the db:

 	docker run --rm --volumes-from=your_database_container -ti ubuntu:18.04 /bin/bash
	cp /var/lib/mysql /docker-entrypoint-initdb.d/db_backup -r

Restore the db:

 	docker run --rm --volumes-from=your_database_container -ti ubuntu:18.04 /bin/bash
	rm /var/lib/mysql/* -rf
	cp /docker-entrypoint-initdb.d/db_backup/* /var/lib/mysql -rf

The container, obviously, should not be running at a moment when you do backup or restore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment