# Terminal
rails new testapp --javascript esbuild --css bootstrap -m main.rb
# generate alias in .zshrc
alias generate='f(){ rails new "$@" -m ~/Rails/generator/main.rb; unset -f f; }; f'
# .railsrc
--skip-spring
--javascript esbuild
--css bootstrap
# main.rb
def source_paths
[__dir__]
end
def ask_with_default(prompt, default)
value = ask("#{prompt} [#{default}]")
value.blank? ? default : value
end
def app_name_dasherized
app_name.gsub('_', '-')
end
def registry
@registry ||= ask_with_default("What is your registry username?", "kobaltz")
end
def domain
@domain ||= ask_with_default("What is the domain name of your server?", "railsapp.dev")
end
registry
domain
rails_command "db:system:change --to=postgresql"
remove_file "config/database.yml"
template "config/database.yml.erb", "config/database.yml"
generate(:controller, 'welcome', 'index')
route "root to: 'welcome#index'"
template './docker_files/.dockerignore.erb', '.dockerignore'
template './docker_files/docker-compose.yml.erb', 'docker-compose.yml'
template './docker_files/Dockerfile.dev.erb', 'Dockerfile.dev'
template './docker_files/docker-compose-prod.yml.erb', 'docker-compose-prod.yml'
template './docker_files/Dockerfile.prod.erb', 'Dockerfile.prod'
template './bin/deploy.erb', 'bin/deploy'
template './bin/entrypoint.sh.erb', 'bin/entrypoint.sh'
after_bundle do
run 'bundle lock --add-platform aarch64-linux'
run 'bundle lock --add-platform x86_64-darwin-19'
run 'bundle lock --add-platform x86_64-linux'
remove_file 'bin/dev'
template './bin/dev.erb', 'bin/dev'
run 'chmod +x ./bin/dev'
run 'chmod +x ./bin/deploy'
run 'chmod +x ./bin/entrypoint.sh'
remove_file 'Procfile.dev'
run 'docker compose run app bundle install'
run 'docker compose run app yarn install'
run 'docker compose run app bin/rails bin/rails db:create db:migrate db:seed'
run 'docker compose down'
git :init
git add: '.'
git commit: %( -m 'base' )
end
# bin/deploy.erb
#!/bin/bash
docker login
docker buildx create \
--name amd64_builder \
--node linux_amd64_builder \
--platform linux/amd64 \
ssh://kobaltz@192.168.1.89
docker buildx build \
--file Dockerfile.prod \
--builder amd64_builder \
--platform linux/amd64 \
--tag <%= registry %>/<%= app_name.underscore %>_app:latest \
--push .
# bin/dev.erb
#!/usr/bin/env bash
docker compose up
# bin/entrypoint.sh.erb
#!/bin/bash
set -e
if [ -f /app/tmp/pids/server.pid ]; then
rm /app/tmp/pids/server.pid
fi
bin/rails db:migrate 2>/dev/null || DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bin/rails db:setup
exec bundle exec "$@"
# config/database.yml.erb
default: &default
adapter: postgresql
encoding: unicode
pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
url: <%%= ENV.fetch("DATABASE_URL") { 'localhost' } %>
development:
<<: *default
database: <%= app_name_dasherized %>_development
test:
<<: *default
database: <%= app_name_dasherized %>_test
production:
<<: *default
database: <%= app_name_dasherized %>_production
# docker_files/.dockerignore.erb
.git*
log/*
tmp/*
tmp/pid/server.pid
Dockerfile
README.rdoc
# docker_files/docker-compose.yml.erb
version: '3.8'
x-base: &base
build:
context: .
dockerfile: ./Dockerfile.dev
args:
RUBY_VERSION: '3.1.2'
stdin_open: true
tty: true
volumes:
- .:/app:cached
environment:
- DATABASE_URL=postgres://postgres:postgres@postgres:5432
depends_on:
- redis
- postgres
services:
app:
<<: *base
command: bin/rails server -p 3000 -b 0.0.0.0
ports:
- '3000:3000'
css:
<<: *base
command: yarn build:css --watch
js:
<<: *base
command: yarn build --watch
# sidekiq:
# <<: *base
# command: bundle exec sidekiq -C config/sidekiq.yml
redis:
image: redis:latest
restart: always
postgres:
image: postgres:14-alpine
volumes:
- postgres:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=postgres
ports:
- 5432
volumes:
postgres:
# docker_files/docker-compose-prod.yml.erb
version: '3.8'
networks:
traefik-public:
external: true
<%= app_name.underscore %>_network:
volumes:
postgres:
storage:
services:
app:
image: <%= registry %>/<%= app_name.underscore %>_app:latest
restart: always
command: bin/rails server -p 3000 -b 0.0.0.0
environment:
RAILS_SERVE_STATIC_FILES: "enabled"
RAILS_LOG_TO_STDOUT: "enabled"
DATABASE_URL: postgres://postgres:postgres@postgres:5432
volumes:
- storage:/app/storage
ports:
- 3000
depends_on:
- postgres
- redis
networks:
- traefik-public
- <%= app_name.underscore %>_network
deploy:
replicas: 2
labels:
- traefik.enable=true
- traefik.http.services.<%= app_name.underscore %>.loadbalancer.server.port=3000
- traefik.http.routers.<%= app_name.underscore %>.rule=Host(`<%= app_name.underscore %>.<%= domain %>`)
- traefik.http.routers.<%= app_name.underscore %>.entrypoints=web
- traefik.constraint-label=traefik-public
- traefik.docker.network=traefik-public
redis:
image: redis:latest
restart: always
networks:
- <%= app_name.underscore %>_network
postgres:
image: postgres:14-alpine
volumes:
- postgres:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=postgres
ports:
- 5432
networks:
- <%= app_name.underscore %>_network
# docker_files/Dockerfile.dev.erb
ARG RUBY_VERSION
FROM ruby:$RUBY_VERSION
RUN apt update -qq && apt upgrade -y
RUN apt-get install -y build-essential
RUN apt install -y postgresql-client
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt update -qq
RUN apt install -y nodejs yarn
RUN gem update --system
RUN gem install bundle
WORKDIR /app
RUN echo 'gem: --no-rdoc --no-ri >> "$HOME/.gemrc"'
COPY Gemfile Gemfile.lock ./
COPY package.json yarn.lock ./
RUN bundle install -j $(nproc)
RUN yarn install
# docker_files/Dockerfile.prod.erb
FROM ruby:3.1.2
ENV RAILS_ENV production
RUN apt update -qq && apt upgrade -y
RUN apt-get install -y build-essential
RUN apt install -y postgresql-client
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt update -qq
RUN apt install -y nodejs yarn
RUN gem update --system
RUN gem install bundle
WORKDIR /app
RUN echo 'gem: --no-rdoc --no-ri >> "$HOME/.gemrc"'
COPY Gemfile Gemfile.lock ./
COPY package.json yarn.lock ./
RUN bundle config set --local without 'development test'
RUN bundle install -j $(nproc)
RUN yarn install
COPY . /app
RUN RAILS_GROUPS=assets bin/rails assets:precompile
ENTRYPOINT [ "/app/bin/entrypoint.sh" ]
CMD ["bin/rails", "server", "-b", "0.0.0.0", "-p", "3000"]
EXPOSE 3000