Skip to content

Instantly share code, notes, and snippets.

@willhaslett
Last active March 10, 2018 05:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save willhaslett/1718968e4c1c3e45e734060915fd84f6 to your computer and use it in GitHub Desktop.
Save willhaslett/1718968e4c1c3e45e734060915fd84f6 to your computer and use it in GitHub Desktop.
BMDS Research Software Docker setup

Prerequisites

  • Install Docker. Ubuntu, Mac, Windows. The following instructions are for Linux and Mac. No promises for Windows.
  • On Linux, the daemon is running after install. Just add yourself to the docker group with sudo usermod -aG docker <username>. On Mac, launch Docker.app to start the daemon. No privilege changes are needed.

Setup the ORALS repo

  • Clone the ORALS repo to your box git clone git@github.com:dartmouth-ic3d/orals.git and cd into the repo.
  • Create the two required out-of-repo files for the ORALS app. There are no secrets here as different values are used on deployed tiers.
    • ./config/application.yml
      ROOT_EMAIL: <email for local login>
      ROOT_PASSWORD: <password for local login>
      OTP_KEY: 0673c38ae98c264d9f2eb809189219ea3131461a3a74549f9c502d32bb82754bc9a2b469657ec1d13da7a9bb26e6ace0d7917940085c9b9aba12a46340d7b2a6
      AUDIO_ENCRYPTION_KEY: 331bdcfc8cb653793068a7e612080751
      APP_DISPLAY_NAME: 'Open Recordings'
      
    • ./config/database.yml
      default: &default
        adapter: postgresql
        encoding: unicode
        pool: 5
        timeout: 5000
        host: db
        username: postgres
      development: <<: *default database: orals_development
      test: <<: *default database: orals_test

Fire it up

tl;dr: docker-compose up, coffee break, open a new terminal, docker exec -it orals_web_1 bundle exec rake db:reset

  • Run docker-compose up. Since you have no images, containers, or volumes yet, this command will do a lot the first time you run it. It will:

    • Download the two images required by the app, postgres and ruby:2.4-stretch.
    • Create a container using the postgres image (this corresponds to a docker service called "db").
    • Start the db container, and start the postgres daemon.
    • Create a container using the Ruby image (for a service called "web") and start it.
    • Install the Debian packages prescribed in the Dockerfile into the web container.
    • Create a volume called orals_gems that will hold the Ruby libraries required by the app.
    • Install all required gems.
    • Start the web server.

    The docker-compose up command will not exit. It will become the terminal in which you view server output during development. When it is ready, the last two lines of output will be:

    web_1  | * Listening on tcp://0.0.0.0:3000
    web_1  | Use Ctrl-C to stop
    
  • Leave the web server process running and open a new terminal session.

  • Your app is running, but you have no database. You can setup a vanilla database for the app using a rake command inside the web container, docker exec -it orals_web_1 bundle exec rake db:reset. When this command exits, you should get the ORALS login page at http://0.0.0.0:3000, and you can log in using the credentials in database.yml.

Workflow

Coding

Docker is monitoring the code tree for changes and they will be seen in the browser upon saving. You can proceed with development as if Docker were not there, including branch changes, except when there are changes to Gemfile, Dockerfile, or docker-compose.yml. In those cases, use docker-compose restart.

Updating images

tl;dr: use the dup alias defined in the next section to launch your containers. This will make sure the whole stack is up-to-date. If your conatainers are already running, you can still use dup to stop them, update your images, and restart.

Updates to the Debian layer underlying both the Postgres and Ruby images are made by the Debian image maintainers. When you use docker pull to update the images that your project uses, Docker will automatically pull any updates to lower layer images, such as the Debian image. For images that use the tag latest, you don't need to specify the tag when pulling updates, for example, docker pull postgres. When your images uses a specific tag, specifify the tag when pulling, for example, docker pull ruby:2.4-stretch.

Packages that Docker installs using apt are specified in Dockerfile as the arguments to the RUN instruction. These packages are installed every time you recreate your containers, e.g. with docker-compose restart, so any updates to these packages will be applied upon restart.

Restoring a Postgres dump

  • See the db-deidentify repo to get set up to create local deidentified snapshots of a project's production database.
  • Add this function to your bash environment, .bashrc on Linux and .bash_profile on Mac.
      dpgrestore() {                                                                                         
      	# $1 = name of target database in container                                                          
      	# $2 = path to your pg_dump file                                                                     
      	DB_CONTAINER="$(docker-compose ps -q db)"                                                            
      	docker-compose stop web                                                                              
      	echo Copying dump file to db container                                                               
      	docker cp $2 "${DB_CONTAINER}":tmp.dump                                                              
      	echo Dropping db "$1"                                                                                
      	docker exec "${DB_CONTAINER}" dropdb -U postgres --if-exists $1                                      
      	echo Creating db "$1"                                                                                
      	docker exec "${DB_CONTAINER}" createdb -U postgres $1                                                
      	echo Executing pg_restore                                                                            
      	docker exec "${DB_CONTAINER}" pg_restore -x --no-owner -U postgres -d "$1" tmp.dump                  
      	echo Starting web container                                                                          
      	docker-compose start web                                                                             
      }        
      
  • Restore an existing pg_dump file: dpgrestore orals_development path_to_dump_file.

Aliases for convenience

  • Show the status of all images and containers
    alias do='echo "" && docker images && echo "" && docker ps -a && echo ""'

  • Update all upstream images, then and run all containers needed for the current project
    alias dup="docker pull `grep FROM Dockerfile | awk '{print $NF}'` && docker-compose pull && docker-compose down && docker-compose up"

  • Stop and destroy all containers for the current project
    alias ddown='docker-compose down'

  • Open a Rails console
    alias dconsole='docker exec -it `docker-compose ps -q web` bundle exec rails console'

  • Reset the database
    alias ddbreset='docker exec `docker-compose ps -q web` bundle exec rake db:reset'

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