diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..7722938c
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,7 @@
+[[sh]]
+indent_style = space
+indent_size = 2
+
+[[bash]]
+indent_style = space
+indent_size = 2
diff --git a/.env.example b/.env.example
index 155e6a10..a0ec5d8a 100644
--- a/.env.example
+++ b/.env.example
@@ -5,9 +5,27 @@
# uncommented option that means it's either mandatory to set or it's being
# overwritten in development to make your life easier.
+# Enable BuildKit by default:
+# https://docs.docker.com/develop/develop-images/build_enhancements
+export DOCKER_BUILDKIT=1
+
# Rather than use the directory name, let's control the name of the project.
export COMPOSE_PROJECT_NAME=hellorails
+# In development we want all services to start but in production you don't
+# need the asset watchers to run since assets get built into the image.
+#
+# You can even choose not to run postgres and redis in prod if you plan to use
+# managed cloud services. Everything "just works", even optional depends_on!
+#export COMPOSE_PROFILES=postgres,redis,web,worker,cable
+export COMPOSE_PROFILES=postgres,redis,assets,web,worker,cable
+
+# If you're running native Linux and your uid:gid isn't 1000:1000 you can set
+# these to match your values before you build your image. You can check what
+# your uid:gid is by running `id` from your terminal.
+#export UID=1000
+#export GID=1000
+
# You can generate a more secure secret by running: ./run rails secret
export SECRET_KEY_BASE=insecure_key_for_dev
@@ -20,7 +38,7 @@ export NODE_ENV=development
# The bind port for puma.
#
# Be warned that if you change this value you'll need to change 8000 in both
-# your Dockerfile and in a few spots in docker-compose.yml due to the nature of
+# your Dockerfile and in a few spots in compose.yaml due to the nature of
# how this value can be set (Docker Compose doesn't support nested ENV vars).
#export PORT=8000
@@ -28,7 +46,7 @@ export NODE_ENV=development
# to the server's CPU count * 2. That is a good starting point. In development
# it's a good idea to use 1 to avoid race conditions when debugging.
#export WEB_CONCURRENCY=
-#export RAILS_MAX_THREADS=5
+#export RAILS_MAX_THREADS=3
export WEB_CONCURRENCY=1
export RAILS_MAX_THREADS=1
@@ -36,9 +54,9 @@ export RAILS_MAX_THREADS=1
# postgres Docker image uses them for its default database user and password.
export POSTGRES_USER=hello
export POSTGRES_PASSWORD=password
+#export POSTGRES_DB=hello
#export POSTGRES_HOST=postgres
#export POSTGRES_PORT=5432
-#export POSTGRES_DB=hello
# What's your full Redis connection URL? This will be used for caching, Sidekiq,
# and Action Cable. You can always split them up later.
@@ -47,7 +65,7 @@ export POSTGRES_PASSWORD=password
# The bind port for puma but for Action Cable.
#
# Be warned that if you change this value you'll need to change 28080 in a few
-# spots in docker-compose.yml due to the nature of how this value can be set
+# spots in compose.yaml due to the nature of how this value can be set
# (Docker Compose doesn't support nested ENV vars).
#export CABLE_PORT=28080
@@ -67,6 +85,10 @@ export POSTGRES_PASSWORD=password
# http:\/\/example.*,https:\/\/example.*
#export ACTION_CABLE_ALLOWED_REQUEST_ORIGINS=http:\/\/localhost*
+# Various functionality in Rails requires setting a host URL, in production
+# this should match your domain name, such as example.com.
+#export URL_HOST=localhost:8000
+
# If this is set then Rails will serve files from public/ in production. You
# probably don't want this behavior unless you're testing prod mode locally,
# because nginx would typically serve static files.
@@ -83,15 +105,15 @@ export DOCKER_RESTART_POLICY=no
export DOCKER_WEB_HEALTHCHECK_TEST=/bin/true
# What ip:port should be published back to the Docker host for the app server?
-# If you're using Docker Toolbox or a custom VM you can't use 127.0.0.1. This
-# is being overwritten in dev to be compatible with more dev environments.
#
# If you have a port conflict because something else is using 8000 then you
# can either stop that process or change 8000 to be something else.
#
-# Use the default in production to avoid having gunicorn directly accessible to
+# Use the default in production to avoid having puma directly accessible on
# the internet since it'll very likely be behind nginx or a load balancer.
-#export DOCKER_WEB_PORT_FORWARD=127.0.0.1:8000
+#
+# This is being overwritten in dev to be compatible with more dev environments,
+# such as accessing your site on another local device (phone, tablet, etc.).
export DOCKER_WEB_PORT_FORWARD=8000
# This is the same as above except for Action Cable.
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..77250508
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+github: "nickjj"
+custom: ["https://www.paypal.me/nickjanetakis"]
diff --git a/.github/docs/screenshot.jpg b/.github/docs/screenshot.jpg
index f3120de8..64a8aa68 100644
Binary files a/.github/docs/screenshot.jpg and b/.github/docs/screenshot.jpg differ
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ee33e331..9f07b543 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -8,13 +8,15 @@ on:
branches:
- "main"
- "master"
+ schedule:
+ - cron: "30 12 * * *"
jobs:
test:
- runs-on: "ubuntu-20.04"
+ runs-on: "ubuntu-22.04"
steps:
- - uses: "actions/checkout@v2"
+ - uses: "actions/checkout@v4"
- name: "Install CI dependencies"
run: |
@@ -24,8 +26,6 @@ jobs:
run: |
# Remove volumes in CI to avoid permission errors due to UID / GID.
sed -i "s|.:/app|/tmp:/tmp|g" .env*
- sed -i "s|.:/app|/tmp:/tmp|g" docker-compose.override.yml.example
+ sed -i "s|.:/app|/tmp:/tmp|g" compose.yaml
./run ci:test
- env:
- DOCKER_BUILDKIT: "1"
diff --git a/.gitignore b/.gitignore
index 4781fe47..17075561 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,8 +12,8 @@ tmp/*
storage/*
!storage/.keep
-# Ignore master key for decrypting credentials.
-config/master.key
+# Ignore key files for decrypting credentials and more.
+config/*.key
# Ignore front-end related files.
app/assets/builds/*
diff --git a/.hadolint.yaml b/.hadolint.yaml
new file mode 100644
index 00000000..5413efd7
--- /dev/null
+++ b/.hadolint.yaml
@@ -0,0 +1,4 @@
+---
+failure-threshold: "style"
+ignored:
+ - "DL3008"
diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 00000000..cacd44f9
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,9 @@
+# Omakase Ruby styling for Rails.
+inherit_gem:
+ rubocop-rails-omakase: "rubocop.yml"
+
+# Overwrite or add rules to create your own house style.
+#
+# # Use `[a, [b, c]]` not `[ a, [ b, c ] ]`
+# Layout/SpaceInsideArrayLiteralBrackets:
+# Enabled: false
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 17c7dc1a..365faba6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,17 +7,248 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]
+### Added
+
+- `URL_HOST` environment variable for setting `default_url_options[:host]`
+- `./run bundle [...]` to run any Bundler command
+- `./run yarn [...]` to run any Yarn command
+- `libyaml-dev` as a system library so the psych gem can be installed
+- `./run lint:shell` for linting shell scripts with ShellCheck
+- `./run format:shell` for formatting shell scripts with shfmt
+- `./run quality` to run all linting and formatting commands
+
+#### Back-end dependencies
+
+- Add `hotwire-spark` for live reloading in development
+
+### Changed
+
+- Reference `CABLE_PORT` in `compose.yaml`
+- Set `config.active_job.queue_adapter = :test` in `config/environments/test.rb`
+- Replace Sprockets with Propshaft
+- Replace `./run bundle:install` with `./run deps:install [--no-build]` to install any deps
+- Replace `./run yarn:install` with `./run deps:install [--no-build]` to install any deps
+- Allow overriding `$TTY` as an environment variable in the `run` script
+- Use `.hadolint.yaml` to configure Hadolint instead of inline flags
+- Remove `build-essential` from the `Dockerfile`'s app stage to reduce image size by ~50% / 250MB
+- Rename run script's `rubocop` command to `format`
+- Use `message_pack` as a serializer
+
+#### Languages and services
+
+- Update `Ruby` to `3.4.7`
+- Update `Node` to `22.X`
+- Update `Postgres` to `18.0`
+- Update `Redis` to `8.2.2`
+
+#### Back-end dependencies
+
+- Update `cssbundling-rails` to `1.4.3`
+- Update `hotwire-spark` to `0.1.13`
+- Update `minitest` to `5.25.4`
+- Update `pp` to `0.6.3`
+- Update `propshaft` to `1.3.1`
+- Update `puma` to `7.1.0`
+- Update `rack-mini-profiler` to `4.0.1`
+- Update `rack` to `3.2.2`
+- Update `rails` to `8.1.0`
+- Update `redis` to `5.4.1`
+- Update `rubocop-rails` to `2.33.4`
+- Update `rubocop` to `1.81.1`
+- Update `selenium-webdriver` to `4.36.0`
+- Update `sidekiq` to `8.0.8`
+- Update `stimulus-rails` to `1.3.4`
+- Update `turbo-rails` to `2.0.17`
+
+#### Front-end dependencies
+
+- Update `@hotwired/turbo-rails` to `8.0.18`
+- Update `@tailwindcss/cli` to `4.1.15`
+- Update `@tailwindcss/postcss` to `4.1.15`
+- Update `esbuild` to `0.25.11`
+- Update `tailwindcss` to `4.1.15`
+
+### Removed
+
+- `config.log_formatter` from the production config
+
+## [0.9.0] - 2024-08-09
+
### Changed
+- Add `config/initializers/enable_yjit.rb` which enables YJIT by default (delete this file to disable it)
+- Add `required: false` to `depends_on` in `docker-compose.yml` (requires Docker Compose v2.20.2+)
+- Update Node and Yarn install strategy to remove install script deprecation warning
+- A whole bunch of changes related to Rails 7.1.0, take a look at [this commit](https://github.com/nickjj/docker-rails-example/commit/94e9190e2e3db2cd350cd217db3b270b7c77fb72)
+- Update `rename-project` script to auto-delete temporary files
+- Rename `docker-compose.yml` to `compose.yaml` to stick to the official Docker Compose spec
+
+#### Languages and services
+
+- Update `Ruby` to `3.3.3`
+- Update `Node` to `20.X`
+- Update `Postgres` to `16.3`
+- Update `Redis` to `7.2.5`
+
+#### Back-end dependencies
+
+- Update `cssbundling-rails` to `1.4.1`
+- Update `jsbundling-rails` to `1.3.1`
+- Update `minitest` to `5.24.1`
+- Update `pg` to `1.5.7`
+- Update `puma` to `6.4.2`
+- Update `rack-mini-profiler` to `3.3.0`
+- Update `rack-mini-profiler` to `3.3.1`
+- Update `rack` to `3.1.7`
+- Update `rails` to `7.1.3.4`
+- Update `redis` to `5.2.0`
+- Update `sidekiq` to `7.3.0`
+- Update `stimulus-rails` to `1.3.3`
+- Update `turbo-rails` to `2.0.6`
+
+#### Front-end dependencies
+
+- Update `@hotwired/stimulus` to `3.2.2`
+- Update `@hotwired/turbo-rails` to `8.0.5`
+- Update `autoprefixer` to `10.4.20`
+- Update `esbuild` to `0.23.0`
+- Update `postcss-import` to `16.1.0`
+- Update `postcss` to `8.4.41`
+- Update `tailwindcss` to `3.4.8`
+
+## [0.8.0] - 2023-05-13
+
+### Added
+
+- Ability to customize `UID` and `GID` if you're not using `1000:1000` (check the `.env.example` file)
+- Output `docker compose logs` in CI for easier debugging
+
+### Changed
+
+- Replace `Redis.current` (removed in `redis` 5.0+) with `RedisConn.current` which is in `config/initializers/redis.rb`
+- Rename `run bash` to `run shell`
+- Reference `PORT` variable in the `docker-compose.yml` web service instead of hard coding `8000`
+- Adjust Hadolint to exit > 0 if any style warnings are present
+
+#### Languages and services
+
+- Update `Ruby` to `3.2.2`
+- Update `Node` to `18.X`
+- Update `Postgres` to `15.3`
+- Update `Redis` to `7.0.11`
+
+#### Back-end dependencies
+
+- Update `cssbundling-rails` to `1.1.2`
+- Update `jsbundling-rails` to `1.1.1`
+- Update `minitest` to `5.18.0`
+- Update `pg` to `1.5.3`
+- Update `puma` to `6.2.2`
+- Update `rack-mini-profiler` to `3.1.0`
+- Update `rails` to `7.0.4.3`
+- Update `redis` to `5.0.6`
+- Update `sidekiq` to `7.1.0`
+- Update `stimulus-rails` to `1.2.1`
+- Update `turbo-rails` to `1.4.0`
+
+#### Front-end dependencies
+
+- Update `@hotwired/stimulus` to `3.2.1`
+- Update `@hotwired/turbo-rails` to `7.3.0`
+- Update `autoprefixer` to `10.4.14`
+- Update `esbuild` to `0.17.19`
+- Update `postcss-import` to `15.1.0`
+- Update `postcss` to `8.4.23`
+- Update `tailwindcss` to `3.3.2`
+
+### Removed
+
+- `set -o nounset` from `run` script since it's incompatible with Bash 3.2 (default on macOS)
+- `--jobs "$(nproc)"` from the `bundle install` command in the `Dockerfile` since this is the default
+
+### Fixed
+
+- Assets in production mode were using the wrong `.sprockets-manifest-XXX.json` file, `bin/docker-entrypoint-web` was adjusted to delete all but the last built version since Rails doesn't pick the latest file based on `mtime`
+
+## [0.7.0] - 2022-09-08
+
+### Added
+
+- `set -o nounset` to `run` script to exit if there's any undefined variables
+
+### Changed
+
+- Switch Docker Compose `env_file` to `environment` for `postgres` to avoid needless recreates on `.env` changes
+- Replace override file with Docker Compose profiles for running specific services
+- Update Github Actions to use Ubuntu 22.04
+- Enable BuildKit by default in the `.env.example` file
+
+#### Languages and services
+
+- Update `PostgreSQL` to `14.5`
+- Update `Redis` to `7.0.4`
+
+#### Back-end dependencies
+
+- Update `cssbundling-rails` to `1.1.1`
+- Update `jsbundling-rails` to `1.0.3`
+- Update `pg` to `1.4.3`
+- Update `redis` to `4.7.1`
+- Update `sidekiq` to `6.5.4`
+- Update `stimulus-rails` to `1.1.0`
+- Update `turbo-rails` to `1.1.1`
+
+#### Front-end dependencies
+
+- Update `@hotwired/stimulus` to `3.1.0`
+- Update `@hotwired/turbo-rails` to `7.1.3`
+- Update `autoprefixer` to `10.4.8`
+- Update `esbuild` to `0.15.2`
+- Update `postcss` to `8.4.16`
+- Update `tailwindcss` to `3.1.8`
+
+### Removed
+
+- Docker Compose `env_file` property for `redis` to avoid needless recreates on `.env` changes
+- Drop support for Docker Compose v1 (mainly to use profiles in an optimal way, it's worth it!)
+
+## [0.6.0] - 2022-05-15
+
+### Added
+
+- `config/initializers/rack_mini_profiler.rb` to enable profiling Hotwire Turbo Drive
+
+### Changed
+
+- Refactor `/up/` endpoint into its own controller and add `/up/databases` as a second URL
+
+#### Languages and services
+
+- Update `Ruby` to `3.1.2`
+- Update `PostgreSQL` to `14.2`
+- Update `Redis` to `7.0.0`
+
#### Back-end dependencies
-- Update `sidekiq` to `6.4.0`
+- Update `capybara` to `3.37.1`
+- Update `jsbundling-rails` to `1.0.2`
+- Update `pg` to `1.3.5`
+- Update `puma` to `5.6.4`
+- Update `rack-mini-profiler` to `3.0.0`
+- Update `rails` to `7.0.3`
+- Update `redis` to `4.6.0`
+- Update `sidekiq` to `6.4.2`
+- Update `stimulus-rails` to `1.0.4`
- Update `turbo-rails` to `1.0.1`
#### Front-end dependencies
- Update `@hotwired/turbo-rails` to `7.1.1`
-- Update `esbuild` to `0.14.13`
+- Update `autoprefixer` to `10.4.7`
+- Update `esbuild` to `0.14.39`
+- Update `postcss-import` to `14.1.0`
+- Update `postcss` to `8.4.13`
+- Update `tailwindcss` to `3.0.24`
## [0.5.0] - 2021-01-15
@@ -178,7 +409,11 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
- Everything!
-[Unreleased]: https://github.com/nickjj/docker-rails-example/compare/0.5.0...HEAD
+[Unreleased]: https://github.com/nickjj/docker-rails-example/compare/0.9.0...HEAD
+[0.9.0]: https://github.com/nickjj/docker-rails-example/compare/0.8.0...0.9.0
+[0.8.0]: https://github.com/nickjj/docker-rails-example/compare/0.7.0...0.8.0
+[0.7.0]: https://github.com/nickjj/docker-rails-example/compare/0.6.0...0.7.0
+[0.6.0]: https://github.com/nickjj/docker-rails-example/compare/0.5.0...0.6.0
[0.5.0]: https://github.com/nickjj/docker-rails-example/compare/0.4.0...0.5.0
[0.4.0]: https://github.com/nickjj/docker-rails-example/compare/0.3.0...0.4.0
[0.3.0]: https://github.com/nickjj/docker-rails-example/compare/0.2.0...0.3.0
diff --git a/Dockerfile b/Dockerfile
index 9165f47e..8d6369fe 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,23 +1,27 @@
-FROM ruby:3.1.0-slim-bullseye AS assets
+FROM ruby:3.4.7-slim-trixie AS assets
LABEL maintainer="Nick Janetakis "
WORKDIR /app
+ARG UID=1000
+ARG GID=1000
+
RUN bash -c "set -o pipefail && apt-get update \
- && apt-get install -y --no-install-recommends build-essential curl git libpq-dev \
- && curl -sSL https://deb.nodesource.com/setup_16.x | bash - \
- && curl -sSL 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 \
- && apt-get update && apt-get install -y --no-install-recommends nodejs yarn \
+ && apt-get install -y --no-install-recommends build-essential curl git libpq-dev libyaml-dev \
+ && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key -o /etc/apt/keyrings/nodesource.asc \
+ && echo 'deb [signed-by=/etc/apt/keyrings/nodesource.asc] https://deb.nodesource.com/node_22.x nodistro main' | tee /etc/apt/sources.list.d/nodesource.list \
+ && apt-get update && apt-get install -y --no-install-recommends nodejs \
+ && corepack enable \
&& rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man \
&& apt-get clean \
- && useradd --create-home ruby \
+ && groupadd -g \"${GID}\" ruby \
+ && useradd --create-home --no-log-init -u \"${UID}\" -g \"${GID}\" ruby \
&& mkdir /node_modules && chown ruby:ruby -R /node_modules /app"
USER ruby
COPY --chown=ruby:ruby Gemfile* ./
-RUN bundle install --jobs "$(nproc)"
+RUN bundle install
COPY --chown=ruby:ruby package.json *yarn* ./
RUN yarn install
@@ -25,29 +29,33 @@ RUN yarn install
ARG RAILS_ENV="production"
ARG NODE_ENV="production"
ENV RAILS_ENV="${RAILS_ENV}" \
- NODE_ENV="${NODE_ENV}" \
- PATH="${PATH}:/home/ruby/.local/bin:/node_modules/.bin" \
- USER="ruby"
+ NODE_ENV="${NODE_ENV}" \
+ PATH="${PATH}:/home/ruby/.local/bin:/node_modules/.bin" \
+ USER="ruby"
COPY --chown=ruby:ruby . .
RUN if [ "${RAILS_ENV}" != "development" ]; then \
- SECRET_KEY_BASE=dummyvalue rails assets:precompile; fi
+ SECRET_KEY_BASE_DUMMY=1 rails assets:precompile; fi
CMD ["bash"]
###############################################################################
-FROM ruby:3.1.0-slim-bullseye AS app
+FROM ruby:3.4.7-slim-trixie AS app
LABEL maintainer="Nick Janetakis "
WORKDIR /app
+ARG UID=1000
+ARG GID=1000
+
RUN apt-get update \
- && apt-get install -y --no-install-recommends build-essential curl libpq-dev \
+ && apt-get install -y --no-install-recommends curl libpq-dev \
&& rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man \
&& apt-get clean \
- && useradd --create-home ruby \
+ && groupadd -g "${GID}" ruby \
+ && useradd --create-home --no-log-init -u "${UID}" -g "${GID}" ruby \
&& chown ruby:ruby -R /app
USER ruby
@@ -57,8 +65,8 @@ RUN chmod 0755 bin/*
ARG RAILS_ENV="production"
ENV RAILS_ENV="${RAILS_ENV}" \
- PATH="${PATH}:/home/ruby/.local/bin" \
- USER="ruby"
+ PATH="${PATH}:/home/ruby/.local/bin" \
+ USER="ruby"
COPY --chown=ruby:ruby --from=assets /usr/local/bundle /usr/local/bundle
COPY --chown=ruby:ruby --from=assets /app/public /public
diff --git a/Gemfile b/Gemfile
index 67ee0b58..bcddb047 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,19 +1,22 @@
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
-ruby "3.1.0"
+ruby "3.4.7"
# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
-gem "rails", "~> 7.0.1"
+gem "rails", "~> 8.1"
-# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails]
-gem "sprockets-rails"
+# Efficient serialization [https://github.com/msgpack/msgpack-ruby]
+gem "msgpack", ">= 1.7.0"
+
+# An improved asset pipeline for Rails [https://github.com/rails/propshaft]
+gem "propshaft", "~> 1.1"
# Use postgresql as the database for Active Record
gem "pg", "~> 1.1"
# Use the Puma web server [https://github.com/puma/puma]
-gem "puma", "~> 5.0"
+gem "puma", "~> 7.1"
# Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails]
gem "jsbundling-rails"
@@ -31,7 +34,7 @@ gem "cssbundling-rails"
gem "jbuilder"
# Use Redis adapter to run Action Cable in production
-gem "redis", "~> 4.0"
+gem "redis", "~> 5.2"
# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis]
# gem "kredis"
@@ -43,14 +46,14 @@ gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]
# gem "image_processing", "~> 1.2"
# Execute jobs in the background [https://github.com/mperham/sidekiq]
-gem "sidekiq", "~> 6.4"
+gem "sidekiq", "~> 8.0"
group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
- gem "debug", platforms: %i[ mri mingw x64_mingw ]
+ gem "debug", platforms: %i[ mri windows ], require: "debug/prelude"
- # Reduces boot times through caching; required in config/boot.rb
- gem "bootsnap", require: false
+ # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
+ gem "rubocop-rails-omakase", require: false
end
group :development do
@@ -60,13 +63,12 @@ group :development do
# Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler]
gem "rack-mini-profiler"
- # Speed up commands on slow machines / big apps [https://github.com/rails/spring]
- # gem "spring"
+ # Live reloading for Hotwire applications [https://github.com/hotwired/spark]
+ gem "hotwire-spark", "~> 0.1"
end
group :test do
# Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
gem "capybara"
gem "selenium-webdriver"
- gem "webdrivers"
end
diff --git a/Gemfile.lock b/Gemfile.lock
index 597cc58e..9537cec6 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,249 +1,373 @@
GEM
remote: https://rubygems.org/
specs:
- actioncable (7.0.1)
- actionpack (= 7.0.1)
- activesupport (= 7.0.1)
+ action_text-trix (2.1.15)
+ railties
+ actioncable (8.1.0)
+ actionpack (= 8.1.0)
+ activesupport (= 8.1.0)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
- actionmailbox (7.0.1)
- actionpack (= 7.0.1)
- activejob (= 7.0.1)
- activerecord (= 7.0.1)
- activestorage (= 7.0.1)
- activesupport (= 7.0.1)
- mail (>= 2.7.1)
- net-imap
- net-pop
- net-smtp
- actionmailer (7.0.1)
- actionpack (= 7.0.1)
- actionview (= 7.0.1)
- activejob (= 7.0.1)
- activesupport (= 7.0.1)
- mail (~> 2.5, >= 2.5.4)
- net-imap
- net-pop
- net-smtp
- rails-dom-testing (~> 2.0)
- actionpack (7.0.1)
- actionview (= 7.0.1)
- activesupport (= 7.0.1)
- rack (~> 2.0, >= 2.2.0)
+ zeitwerk (~> 2.6)
+ actionmailbox (8.1.0)
+ actionpack (= 8.1.0)
+ activejob (= 8.1.0)
+ activerecord (= 8.1.0)
+ activestorage (= 8.1.0)
+ activesupport (= 8.1.0)
+ mail (>= 2.8.0)
+ actionmailer (8.1.0)
+ actionpack (= 8.1.0)
+ actionview (= 8.1.0)
+ activejob (= 8.1.0)
+ activesupport (= 8.1.0)
+ mail (>= 2.8.0)
+ rails-dom-testing (~> 2.2)
+ actionpack (8.1.0)
+ actionview (= 8.1.0)
+ activesupport (= 8.1.0)
+ nokogiri (>= 1.8.5)
+ rack (>= 2.2.4)
+ rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
- rails-dom-testing (~> 2.0)
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
- actiontext (7.0.1)
- actionpack (= 7.0.1)
- activerecord (= 7.0.1)
- activestorage (= 7.0.1)
- activesupport (= 7.0.1)
+ rails-dom-testing (~> 2.2)
+ rails-html-sanitizer (~> 1.6)
+ useragent (~> 0.16)
+ actiontext (8.1.0)
+ action_text-trix (~> 2.1.15)
+ actionpack (= 8.1.0)
+ activerecord (= 8.1.0)
+ activestorage (= 8.1.0)
+ activesupport (= 8.1.0)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
- actionview (7.0.1)
- activesupport (= 7.0.1)
+ actionview (8.1.0)
+ activesupport (= 8.1.0)
builder (~> 3.1)
- erubi (~> 1.4)
- rails-dom-testing (~> 2.0)
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
- activejob (7.0.1)
- activesupport (= 7.0.1)
+ erubi (~> 1.11)
+ rails-dom-testing (~> 2.2)
+ rails-html-sanitizer (~> 1.6)
+ activejob (8.1.0)
+ activesupport (= 8.1.0)
globalid (>= 0.3.6)
- activemodel (7.0.1)
- activesupport (= 7.0.1)
- activerecord (7.0.1)
- activemodel (= 7.0.1)
- activesupport (= 7.0.1)
- activestorage (7.0.1)
- actionpack (= 7.0.1)
- activejob (= 7.0.1)
- activerecord (= 7.0.1)
- activesupport (= 7.0.1)
+ activemodel (8.1.0)
+ activesupport (= 8.1.0)
+ activerecord (8.1.0)
+ activemodel (= 8.1.0)
+ activesupport (= 8.1.0)
+ timeout (>= 0.4.0)
+ activestorage (8.1.0)
+ actionpack (= 8.1.0)
+ activejob (= 8.1.0)
+ activerecord (= 8.1.0)
+ activesupport (= 8.1.0)
marcel (~> 1.0)
- mini_mime (>= 1.1.0)
- activesupport (7.0.1)
- concurrent-ruby (~> 1.0, >= 1.0.2)
+ activesupport (8.1.0)
+ base64
+ bigdecimal
+ concurrent-ruby (~> 1.0, >= 1.3.1)
+ connection_pool (>= 2.2.5)
+ drb
i18n (>= 1.6, < 2)
+ json
+ logger (>= 1.4.2)
minitest (>= 5.1)
- tzinfo (~> 2.0)
- addressable (2.8.0)
- public_suffix (>= 2.0.2, < 5.0)
+ securerandom (>= 0.3)
+ tzinfo (~> 2.0, >= 2.0.5)
+ uri (>= 0.13.1)
+ addressable (2.8.7)
+ public_suffix (>= 2.0.2, < 7.0)
+ ast (2.4.3)
+ base64 (0.3.0)
+ bigdecimal (3.3.1)
bindex (0.8.1)
- bootsnap (1.10.2)
- msgpack (~> 1.2)
- builder (3.2.4)
- capybara (3.36.0)
+ builder (3.3.0)
+ capybara (3.40.0)
addressable
matrix
mini_mime (>= 0.1.3)
- nokogiri (~> 1.8)
+ nokogiri (~> 1.11)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
- childprocess (4.1.0)
- concurrent-ruby (1.1.9)
- connection_pool (2.2.5)
+ concurrent-ruby (1.3.5)
+ connection_pool (2.5.4)
crass (1.0.6)
- cssbundling-rails (1.0.0)
+ cssbundling-rails (1.4.3)
railties (>= 6.0.0)
- debug (1.4.0)
- irb (>= 1.3.6)
- reline (>= 0.2.7)
- digest (3.1.0)
- erubi (1.10.0)
- globalid (1.0.0)
- activesupport (>= 5.0)
- i18n (1.8.11)
+ date (3.4.1)
+ debug (1.11.0)
+ irb (~> 1.10)
+ reline (>= 0.3.8)
+ drb (2.2.3)
+ erb (5.0.3)
+ erubi (1.13.1)
+ ffi (1.17.2-aarch64-linux-gnu)
+ ffi (1.17.2-aarch64-linux-musl)
+ ffi (1.17.2-arm-linux-gnu)
+ ffi (1.17.2-arm-linux-musl)
+ ffi (1.17.2-arm64-darwin)
+ ffi (1.17.2-x86_64-darwin)
+ ffi (1.17.2-x86_64-linux-gnu)
+ ffi (1.17.2-x86_64-linux-musl)
+ globalid (1.3.0)
+ activesupport (>= 6.1)
+ hotwire-spark (0.1.13)
+ listen
+ rails (>= 7.0.0)
+ zeitwerk
+ i18n (1.14.7)
concurrent-ruby (~> 1.0)
- io-console (0.5.11)
- io-wait (0.2.1)
- irb (1.4.1)
- reline (>= 0.3.0)
- jbuilder (2.11.5)
- actionview (>= 5.0.0)
- activesupport (>= 5.0.0)
- jsbundling-rails (1.0.0)
+ io-console (0.8.1)
+ irb (1.15.2)
+ pp (>= 0.6.0)
+ rdoc (>= 4.0.0)
+ reline (>= 0.4.2)
+ jbuilder (2.14.1)
+ actionview (>= 7.0.0)
+ activesupport (>= 7.0.0)
+ jsbundling-rails (1.3.1)
railties (>= 6.0.0)
- loofah (2.13.0)
+ json (2.13.2)
+ language_server-protocol (3.17.0.5)
+ lint_roller (1.1.0)
+ listen (3.9.0)
+ rb-fsevent (~> 0.10, >= 0.10.3)
+ rb-inotify (~> 0.9, >= 0.9.10)
+ logger (1.7.0)
+ loofah (2.24.1)
crass (~> 1.0.2)
- nokogiri (>= 1.5.9)
- mail (2.7.1)
+ nokogiri (>= 1.12.0)
+ mail (2.8.1)
mini_mime (>= 0.1.1)
- marcel (1.0.2)
- matrix (0.4.2)
- method_source (1.0.0)
- mini_mime (1.1.2)
- minitest (5.15.0)
- msgpack (1.4.4)
- net-imap (0.2.3)
- digest
+ net-imap
+ net-pop
+ net-smtp
+ marcel (1.1.0)
+ matrix (0.4.3)
+ mini_mime (1.1.5)
+ minitest (5.26.0)
+ msgpack (1.8.0)
+ net-imap (0.5.12)
+ date
net-protocol
- strscan
- net-pop (0.1.1)
- digest
+ net-pop (0.1.2)
net-protocol
+ net-protocol (0.2.2)
timeout
- net-protocol (0.1.2)
- io-wait
- timeout
- net-smtp (0.3.1)
- digest
+ net-smtp (0.5.1)
net-protocol
- timeout
- nio4r (2.5.8)
- nokogiri (1.13.1-x86_64-linux)
+ nio4r (2.7.4)
+ nokogiri (1.18.10-aarch64-linux-gnu)
+ racc (~> 1.4)
+ nokogiri (1.18.10-aarch64-linux-musl)
+ racc (~> 1.4)
+ nokogiri (1.18.10-arm-linux-gnu)
+ racc (~> 1.4)
+ nokogiri (1.18.10-arm-linux-musl)
+ racc (~> 1.4)
+ nokogiri (1.18.10-arm64-darwin)
+ racc (~> 1.4)
+ nokogiri (1.18.10-x86_64-darwin)
+ racc (~> 1.4)
+ nokogiri (1.18.10-x86_64-linux-gnu)
racc (~> 1.4)
- pg (1.2.3)
- public_suffix (4.0.6)
- puma (5.5.2)
+ nokogiri (1.18.10-x86_64-linux-musl)
+ racc (~> 1.4)
+ parallel (1.27.0)
+ parser (3.3.9.0)
+ ast (~> 2.4.1)
+ racc
+ pg (1.6.2)
+ pg (1.6.2-aarch64-linux)
+ pg (1.6.2-aarch64-linux-musl)
+ pg (1.6.2-arm64-darwin)
+ pg (1.6.2-x86_64-darwin)
+ pg (1.6.2-x86_64-linux)
+ pg (1.6.2-x86_64-linux-musl)
+ pp (0.6.3)
+ prettyprint
+ prettyprint (0.2.0)
+ prism (1.4.0)
+ propshaft (1.3.1)
+ actionpack (>= 7.0.0)
+ activesupport (>= 7.0.0)
+ rack
+ psych (5.2.6)
+ date
+ stringio
+ public_suffix (6.0.2)
+ puma (7.1.0)
nio4r (~> 2.0)
- racc (1.6.0)
- rack (2.2.3)
- rack-mini-profiler (2.3.3)
+ racc (1.8.1)
+ rack (3.2.2)
+ rack-mini-profiler (4.0.1)
rack (>= 1.2.0)
- rack-test (1.1.0)
- rack (>= 1.0, < 3)
- rails (7.0.1)
- actioncable (= 7.0.1)
- actionmailbox (= 7.0.1)
- actionmailer (= 7.0.1)
- actionpack (= 7.0.1)
- actiontext (= 7.0.1)
- actionview (= 7.0.1)
- activejob (= 7.0.1)
- activemodel (= 7.0.1)
- activerecord (= 7.0.1)
- activestorage (= 7.0.1)
- activesupport (= 7.0.1)
+ rack-session (2.1.1)
+ base64 (>= 0.1.0)
+ rack (>= 3.0.0)
+ rack-test (2.2.0)
+ rack (>= 1.3)
+ rackup (2.2.1)
+ rack (>= 3)
+ rails (8.1.0)
+ actioncable (= 8.1.0)
+ actionmailbox (= 8.1.0)
+ actionmailer (= 8.1.0)
+ actionpack (= 8.1.0)
+ actiontext (= 8.1.0)
+ actionview (= 8.1.0)
+ activejob (= 8.1.0)
+ activemodel (= 8.1.0)
+ activerecord (= 8.1.0)
+ activestorage (= 8.1.0)
+ activesupport (= 8.1.0)
bundler (>= 1.15.0)
- railties (= 7.0.1)
- rails-dom-testing (2.0.3)
- activesupport (>= 4.2.0)
+ railties (= 8.1.0)
+ rails-dom-testing (2.3.0)
+ activesupport (>= 5.0.0)
+ minitest
nokogiri (>= 1.6)
- rails-html-sanitizer (1.4.2)
- loofah (~> 2.3)
- railties (7.0.1)
- actionpack (= 7.0.1)
- activesupport (= 7.0.1)
- method_source
+ rails-html-sanitizer (1.6.2)
+ loofah (~> 2.21)
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
+ railties (8.1.0)
+ actionpack (= 8.1.0)
+ activesupport (= 8.1.0)
+ irb (~> 1.13)
+ rackup (>= 1.0.0)
rake (>= 12.2)
- thor (~> 1.0)
- zeitwerk (~> 2.5)
- rake (13.0.6)
- redis (4.5.1)
- regexp_parser (2.2.0)
- reline (0.3.1)
+ thor (~> 1.0, >= 1.2.2)
+ tsort (>= 0.2)
+ zeitwerk (~> 2.6)
+ rainbow (3.1.1)
+ rake (13.3.0)
+ rb-fsevent (0.11.2)
+ rb-inotify (0.11.1)
+ ffi (~> 1.0)
+ rdoc (6.15.0)
+ erb
+ psych (>= 4.0.0)
+ tsort
+ redis (5.4.1)
+ redis-client (>= 0.22.0)
+ redis-client (0.26.1)
+ connection_pool
+ regexp_parser (2.11.3)
+ reline (0.6.2)
io-console (~> 0.5)
- rexml (3.2.5)
- rubyzip (2.3.2)
- selenium-webdriver (4.1.0)
- childprocess (>= 0.5, < 5.0)
+ rexml (3.4.4)
+ rubocop (1.81.1)
+ json (~> 2.3)
+ language_server-protocol (~> 3.17.0.2)
+ lint_roller (~> 1.1.0)
+ parallel (~> 1.10)
+ parser (>= 3.3.0.2)
+ rainbow (>= 2.2.2, < 4.0)
+ regexp_parser (>= 2.9.3, < 3.0)
+ rubocop-ast (>= 1.47.1, < 2.0)
+ ruby-progressbar (~> 1.7)
+ unicode-display_width (>= 2.4.0, < 4.0)
+ rubocop-ast (1.47.1)
+ parser (>= 3.3.7.2)
+ prism (~> 1.4)
+ rubocop-performance (1.26.0)
+ lint_roller (~> 1.1)
+ rubocop (>= 1.75.0, < 2.0)
+ rubocop-ast (>= 1.44.0, < 2.0)
+ rubocop-rails (2.33.4)
+ activesupport (>= 4.2.0)
+ lint_roller (~> 1.1)
+ rack (>= 1.1)
+ rubocop (>= 1.75.0, < 2.0)
+ rubocop-ast (>= 1.44.0, < 2.0)
+ rubocop-rails-omakase (1.1.0)
+ rubocop (>= 1.72)
+ rubocop-performance (>= 1.24)
+ rubocop-rails (>= 2.30)
+ ruby-progressbar (1.13.0)
+ rubyzip (3.1.1)
+ securerandom (0.4.1)
+ selenium-webdriver (4.36.0)
+ base64 (~> 0.2)
+ json (<= 2.13.2)
+ logger (~> 1.4)
+ prism (~> 1.0, < 1.5)
rexml (~> 3.2, >= 3.2.5)
- rubyzip (>= 1.2.2)
- sidekiq (6.4.0)
- connection_pool (>= 2.2.2)
- rack (~> 2.0)
- redis (>= 4.2.0)
- sprockets (4.0.2)
- concurrent-ruby (~> 1.0)
- rack (> 1, < 3)
- sprockets-rails (3.4.2)
- actionpack (>= 5.2)
- activesupport (>= 5.2)
- sprockets (>= 3.0.0)
- stimulus-rails (1.0.2)
- railties (>= 6.0.0)
- strscan (3.0.1)
- thor (1.2.1)
- timeout (0.2.0)
- turbo-rails (1.0.1)
- actionpack (>= 6.0.0)
+ rubyzip (>= 1.2.2, < 4.0)
+ websocket (~> 1.0)
+ sidekiq (8.0.8)
+ connection_pool (>= 2.5.0)
+ json (>= 2.9.0)
+ logger (>= 1.6.2)
+ rack (>= 3.1.0)
+ redis-client (>= 0.23.2)
+ stimulus-rails (1.3.4)
railties (>= 6.0.0)
- tzinfo (2.0.4)
+ stringio (3.1.7)
+ thor (1.4.0)
+ timeout (0.4.3)
+ tsort (0.2.0)
+ turbo-rails (2.0.17)
+ actionpack (>= 7.1.0)
+ railties (>= 7.1.0)
+ tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
- web-console (4.2.0)
+ unicode-display_width (3.2.0)
+ unicode-emoji (~> 4.1)
+ unicode-emoji (4.1.0)
+ uri (1.0.4)
+ useragent (0.16.11)
+ web-console (4.2.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 6.0.0)
- webdrivers (5.0.0)
- nokogiri (~> 1.6)
- rubyzip (>= 1.3.0)
- selenium-webdriver (~> 4.0)
- websocket-driver (0.7.5)
+ websocket (1.2.11)
+ websocket-driver (0.8.0)
+ base64
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
- zeitwerk (2.5.3)
+ zeitwerk (2.7.3)
PLATFORMS
- x86_64-linux
+ aarch64-linux
+ aarch64-linux-gnu
+ aarch64-linux-musl
+ arm-linux-gnu
+ arm-linux-musl
+ arm64-darwin
+ x86_64-darwin
+ x86_64-linux-gnu
+ x86_64-linux-musl
DEPENDENCIES
- bootsnap
capybara
cssbundling-rails
debug
+ hotwire-spark (~> 0.1)
jbuilder
jsbundling-rails
+ msgpack (>= 1.7.0)
pg (~> 1.1)
- puma (~> 5.0)
+ propshaft (~> 1.1)
+ puma (~> 7.1)
rack-mini-profiler
- rails (~> 7.0.1)
- redis (~> 4.0)
+ rails (~> 8.1)
+ redis (~> 5.2)
+ rubocop-rails-omakase
selenium-webdriver
- sidekiq (~> 6.4)
- sprockets-rails
+ sidekiq (~> 8.0)
stimulus-rails
turbo-rails
tzinfo-data
web-console
- webdrivers
RUBY VERSION
- ruby 3.1.0p0
+ ruby 3.4.7p58
BUNDLED WITH
- 2.3.3
+ 2.6.9
diff --git a/README.md b/README.md
index e6f0f75e..fb9c0c16 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,4 @@
-# An example Rails + Docker app
-
-
+# ๐ณ An example Rails + Docker app
You could use this example app as a base for your new project or as a guide to
Dockerize your existing Rails app.
@@ -14,12 +12,12 @@ practices](https://nickjanetakis.com/blog/best-practices-around-production-ready
based on building and deploying dozens of assorted Dockerized web apps since
late 2014.
-**This app is using Rails 7.0.1 and Ruby 3.1.0**. The screenshot doesn't get
-updated every time I bump the versions:
+**This app is using Rails 8.1.0 and Ruby 3.4.7**. The screenshot shows
+`X.X.X` since they get updated regularly:
[](https://github.com/nickjj/docker-rails-example/blob/main/.github/docs/screenshot.jpg?raw=true)
-## Table of contents
+## ๐งพ Table of contents
- [Tech stack](#tech-stack)
- [Main changes vs a newly generated Rails app](#main-changes-vs-a-newly-generated-rails-app)
@@ -35,7 +33,7 @@ updated every time I bump the versions:
- [Deploy to production](#deploy-to-production)
- [About the author](#about-the-author)
-## Tech stack
+## ๐งฌ Tech stack
If you don't like some of these choices that's no problem, you can swap them
out for something else on your own.
@@ -56,7 +54,7 @@ out for something else on your own.
- [TailwindCSS](https://tailwindcss.com/)
- [Heroicons](https://heroicons.com/)
-## Main changes vs a newly generated Rails app
+## ๐ฃ Notable opinions and packages
Here's a run down on what's different. You can also use this as a guide to
Dockerize an existing Rails app.
@@ -66,21 +64,28 @@ Dockerize an existing Rails app.
- Use Redis as the cache back-end
- Use Sidekiq as a background worker through Active Job
- Use a standalone Action Cable process
+ - Remove `solid_*` adapters (for now)
+ - Remove Kamal and Thruster (for now)
- **App Features**:
- - Add a `pages` controller with `home` and `up` (health check) actions
+ - Add `pages` controller with a home page
+ - Add `up` controller with 2 health check related actions
+ - Remove generated code around PWA and service workers
- **Config**:
- - Log to STDOUT so that Docker can consume and deal with log output
+ - Log to STDOUT so that Docker can consume and deal with log output
- Credentials are removed (secrets are loaded in with an `.env` file)
- Extract a bunch of configuration settings into environment variables
- Rewrite `config/database.yml` to use environment variables
- `.yarnc` sets a custom `node_modules/` directory
- - `config/initializers/assets.rb` references a custom `node_modules/` directory
+ - `config/initializers/enable_yjit.rb` to enable YJIT
+ - `config/initializers/rack_mini_profiler.rb` to enable profiling Hotwire Turbo Drive
- `config/routes.rb` has Sidekiq's dashboard ready to be used but commented out for safety
- - `Procifile.dev` has been removed since Docker Compose handles this for us
+ - `Procfile.dev` has been removed since Docker Compose handles this for us
+ - Brakeman has been removed
- **Assets**:
- Use esbuild (`-j esbuild`) and TailwindCSS (`-c tailwind`)
- Add `postcss-import` support for `tailwindcss` by using the `--postcss` flag
- Add ActiveStorage JavaScript package
+ - Add [Hotwire Spark](https://github.com/hotwired/spark) for live reloading in development
- **Public:**
- Custom `502.html` and `maintenance.html` pages
- Generate favicons using modern best practices
@@ -89,7 +94,7 @@ Besides the Rails app itself, a number of new Docker related files were added
to the project which would be any file having `*docker*` in its name. Also
GitHub Actions have been set up.
-## Running this app
+## ๐ Running this app
You'll need to have [Docker installed](https://docs.docker.com/get-docker/).
It's available on Windows, macOS and most distros of Linux. If you're new to
@@ -97,6 +102,14 @@ Docker and want to learn it in detail check out the [additional resources
links](#learn-more-about-docker-and-ruby-on-rails) near the bottom of this
README.
+You'll also need to enable Docker Compose v2 support if you're using Docker
+Desktop. On native Linux without Docker Desktop you can [install it as a plugin
+to Docker](https://docs.docker.com/compose/install/linux/). It's been generally
+available for a while now and is stable. This project uses specific [Docker
+Compose v2
+features](https://nickjanetakis.com/blog/optional-depends-on-with-docker-compose-v2-20-2)
+that only work with Docker Compose v2 2.20.2+.
+
If you're using Windows, it will be expected that you're following along inside
of [WSL or WSL
2](https://nickjanetakis.com/blog/a-linux-dev-environment-on-windows-with-wsl-2-docker-desktop-and-more).
@@ -109,14 +122,13 @@ these commands for PowerShell if you want.
git clone https://github.com/nickjj/docker-rails-example hellorails
cd hellorails
-# Optionally checkout a specific tag, such as: git checkout 0.5.0
+# Optionally checkout a specific tag, such as: git checkout 0.9.0
```
-#### Copy a few example files because the real files are git ignored:
+#### Copy an example .env file because the real one is git ignored:
```sh
cp .env.example .env
-cp docker-compose.override.yml.example docker-compose.override.yml
```
#### Build everything:
@@ -126,16 +138,25 @@ internet connection speed and computer's hardware specs. That's because it's
going to download a few Docker images and build the Ruby + Yarn dependencies.*
```sh
-docker-compose up --build
+docker compose up --build
```
Now that everything is built and running we can treat it like any other Rails
app.
+Did you receive a `depends_on` "Additional property required is not allowed"
+error? Please update to at least Docker Compose v2.20.2+ or Docker Desktop
+4.22.0+.
+
Did you receive an error about a port being in use? Chances are it's because
something on your machine is already running on port 8000. Check out the docs
in the `.env` file for the `DOCKER_WEB_PORT` variable to fix this.
+Did you receive a permission denied error? Chances are you're running native
+Linux and your `uid:gid` aren't `1000:1000` (you can verify this by running
+`id`). Check out the docs in the `.env` file to customize the `UID` and `GID`
+variables to fix this.
+
#### Setup the initial database:
```sh
@@ -149,6 +170,19 @@ in the `.env` file for the `DOCKER_WEB_PORT` variable to fix this.
Visit in your favorite browser.
+#### Formatting the code base:
+
+```sh
+# You should see that everything is unchanged (it's all already formatted).
+./run format
+```
+
+You can also run `./run format --auto-correct` which will automatically correct
+any issues that are auto-correctable. Alternatively the shorthand `-a` flag
+does the same thing.
+
+*There's also a `./run quality` command to lint and format all files.*
+
#### Running the test suite:
```sh
@@ -165,13 +199,13 @@ browser.
```sh
# Stop the containers and remove a few Docker related resources associated to this project.
-docker-compose down
+docker compose down
```
-You can start things up again with `docker-compose up` and unlike the first
+You can start things up again with `docker compose up` and unlike the first
time it should only take seconds.
-## Files of interest
+## ๐ Files of interest
I recommend checking out most files and searching the code base for `TODO:`,
but please review the `.env` and `run` files before diving into the rest of the
@@ -208,7 +242,7 @@ functions as you want. This file's purpose is to make your experience better!
`alias run=./run` in your `~/.bash_aliases` or equivalent file. Then you'll be
able to run `run` instead of `./run`.*
-## Running a script to automate renaming the project
+## โจ Running a script to automate renaming the project
The app is named `hello` right now but chances are your app will be a different
name. Since the app is already created we'll need to do a find / replace on a
@@ -255,7 +289,7 @@ also need to setup our database since a new one will be created for us by
Docker.
```sh
-docker-compose up --build
+docker compose up --build
# Then in a 2nd terminal once it's up and ready.
./run rails db:setup
@@ -268,6 +302,7 @@ adding custom changes.
```sh
# You can run this from the same terminal as before.
+./run quality
./run test
```
@@ -291,53 +326,56 @@ to it. If you want to reference me directly please link to my site at
. You don't have to do this, but it would be very
much appreciated!
-## Updating dependencies
-
-Let's say you've customized your app and it's time to make a change to your
-`Gemfile` or `package.json` file.
-
-Without Docker you'd normally run `bundle install` or `yarn install`. With
-Docker it's basically the same thing and since these commands are in our
-`Dockerfile` we can get away with doing a `docker-compose build` but don't run
-that just yet.
-
-#### In development:
+## ๐ Updating dependencies
You can run `./run bundle:outdated` or `./run yarn:outdated` to get a list of
outdated dependencies based on what you currently have installed. Once you've
figured out what you want to update, go make those updates in your `Gemfile`
and / or `package.json` file.
-Then to update your dependencies you can run `./run bundle:install` or `./run
-yarn:install`. That'll make sure any lock files get copied from Docker's image
-(thanks to volumes) into your code repo and now you can commit those files to
-version control like usual.
+Or, let's say you've customized your app and it's time to add a new dependency,
+either for Ruby or Node.
+
+#### In development:
+
+##### Option 1
+
+1. Directly edit `Gemfile` or `package.json` to add your package
+2. `./run deps:install` or `./run deps:install --no-build`
+ - The `--no-build` option will only write out a new lock file without re-building your image
+
+##### Option 2
+
+1. Run `./run bundle add mypackage --skip-install` or `run yarn add mypackage --no-lockfile` which will update your `Gemfile` or `package.json` with the latest version of that package but not install it
+2. The same step as step 2 from option 1
-Alternatively for updating your gems based on specific version ranges defined
-in your `Gemfile` you can run `./run bundle:update` which will install the
-latest versions of your gems and then write out a new lock file.
+Either option is fine, it's up to you based on what's more convenient at the
+time. You can modify the above workflows for updating an existing package or
+removing one as well.
-You can check out the `run` file to see what these commands do in more detail.
+You can also access `bundle` and `yarn` in Docker with `./run bundle` and
+`./run yarn` after you've upped the project.
#### In CI:
-You'll want to run `docker-compose build` since it will use any existing lock
+You'll want to run `docker compose build` since it will use any existing lock
files if they exist. You can also check out the complete CI test pipeline in
-the `run` file under the `ci:test` function.
+the [run](https://github.com/nickjj/docker-rails-example/blob/main/run) file
+under the `ci:test` function.
#### In production:
This is usually a non-issue since you'll be pulling down pre-built images from
a Docker registry but if you decide to build your Docker images directly on
-your server you could run `docker-compose build` as part of your deploy
-pipeline.
+your server you could run `docker compose build` as part of your deploy
+pipeline which is similar to how it would work in CI.
-## See a way to improve something?
+## ๐ค See a way to improve something?
If you see anything that could be improved please open an issue or start a PR.
Any help is much appreciated!
-## Additional resources
+## ๐ Additional resources
Now that you have your app ready to go, it's time to build something cool! If
you want to learn more about Docker, Rails and deploying a Rails app here's a
@@ -345,7 +383,7 @@ couple of free and paid resources. There's Google too!
### Learn more about Docker and Ruby on Rails
-#### Official documentation
+#### Official documentation
-
-
@@ -363,7 +401,7 @@ you want to get notified when it launches with a discount and potentially get
free videos while the course is being developed then [sign up here to get
notified](https://nickjanetakis.com/courses/deploy-to-production).
-## About the author
+## ๐ About the author
- Nick Janetakis | | [@nickjanetakis](https://twitter.com/nickjanetakis)
@@ -371,7 +409,7 @@ I'm a self taught developer and have been freelancing for the last ~20 years.
You can read about everything I've learned along the way on my site at
[https://nickjanetakis.com](https://nickjanetakis.com/).
-There's hundreds of [blog posts](https://nickjanetakis.com/blog/) and a couple
-of [video courses](https://nickjanetakis.com/courses/) on web development and
+There's hundreds of [blog posts](https://nickjanetakis.com/blog) and a couple
+of [video courses](https://nickjanetakis.com/courses) on web development and
deployment topics. I also have a [podcast](https://runninginproduction.com)
where I talk with folks about running web apps in production.
diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js
deleted file mode 100644
index 9a99757a..00000000
--- a/app/assets/config/manifest.js
+++ /dev/null
@@ -1,2 +0,0 @@
-//= link_tree ../images
-//= link_tree ../builds
diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css
index 7fea409d..d73d3249 100644
--- a/app/assets/stylesheets/application.tailwind.css
+++ b/app/assets/stylesheets/application.tailwind.css
@@ -1,7 +1 @@
-/*
- * Your custom CSS goes here but before adding a lot of CSS check this out:
- * https://tailwindcss.com/docs/extracting-components
-*/
-@import "tailwindcss/base";
-@import "tailwindcss/components";
-@import "tailwindcss/utilities";
+@import "tailwindcss" source("/app");
diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb
index a99d3e27..45f463e4 100644
--- a/app/controllers/pages_controller.rb
+++ b/app/controllers/pages_controller.rb
@@ -1,11 +1,4 @@
class PagesController < ApplicationController
def home
end
-
- def up
- Redis.current.ping
- ActiveRecord::Base.connection.execute("SELECT 1")
-
- head :ok
- end
end
diff --git a/app/controllers/up_controller.rb b/app/controllers/up_controller.rb
new file mode 100644
index 00000000..8416becf
--- /dev/null
+++ b/app/controllers/up_controller.rb
@@ -0,0 +1,12 @@
+class UpController < ApplicationController
+ def index
+ head :ok
+ end
+
+ def databases
+ RedisConn.current.ping
+ ActiveRecord::Base.connection.execute("SELECT 1")
+
+ head :ok
+ end
+end
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index f86a39fc..623ea35e 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -5,6 +5,7 @@
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
+ <%= action_cable_meta_tag %>
@@ -35,7 +36,7 @@