Use Docker for Local Databases
Table of Contents
Problem
You want access to a local database for some reason. You might be doing web or app development, or practicing SQL queries, or whatever. Why you want a local database is your business.
Solution
Use Docker. It can manage your data (with docker volume
), your databases and versions (with docker images
), and makes cleanup very simple so as to not overburden your computer.
For these examples, I’m using Docker version 3.1.0 on OSX.
Example 1: DB only
For this, I’m using MySQL, although conceptually changing to any other database (e.g. PostGREs, Mongo, Maria) is straightforward. To create a Docker managed database (without a corresponding database management system), we can create the following Makefile
.
Setup
# ./Makefile
# local variables
# these can be imported from a separate config file
MYSQL_DATA_IMAGE_NAME=steve-data
MYSQL_INIT_FILE=dev.mysql.list
SHELL_USER=steve
DOCKER_NETWORK=steve-network
MYSQL_IMAGE_NAME=steve-dev-mysql
MYSQL_PORT=3306 # <-- can be different to avoid port collisions.
# create network and volume
# only needs to be run once
setup:
docker network create $(DOCKER_NETWORK)
docker volume create --name $(MYSQL_DATA_IMAGE_NAME)
# start database in a docker instance.
start-db:
docker run --name $(MYSQL_IMAGE_NAME) -v $(MYSQL_DATA_IMAGE_NAME):/var/lib/mysql --network $(DOCKER_NETWORK) --env-file $(MYSQL_INIT_FILE) --detach --publish $(MYSQL_PORT):3306 mysql:5.7
# stop database instance.
stop-db:
docker stop $(MYSQL_IMAGE_NAME)
docker rm $(MYSQL_IMAGE_NAME)
shell:
docker exec -it $(MYSQL_IMAGE_NAME) mysql -u $(SHELL_USER) -p
shell-root:
docker exec -it $(MYSQL_IMAGE_NAME) mysql -u root -p
inspect:
docker inspect $(MYSQL_IMAGE_NAME)
ip_addr:
docker inspect $(MYSQL_IMAGE_NAME) | grep IPAddress
clean:
docker volume rm $(MYSQL_DATA_IMAGE_NAME)
And, we can provide the specified environment configuration file as follows:
# ./dev.mysql.list
MYSQL_USER=steve
MYSQL_PASSWORD=password
MYSQL_ROOT_PASSWORD=password
Run
To run this, cd
into the same directory as the Makefile
, and enter:
$ ls
Makefile dev.mysql.list
$ make setup
$ make start-db
You can then interact with the database via the cli. For example, to administer user permissions (for later use when seeding data, or whatever), you might do the following.
$ make shell-root
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.32 MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.01 sec)
mysql> SHOW GRANTS for 'steve';
+------------------------------------------------------+
| Grants for steve@% |
+------------------------------------------------------+
| GRANT USAGE ON *.* TO 'steve'@'%' |
+------------------------------------------------------+
1 rows in set (0.00 sec)
mysql> GRANT INSERT, UPDATE, DELETE ON *.* TO 'steve';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW GRANTS FOR 'steve';
+----------------------------------------------------+
| Grants for steve@% |
+----------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE ON *.* TO 'steve'@'%' |
+----------------------------------------------------+
1 row in set (0.00 sec)
And later, to stop the database container, run
$ make stop
And finally, if you want to destroy the data from that database to free up hard drive space, type
$ make clean
Example 2: DB and DBMS
Sometimes you may additionally want to have available a database management system without committing to a full install. For example, Sequel Ace is a very popular piece of database management software for MySQL and Maria databases, but is only compatible on OSX. MySQL Workbench is a popular but bulky choice if you’re not 100% committed to using it regularly.
In this case, we can use docker-compose
to build both the database server, and a locally hosted database management system.
Setup
We’ll again use MySQL as the database, and select Adminer (formerly phpMyAdmin) as the database management system. It’s not amazing, but it does everything we need as lightweight solution.
First, create a docker-compose.yml
file
# ./docker-compose.yml
version: '3.1'
services:
adminer:
container_name: admin_portal
image: adminer
restart: always
ports:
- 8080:8080
db:
container_name: steve_db
image: mysql:5.6
ports:
- 3306:3306
volumes:
- steve_data:/var/lib/mysql
env_file:
- mysql.dev.list
volumes:
steve_data:
The mysql environment configuation file, mysql.dev.list
# ./mysql.dev.list
MYSQL_ROOT_PASSWORD=password
MYSQL_USER=steve
MYSQL_PASSWORD=password
MYSQL_DATABASE=test_db
Finally, we can build a Makefile
to simplify commands
# ./Makefile
DATABASE_IMAGE=steve_db
DEFAULT_USER=steve
up:
docker-compose up -d
down:
docker-compose down
shell:
docker exec -it $(DATABASE_CONTAINER) mysql -u $(DEFAULT_USER) -p
inspect:
docker inspect $(DATABASE_CONTAINER)
ip_addr:
docker inspect $(DATABASE_CONTAINER) | grep IPAddress
Run
Now, to start the database, we cd
into the root directory with the Makefile
and docker-compose.yml
and run
$ ls
Makefile docker-compose.yml mysql.dev.list
$ make up
Now, we can either interact with the database via the cli
$ make shell
Or, we can open a browser, navigate to https://localhost:8080, and find Adminer. Simply login with the credentials you provided in the mysql.dev.list
configuration file.