Peter Lyons

How to use docker to run local databases

December 05, 2017

Here's how I run use docker to run databases for local development. I think my approach is the simplest I've seen and if something is unnecessary I skip it. You don't need data containers or port mappings, so I don't use them. The goal here is to make it very easy to run databases while developing applications or doing DB development work. It's basically the same for macOS and linux but I'm currently on macOS so that's where my instructions come from.

Goals

  1. Same process works mostly the same for many databases (postgresql, mysql, mongodb, redis, etc)
  2. Data persists as expected
    • Can start/stop containers, reboot host without losing data
  3. When we want to wipe data and start fresh, that's easy too
  4. Easy to transfer files into the container and out of the container
  5. Easy to get a shell inside the container to run tools there (psql etc)
  6. Easy to purge when done

My Approach

The compose file

# Run with:
# docker-compose -f ~/projects/dotfiles/docker-compose-local-dev.yml up -d
version: '2'
services:
  # https://hub.docker.com/_/postgres/
  postgres:
    container_name: 'postgres'
    ports: ['127.0.0.1:5432:5432']
    volumes: [
      # for ad-hoc transfers in/out of container
      '~/docker-volumes/host:/host',
      # for DB data itself
      '~/docker-volumes/postgres:/var/lib/postgresql/data'
      ]
    image: 'postgres'
    environment:
      POSTGRES_PASSWORD: 'password'
      PGDATA: '/var/lib/postgresql/data/pgdata'
  mysql:
    container_name: 'mysql'
    ports: ['127.0.0.1:3306:3306']
    volumes: [
      # for ad-hoc transfers in/out of container
      '~/docker-volumes/host:/host',
      # for DB data itself
      '~/docker-volumes/mysql:/var/lib/mysql'
      ]
    image: 'mysql'
    environment:
      MYSQL_ROOT_PASSWORD: 'password'
  mongo:
    container_name: 'mongo'
    ports: ['127.0.0.1:27017:27017']
    volumes: [
      # for ad-hoc transfers in/out of container
      '~/docker-volumes/host:/host',
      # for DB data itself
      '~/docker-volumes/mongo:/data/db'
      ]
    image: 'mongo'
  dynamodb:
   container_name: 'dynamodb'
   ports: ['127.0.0.1:8000:8000']
   volumes: [
        # for ad-hoc transfers in/out of container
        '~/docker-volumes/host:/host',
        # for DB data itself
        '~/docker-volumes/dynamodb:/var/dynamodb_local'
        ]
   image: 'peopleperhour/dynamodb'
  redis:
    container_name: 'redis'
    ports: ['127.0.0.1:6379:6379']
    volumes: [
      # for ad-hoc transfers in/out of container
      '~/docker-volumes/host:/host',
      # for DB data itself
      '~/docker-volumes/redis:/data'
      ]
    image: 'redis'

Check the docker compose file in my github dotfiles repo for latest version.

How to do basic operations

Commands are run from the host (macOS) terminal unless explicitly marked as run from within a container.

Bonus docker shell aliases

These may come in handy:

alias dcf="docker-compose -f ~/projects/dotfiles/docker-compose-local-dev.yml"
alias dcup="docker-compose -f ~/projects/dotfiles/docker-compose-local-dev.yml up -d"
alias deit="docker exec --interactive --tty"
alias doco="docker-compose"
alias dpa="docker ps -a"
alias drit='docker run --rm --interactive --tty'