Last active
April 1, 2025 06:06
-
-
Save kofiasare-dev/0708f9e39bfd5aac32e809a9eea5d3d2 to your computer and use it in GitHub Desktop.
Create docker compose rails app
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 | |
create_dir() { | |
local target="$1" | |
if [ -d "$target" ]; then | |
echo "β Directory '$target' already exists. Skipping." | |
else | |
mkdir -p "$target" | |
echo "β Created directory: $target" | |
fi | |
} | |
create_file() { | |
local target="$1" | |
local content="$2" | |
if [ -f "$target" ]; then | |
echo "β File '$target' already exists. Skipping." | |
else | |
echo "$content" >"$target" | |
echo "β Created file: $target" | |
fi | |
} | |
write_file() { | |
local filename="$1" | |
local content="$2" | |
echo "$content" >"$filename" | |
} | |
create_rails_api() { | |
local app="$1" | |
RUBY_VERSION=3.2.2 | |
RAILS_VERSION='7.1.0.rc1' | |
DB_DOCKERFILE=db/Dockerfile | |
DB_DOCKERFILE_CONTENT="FROM postgres:15.1-alpine" | |
CREATE_DB_SQL=db/initdb.d/01_create_db.sql | |
CREATE_DB_SQL_CONTENT=$( | |
cat <<EOL | |
CREATE DATABASE $app; | |
CREATE DATABASE ${app}_testd; | |
EOL | |
) | |
DOCKER_COMPOSE_FILE=docker-compose.yml | |
DOCKER_COMPOSE_FILE_CONTENT=$( | |
cat <<EOL | |
version: "3" | |
x-rails: &rails-config | |
build: . | |
volumes: | |
- ./:/app | |
- api_gem_path:/bundle | |
environment: | |
- RUBY_YJIT_ENABLE=1 | |
- BUNDLE_GEMFILE=/app/Gemfile | |
- BUNDLE_PATH=/bundle/vendor | |
- RAILS_ENV=\$RAILS_ENV | |
- DB_HOST=\$DB_HOST | |
- DB_PASSWORD=\$DB_PASSWORD | |
- HOST_PORT=\$HOST_PORT | |
- CONTAINER_PORT=\$CONTAINER_PORT | |
services: | |
db: | |
build: | |
context: db | |
environment: | |
- POSTGRES_PASSWORD=\$DB_PASSWORD | |
volumes: | |
- ./db/initdb.d:/docker-entrypoint-initdb.d | |
- db_data:/var/lib/postgresql/data | |
ports: | |
- 5432:5432 | |
api: | |
<<: *rails-config | |
tty: true | |
stdin_open: true | |
ports: | |
- \$HOST_PORT:\$CONTAINER_PORT | |
command: | | |
sh -c "rm -f /app/tmp/pids/server.pid && | |
bin/rails db:migrate | |
bin/rails db:seed | |
bin/rails s -b 0.0.0.0 -p \$CONTAINER_PORT" | |
depends_on: | |
- db | |
volumes: | |
db_data: | |
api_gem_path: | |
external: true | |
EOL | |
) | |
DOCKERFILE=Dockerfile | |
DOCKERFILE_CONTENT=$( | |
cat <<EOL | |
FROM ruby:${RUBY_VERSION} | |
RUN apt-get update -qq && apt-get install -y postgresql-client vim | |
WORKDIR /app | |
ADD Gemfile /app/Gemfile | |
EOL | |
) | |
DOCKER_IGNORE_FILE=.dockerignore | |
DOCKER_IGNORE_FILE_CONTENT=$( | |
cat <<EOL | |
crapi.sh | |
.env | |
.git | |
EOL | |
) | |
GEMFILE=Gemfile | |
GEMFILE_CONTENT=$( | |
cat <<EOL | |
# frozen_string_literal: true | |
source 'https://rubygems.org' | |
git_source(:github) { |repo| "https://github.com/#{repo}.git" } | |
ruby '~> ${RUBY_VERSION}' | |
gem 'rails', '${RAILS_VERSION}' | |
EOL | |
) | |
MAKEFILE=Makefile | |
MAKEFILE_CONTENT=$( | |
cat <<EOL | |
.PHONY: build install up debug down shell test | |
build: | |
@docker compose build | |
install: | |
@docker compose run --rm --no-deps --entrypoint bundle api install --jobs=3 --retry=5 | |
up: | |
@docker compose up -d | |
debug: | |
@docker compose up -d | |
@docker attach \$\$(docker compose ps -q api) | |
down: | |
@docker compose down | |
start: | |
@docker compose start | |
stop: | |
@docker compose stop | |
sh: | |
@docker compose exec api bash | |
EOL | |
) | |
DOTENV_FILE=.env | |
DOTENV_FILE_CONTENT=$( | |
cat <<EOL | |
RAILS_ENV=development | |
DB_HOST=db | |
DB_PASSWORD=postgres | |
HOST_PORT=4000 | |
CONTAINER_PORT=3000 | |
EOL | |
) | |
RUBOCOP_FILE=.rubocop.yml | |
RUBOCOP_FILE_CONTENT=$( | |
cat <<EOL | |
--- | |
require: | |
- rubocop-performance | |
- rubocop-rails | |
Style/FrozenStringLiteralComment: | |
SafeAutoCorrect: true | |
Style/ClassAndModuleChildren: | |
SafeAutoCorrect: true | |
EOL | |
) | |
create_dir "$app" && cd "$app" | |
create_dir "db/initdb.d" | |
create_file "$DB_DOCKERFILE" "$DB_DOCKERFILE_CONTENT" | |
create_file "$CREATE_DB_SQL" "$CREATE_DB_SQL_CONTENT" | |
create_file "$DOCKER_COMPOSE_FILE" "$DOCKER_COMPOSE_FILE_CONTENT" | |
create_file "$DOCKERFILE" "$DOCKERFILE_CONTENT" | |
create_file "$DOCKER_IGNORE_FILE" "$DOCKER_IGNORE_FILE_CONTENT" | |
create_file "$GEMFILE" "$GEMFILE_CONTENT" | |
create_file "$MAKEFILE" "$MAKEFILE_CONTENT" | |
create_file "$DOTENV_FILE" "$DOTENV_FILE_CONTENT" | |
create_file "$RUBOCOP_FILE" "$RUBOCOP_FILE_CONTENT" | |
echo "π Files and directories created successfully!" | |
echo "π₯ Building docker containers for rails app $app..." | |
make build | |
echo "β³ Preparing to generate your rails app $app..." | |
make install | |
echo "π Generating your rails app $app..." | |
docker compose run --rm --no-deps --entrypoint bundle api exec rails new "$app" . -JTABf -d=postgresql --api --skip-docker --skip-active-storage | |
rsync -a "$app"/ . && rm -rf "$app" | |
DB_CONFIG=config/database.yml | |
DB_CONFIG_CONTENT=$( | |
cat <<EOL | |
default: &default | |
adapter: postgresql | |
encoding: unicode | |
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> | |
host: <%= ENV.fetch("DB_HOST") { "localhost" } %> | |
username: postgres | |
password: <%= ENV['DB_PASSWORD'] %> | |
development: | |
<<: *default | |
database: ${app} | |
# Warning: The database defined as "test" will be erased and | |
# re-generated from your development database when you run "rake". | |
# Do not set this db to the same as development or production. | |
test: | |
<<: *default | |
database: ${app}_testd | |
production: | |
<<: *default | |
database: ${app}_prod | |
EOL | |
) | |
write_file "$DB_CONFIG" "$DB_CONFIG_CONTENT" | |
GEMFILE=Gemfile | |
GEMFILE_CONTENT=$( | |
cat <<EOL | |
# frozen_string_literal: true | |
source 'https://rubygems.org' | |
git_source(:github) { |repo| "https://github.com/#{repo}.git" } | |
ruby '~> ${RUBY_VERSION}' | |
gem 'rails', '${RAILS_VERSION}' | |
gem 'bootsnap', require: false | |
gem 'pg', '~> 1.1' | |
gem 'puma', '6.0' | |
gem 'rack-cors' | |
gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby] | |
group :github do | |
gem 'plutonium_generators', git: 'https://github.com/plutonium-rails/plutonium-generators' | |
end | |
group :development do | |
gem 'awesome_print' | |
gem 'rubocop', require: false | |
gem 'rubocop-performance', require: false | |
gem 'rubocop-rails', require: false | |
gem 'prosopite' | |
end | |
group :development, :test do | |
gem 'pry-byebug' | |
gem 'pry-rails' | |
gem 'spring' | |
end | |
EOL | |
) | |
write_file "$GEMFILE" "$GEMFILE_CONTENT" | |
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" | |
echo "| Post-installation instructions completed.|" | |
echo "| |" | |
echo "| cd $app && crapi -i |" | |
echo "| |" | |
echo "| springify your app |" | |
echo "| crapi -sh |" | |
echo "| bundle exec spring binstub --all |" | |
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" | |
echo 'π₯π₯ Done !!!' | |
} | |
help() { | |
echo "Usage: crapi [APP_NAME] | [options]" | |
echo "Options (must be called in a valid 'crapi' directory):" | |
echo " -b build/rebuild the app" | |
echo " -i Install dependencies in Gemfile" | |
echo " -u Start/Up the app" | |
echo " -dbg Start the app in debug mode" | |
echo " -s Stop the app" | |
echo " -u Start/Up the app" | |
echo " -u Start/Up the app" | |
} | |
# Check if there are no arguments | |
if [ $# -eq 0 ]; then | |
help | |
exit 1 | |
fi | |
# Variable for the app name | |
APP_NAME="$1" | |
# Check if the first argument is a valid option | |
if [ "${APP_NAME:0:1}" = "-" ]; then | |
if [ -f Makefile ] && [ -f docker-compose.yml ]; then | |
case "$APP_NAME" in | |
-b) | |
make build | |
;; | |
-i) | |
echo "Installing dependencies for app..." | |
make install | |
;; | |
-u) | |
echo "Starting app..." | |
make up | |
;; | |
-dbg) | |
echo "Starting app in debug mode..." | |
make debug | |
;; | |
-s) | |
make stop | |
;; | |
-d) | |
echo "Stopping the app and removing all containers..." | |
make down | |
;; | |
-sh) | |
make sh | |
;; | |
*) | |
echo "Invalid option: $APP_NAME" | |
help | |
exit 1 | |
;; | |
esac | |
else | |
help | |
exit 1 | |
fi | |
else | |
echo "Creating the app '$APP_NAME'..." | |
create_rails_api "$APP_NAME" | |
fi |
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
gist_url="https://gist.github.com/kofiasare-dev/0708f9e39bfd5aac32e809a9eea5d3d2" | |
wget $gist_url/raw -O crapi | |
chmod +x crapi | |
mkdir -p ~/bin | |
mv crapi ~/bin/ | |
add to your .bashrc or .zshrc | |
export PATH="$PATH:$HOME/bin" | |
source ~/.bashrc or ~/.zshrc |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment