Last active
May 20, 2022 11:01
-
-
Save natevick/96c22b18b6cb31fa458fafba32fa000f to your computer and use it in GitHub Desktop.
Base Rails Docker Development Environment
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
default: &default | |
adapter: postgresql | |
encoding: unicode | |
pool: <%= ENV.fetch("RAILS_MAX_THREADS", 5) %> | |
username: <%= ENV.fetch("DATABASE_USER", 'postgres') %> | |
host: <%= ENV.fetch("DATABASE_HOST", 'localhost') %> | |
port: 5432 | |
development: | |
<<: *default | |
database: docker_development | |
test: | |
<<: *default | |
database: docker_test | |
production: | |
<<: *default | |
database: docker_production | |
username: docker | |
password: <%= ENV['DOCKER_DATABASE_PASSWORD'] %> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
version: '3.7' | |
services: | |
rails: | |
build: | |
context: ./docker/ruby | |
args: | |
- RUBY_VERSION=2.6.5 | |
- BUNDLE_JOBS=15 | |
- BUNDLE_RETRY=2 | |
- NODE_VERSION=12 | |
- INSTALL_PG_CLIENT=true | |
- UID=500 | |
- GID=500 | |
environment: | |
- DATABASE_USER=postgres | |
- DATABASE_HOST=postgres | |
command: bundle exec rails server -p 3000 -b '0.0.0.0' | |
entrypoint: docker/ruby/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 | |
environment: | |
- POSTGRES_HOST_AUTH_METHOD=trust | |
volumes: | |
- postgres:/var/lib/postgresql/data | |
volumes: | |
gems: | |
postgres: | |
node_modules: | |
packs: | |
rails_cache: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/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 -- bundle exec rails server -p 3000 -b 0.0.0.0 "$@"; fi | |
# 5: Run the checks only if the app code is executed: | |
if [[ "$3" = "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 [[ "$4" = "s" || "$4" = "server" ]]; then rm -rf /app/tmp/pids/server.pid; fi | |
fi | |
# 12: Replace the shell with the given command: | |
exec "$@" |
@bovender Thanks for the kind words! I have gone back and forth on that section of the entrypoint with my team over the years. I honestly believe we landed there because if a setup.lock file did not get cleaned up for some reason when the entrypoint was run again it would stall the starting of the app. Feel free to experiment with it to see what works best in your situation.
Thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great Gist, even two years on ;-) I also love the blog on hint.io. But allow me one question: In entrypoint.sh, you call
unlock_setup
followed bywhile [ -f $APP_SETUP_LOCK ]; do wait_setup; done
-- but if I am not mistaken, the call tounlock_setup
will basically render the locking mechanism ineffective? It seems to me that this function call is erroneous, or am I missing something?