Skip to content

Commit

Permalink
Setup bin utilities for database and entrypoint
Browse files Browse the repository at this point in the history
  • Loading branch information
CharlieIGG committed Nov 10, 2019
1 parent fbac9fc commit 9ab2c87
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 0 deletions.
45 changes: 45 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Ignore version control files:
.git/
.gitignore

# Ignore github templates:
.github/

# Ignore docker and environment files:
*Dockerfile
docker-compose*.yml
**/*.env
.dockerignore

# Ignore log files:
log/*.log

# Ignore temporary files:
tmp/

# Ignore OS artifacts:
**/.DS_Store

# Ignore database dumps:
db/dumps

# 3: Ignore Development container's Home artifacts:
# 3.1: Ignore bash / IRB / Byebug history files
.*_hist*

# 3.3: bundler stuff
.bundle/*

# 3.4: Codeclimate stuff:
.codeclimate.yml
.csslintrc
.eslintignore
.eslintrc
coffeelint.json
.rubocop.yml
.rubocop-rails.yml
.reek.yml
.scss-lint.yml

# Ignore test coverage reports:
coverage/*
42 changes: 42 additions & 0 deletions bin/checkdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env ruby

# This script is used by this project's Docker development entrypoint script
# to check if the app database (and any of the configured database schemas)
# exists, tripping out if they are missing.
#
# If this script trips out, the entrypoint script will then try to run the
# database setup. This is part of the magic that allows us the "clone & run"
# configuration.
require 'rubygems'
require 'rake'
require 'bundler'

Bundler.setup(:default)

require 'active_record'
require 'erb'
require 'yaml'

def connection_to_database?
connection = ActiveRecord::Base.establish_connection
curr_ver = ActiveRecord::Migrator.current_version
connection && \
ActiveRecord::Migrator.current_version
end

begin
connection_tries ||= 3
exit 1 unless connection_to_database?
exit 0
rescue PG::ConnectionBad
unless (connection_tries -= 1).zero?
puts "Retrying DB connection #{connection_tries} more times..."
sleep ENV.fetch("APP_SETUP_WAIT", "5").to_i
retry
end
exit 2
rescue ActiveRecord::NoDatabaseError
exit 3
ensure
ActiveRecord::Base.clear_all_connections!
end
62 changes: 62 additions & 0 deletions bin/dev-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#! /bin/sh

# The Docker App Container's development entrypoint.
# This is a script used by the project's Docker development environment to
# setup the app containers and databases upon runnning.
set -e

: ${APP_PATH:="/usr/src"}
: ${APP_TEMP_PATH:="$APP_PATH/tmp"}
: ${APP_SETUP_LOCK:="$APP_TEMP_PATH/setup.lock"}
: ${APP_SETUP_WAIT:="5"}

# 1: Define the functions lock and unlock our app containers setup processes:
lock_setup() { mkdir -p $APP_TEMP_PATH && touch $APP_SETUP_LOCK; }
unlock_setup() { rm -rf $APP_SETUP_LOCK; }
wait_setup() { echo "Waiting for app setup to finish..."; sleep $APP_SETUP_WAIT; }

# 2: 'Unlock' the setup process if the script exits prematurely:
trap unlock_setup HUP INT QUIT KILL TERM EXIT

# 3: Specify a default command, in case it wasn't issued:
if [ -z "$1" ]; then set -- rails server -p 3000 -b 0.0.0.0 "$@"; fi

if [ "$1" = "rails" ] || [ "$1" = "hutch" ] || [ "$1" = "sidekiq" ] || [ "$1" = "guard" ] || [ "$1" = "rspec" ] || [ "$1" = "webpack-dev-server" ]
then

# 4: Wait until the setup 'lock' file no longer exists:
while [ -f $APP_SETUP_LOCK ]; do wait_setup; done

# 5: 'Lock' the setup process, to prevent a race condition when the project's
# app containers will try to install gems and setup the database concurrently:
lock_setup

# 6: Check if the gem dependencies are met, or install
bundle check || bundle install

# 7: Check yarn dependencies, or install:
check-dependencies || yarn install

# 8: Check if the database exists, or setup the database if it doesn't, as it is
# the case when the project runs for the first time.
#
# We'll use a custom script `checkdb` (inside our app's `bin` folder), instead
# of running `rails db:version` to avoid loading the entire rails app for this
# simple check - we'll be skipping this step on the webpack container:
if [ "$1" != "webpack-dev-server" ]; then
dockerize -wait tcp://postgres:5432 -timeout 25s
bundle exec ${APP_PATH}/bin/checkdb || rails db:setup
fi

# 9: 'Unlock' the setup process:
unlock_setup

# 10: If the command to execute is 'rails server', then force it to write the
# pid file into a non-shared container directory. Suddenly killing and
# removing app containers without this would leave a pidfile in the project's
# tmp dir, preventing the app container from starting up on further attempts:
if [ "$2" = "s" ] || [ "$2" = "server" ]; then rm -rf /usr/src/tmp/pids/server.pid; fi
fi

# 11: Execute the given or default command:
exec "$@"
15 changes: 15 additions & 0 deletions bin/restoredb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#! /bin/bash

# For use on the postgres container only.
# Usage:
# bin/restoredb testapp_dev db/dumps/<your-dump-name>
set -e

: ${DB_NAME:=$1}
: ${DB_DUMP_PATH:=$2}

dropdb -U postgres -e --if-exists $1 && \
createdb -U postgres $1 && \
pg_restore -U postgres --dbname=$1 \
--clean --no-owner --no-privileges --verbose --jobs=2 \
$2
Empty file added db/dumps/.keep
Empty file.

0 comments on commit 9ab2c87

Please sign in to comment.