Skip to content

Instantly share code, notes, and snippets.

@joshillian
Created February 6, 2020 15:12
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 joshillian/d601a2eb28045a43f6547846e55bc209 to your computer and use it in GitHub Desktop.
Save joshillian/d601a2eb28045a43f6547846e55bc209 to your computer and use it in GitHub Desktop.
Ruby on Rails Docker development environment - based on blog post by Hint.io's Nate Vick https://hint.io/blog/rails-development-with-docker
version: '3.7'
services:
rails:
build:
context: .
args:
- RUBY_VERSION=2.6
- BUNDLE_JOBS=15
- BUNDLE_RETRY=2
- NODE_VERSION=10
- INSTALL_PG_CLIENT=true
- UID=500
- GID=500
environment:
- DATABASE_USER=postgres
- DATABASE_HOST=postgres
entrypoint: ./entrypoint.sh
volumes:
- .:/app:cached
- gems:/gems
- node_modules:/app/node_modules
- packs:/app/public/packs
- rails_cache:/app/tmp/cache
ports:
- "3000:3000"
user: ruby
tty: true
stdin_open: true
depends_on:
- postgres
postgres:
image: postgres:11
volumes:
- postgres:/var/lib/postgresql/data
volumes:
gems:
postgres:
node_modules:
packs:
rails_cache:
ARG RUBY_VERSION=2.6
FROM ruby:$RUBY_VERSION
ARG DEBIAN_FRONTEND=noninteractive
ARG NODE_VERSION=11
RUN curl -sL https://deb.nodesource.com/setup_$NODE_VERSION.x | bash -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update && apt-get install -y \
build-essential \
nodejs \
yarn \
locales \
git \
netcat \
vim \
sudo
ARG UID
ENV UID $UID
ARG GID
ENV GID $GID
ARG USER=ruby
ENV USER $USER
RUN groupadd -g $GID $USER && \
useradd -u $UID -g $USER -m $USER && \
usermod -p "*" $USER && \
usermod -aG sudo $USER && \
echo "$USER ALL=NOPASSWD: ALL" >> /etc/sudoers.d/50-$USER
ENV LANG C.UTF-8
ENV BUNDLE_PATH /gems
ENV BUNDLE_HOME /gems
ARG BUNDLE_JOBS=20
ENV BUNDLE_JOBS $BUNDLE_JOBS
ARG BUNDLE_RETRY=5
ENV BUNDLE_RETRY $BUNDLE_RETRY
ENV GEM_HOME /gems
ENV GEM_PATH /gems
ENV PATH /gems/bin:$PATH
#-----------------
# Postgres Client:
#-----------------
ARG INSTALL_PG_CLIENT=false
RUN if [ "$INSTALL_PG_CLIENT" = true ]; then \
apt-get install -y postgresql-client \
;fi
RUN mkdir -p "$GEM_HOME" && chown $USER:$USER "$GEM_HOME"
RUN mkdir -p /app && chown $USER:$USER /app
WORKDIR /app
RUN mkdir -p node_modules && chown $USER:$USER node_modules
RUN mkdir -p public/packs && chown $USER:$USER public/packs
RUN mkdir -p tmp/cache && chown $USER:$USER tmp/cache
USER $USER
RUN gem install bundler
#!/usr/bin/env bash
set -e
: ${APP_PATH:="/app"}
: ${APP_TEMP_PATH:="$APP_PATH/tmp"}
: ${APP_SETUP_LOCK:="$APP_TEMP_PATH/setup.lock"}
: ${APP_SETUP_WAIT:="5"}
# 1: Define the functions to lock and unlock our app container's setup
# processes:
function lock_setup { mkdir -p $APP_TEMP_PATH && touch $APP_SETUP_LOCK; }
function unlock_setup { rm -rf $APP_SETUP_LOCK; }
function 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: Wait for postgres to come up
echo "DB is not ready, sleeping..."
until nc -vz postgres 5432 &>/dev/null; do
sleep 1
done
echo "DB is ready, starting Rails."
# 4: 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
# 5: Run the checks only if the app code is executed:
if [[ "$1" = "rails" ]]
then
# Clean up any orphaned lock file
unlock_setup
# 6: Wait until the setup 'lock' file no longer exists:
while [ -f $APP_SETUP_LOCK ]; do wait_setup; done
# 7: 'Lock' the setup process, to prevent a race condition when the
# project's app containers will try to install gems and set up the
# database concurrently:
lock_setup
# 8: Check if dependencies need to be installed and install them
bundle install
yarn install
# 9: Run migrations or set up the database if it doesn't exist
# Rails >= 6
bundle exec rails db:prepare
# Rails < 6
# bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup
# 10: 'Unlock' the setup process:
unlock_setup
# 11: If the command to execute is 'rails server', then we must remove any
# pid file present. Suddenly killing and removing app containers might leave
# this file, and prevent rails from starting-up if present:
if [[ "$2" = "s" || "$2" = "server" ]]; then rm -rf /app/tmp/pids/server.pid; fi
fi
# 12: Replace the shell with the given command:
exec "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment