Code Monkey home page Code Monkey logo

docker-rails-example's Introduction

An example Rails + Docker app

CI

You could use this example app as a base for your new project or as a guide to Dockerize your existing Rails app.

The example app is minimal but it wires up a number of things you might use in a real world Rails app, but at the same time it's not loaded up with a million personal opinions.

For the Docker bits, everything included is an accumulation of Docker best practices based on building and deploying dozens of assorted Dockerized web apps since late 2014.

This app is using Rails 7.1.3.4 and Ruby 3.3.3. The screenshot doesn't get updated every time I bump the versions:

Screenshot

Table of contents

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.

Back-end

Front-end

Main changes vs a newly generated Rails app

Here's a run down on what's different. You can also use this as a guide to Dockerize an existing Rails app.

  • Core:
    • Use PostgreSQL (-d postgresql) as the primary SQL database
    • Use Redis as the cache back-end
    • Use Sidekiq as a background worker through Active Job
    • Use a standalone Action Cable process
  • App Features:
    • Add pages controller with a home page
    • Add up controller with 2 health check related actions
  • Config:
    • 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/enable_yjit.rb to enable YJIT
    • config/initializers/rack_mini_profiler.rb to enable profiling Hotwire Turbo Drive
    • config/initializers/assets.rb references a custom node_modules/ directory
    • config/routes.rb has Sidekiq's dashboard ready to be used but commented out for safety
    • Procfile.dev has been removed since Docker Compose handles this for us
  • Assets:
    • Use esbuild (-j esbuild) and TailwindCSS (-c tailwind)
    • Add postcss-import support for tailwindcss by using the --postcss flag
    • Add ActiveStorage JavaScript package
  • Public:
    • Custom 502.html and maintenance.html pages
    • Generate favicons using modern best practices

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

You'll need to have Docker installed. It's available on Windows, macOS and most distros of Linux. If you're new to Docker and want to learn it in detail check out the additional resources links 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. It's been generally available for a while now and is stable. This project uses specific Docker Compose v2 features 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. That's because we're going to be running shell commands. You can always modify these commands for PowerShell if you want.

Clone this repo anywhere you want and move into the directory:

git clone https://github.com/nickjj/docker-rails-example hellorails
cd hellorails

# Optionally checkout a specific tag, such as: git checkout 0.8.0

Copy an example .env file because the real one is git ignored:

cp .env.example .env

Build everything:

The first time you run this it's going to take 5-10 minutes depending on your 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.

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:

# You can run this from a 2nd terminal.
./run rails db:setup

We'll go over that ./run script in a bit!

Check it out in a browser:

Visit http://localhost:8000 in your favorite browser.

Running the test suite:

# You can run this from the same terminal as before.
./run test

You can also run ./run test -b with does the same thing but builds your JS and CSS bundles. This could come in handy in fresh environments such as CI where your assets haven't changed and you haven't visited the page in a browser.

Stopping everything:

# Stop the containers and remove a few Docker related resources associated to this project.
docker compose down

You can start things up again with docker compose up and unlike the first time it should only take seconds.

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 code and customizing it. Also, you should hold off on changing anything until we cover how to customize this example app's name with an automated script (coming up next in the docs).

.env

This file is ignored from version control so it will never be commit. There's a number of environment variables defined here that control certain options and behavior of the application. Everything is documented there.

Feel free to add new variables as needed. This is where you should put all of your secrets as well as configuration that might change depending on your environment (specific dev boxes, CI, production, etc.).

run

You can run ./run to get a list of commands and each command has documentation in the run file itself.

It's a shell script that has a number of functions defined to help you interact with this project. It's basically a Makefile except with less limitations. For example as a shell script it allows us to pass any arguments to another program.

This comes in handy to run various Docker commands because sometimes these commands can be a bit long to type. Feel free to add as many convenience functions as you want. This file's purpose is to make your experience better!

If you get tired of typing ./run you can always create a shell alias with 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

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 few variants of the string "hello" and update a few Docker related resources.

And by we I mean I created a zero dependency shell script that does all of the heavy lifting for you. All you have to do is run the script below.

Run the rename-project script included in this repo:

# The script takes 2 arguments.
#
# The first one is the lower case version of your app's name, such as myapp or
# my_app depending on your preference.
#
# The second one is used for your app's module name. For example if you used
# myapp or my_app for the first argument you would want to use MyApp here.
bin/rename-project myapp MyApp

The bin/rename-project script is going to:

  • Remove any Docker resources for your current project
  • Perform a number of find / replace actions
  • Optionally initialize a new git repo for you

Afterwards you can delete this script because its only purpose is to assist in helping you change this project's name without depending on any complicated project generator tools or 3rd party dependencies.

If you're not comfy running the script or it doesn't work for whatever reasons you can check it out and perform the actions manually. It's mostly running a find / replace across files and then renaming a few directories and files.

Start and setup the project:

This won't take as long as before because Docker can re-use most things. We'll also need to setup our database since a new one will be created for us by Docker.

docker compose up --build

# Then in a 2nd terminal once it's up and ready.
./run rails db:setup

Sanity check to make sure the tests still pass:

It's always a good idea to make sure things are in a working state before adding custom changes.

# You can run this from the same terminal as before.
./run test

If everything passes now you can optionally git add -A && git commit -m "Initial commit" and start customizing your app. Alternatively you can wait until you develop more of your app before committing anything. It's up to you!

Tying up a few loose ends:

You'll probably want to create a fresh CHANGELOG.md file for your project. I like following the style guide at https://keepachangelog.com/ but feel free to use whichever style you prefer.

Since this project is MIT licensed you should keep my name and email address in the LICENSE file to adhere to that license's agreement, but you can also add your name and email on a new line.

If you happen to base your app off this example app or write about any of the code in this project it would be rad if you could credit this repo by linking to it. If you want to reference me directly please link to my site at https://nickjanetakis.com. 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:

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.

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.

You can check out the run file to see what these commands do in more detail.

In CI:

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.

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.

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

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 couple of free and paid resources. There's Google too!

Learn more about Docker and Ruby on Rails

Official documentation

Courses / Screencasts

Deploy to production

I'm creating an in-depth course related to deploying Dockerized web apps. If 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.

About the author

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.

There's hundreds of blog posts and a couple of video courses on web development and deployment topics. I also have a podcast where I talk with folks about running web apps in production.

docker-rails-example's People

Contributors

edruder avatar jberendes avatar nickjj avatar saiqulhaq avatar travisdock avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

docker-rails-example's Issues

Issue calling Node Binaries / Modules

Dear @nickjj ,

first of all, i would like to thank you for putting together this awesome repository and project. This is a really cool starter for new rails projects.

I have started to work on a rails application and have installed devise for my user management. In order to send mails, i would like to use mjml (https://mjml.io/) and mjml-rails (https://github.com/sighmon/mjml-rails) respectively. However, mjml-rails requires you to also install the npm package mjml (i.e., yarn install mjml)

As far as i have understood, mjml-rails calls the mjml binary from the mjml node package in order to transform the <mjml-*> tags to proper valid and responsive html tags .

In the docker-compose setup of this project, however, all js-bundling stuff works within the NAME-js container. The actual web container does not have a node-modules folder. Hence, the mjml binary is missing.

How can i get this to work? This is not only the problem with mjml, but rather with all node packages that are called via the console, right? I know, that the basic idea is to have all the javascript-stuff built within a dedicated container and then "move the final product" to the application container. But in this case (i.e., requiring a dedicated node binary that is invoked via the console) this does not work. Or am i missing something?

Thank you very much for your time and effort in helping me with this issue.
All the best,
Johannes

Permission issue on second docker-compose up

I could not use docker compose on my machine - I had to change to docker-compose everywhere. Otherwise I just followed the setup in the README.

On the first docker-compose up, everything worked fine. The server started, and I could visit it in a browser. The second time, I got multiple "permission denied" errors. I had to run chmod -R 777 . in order to be able to boot up.

Full backtrace: https://gist.github.com/danielittlewood0/a6762b0d411124bf6215da8a6573deed

JS entrypoint not executing

First off - this package is perfect! After spending way too long trying to get Rails up and running with Docker, I came across this repo which has the nice bonus of having just the packages I needed included. Excited to dig in.

One issue that I have come across - I notice that the application.js pack is not running. After downloading, running docker-compose up --build and initialising the database, I can load the home page. However, no javascript is executing - verified by adding a console.log to the start of the application.js file and seeing nothing come up in the console.

I can set up a repo to reproduce, but literally the only thing I changed is to add a console.log. So either there is something really silly I am missing or there is a new bug that has been introduced.

https://www.loom.com/share/5241219529d94a26a889226f11f3cd69

Do we need Nodejs if all assets is disabled ?

Thanks for the useful repository. I have one question.

In my app, all assets is precompiled offline and put in CDN, so i don't run assets when deploying, so is NodeJS nessessary in Dockerfile ?

Fix warnings

Any idea on how to fix this 2 warnings?

web_1 | Warning: the running version of Bundler (2.1.4) is older than the version that created the lockfile (2.2.3). We suggest you to upgrade to the version that created the lockfile by running gem install bundler:2.2.3.

On this, I suggest to install latest bundler in the Dockerfile before running bundle install.

worker_1 | WARN: Unresolved or ambiguous specs during Gem::Specification.reset:
worker_1 | minitest (>= 5.1)
worker_1 | Available/installed versions of this gem:
worker_1 | - 5.14.2
worker_1 | - 5.13.0
worker_1 | rake (>= 0.8.7)
worker_1 | Available/installed versions of this gem:
worker_1 | - 13.0.3
worker_1 | - 13.0.1
worker_1 | WARN: Clearing out unresolved specs. Try 'gem cleanup '
worker_1 | Please report a bug if this causes problems.

I don't know whay the worker service fire this warnings. Any idea?

Tks!

Adding react

Hey, thanks for your great job 🙂 trying to add react as descriped here: https://youtu.be/JsNtLiph87Y?t=586

But seems not that easy? 🤔 Anything else todo for adding react?

Just did ./run yarn:install react react-dom and import a jsx component to a view as described in video, but nothing...

greets dima

Load jQuery

Nick I am sorry to waste your time with such a stupid question. First of all, you've put together an amazing resource. I appreciate it so much and have learned a lot working through it. One thing I am struggling with and have spent a ridiculous amount of time trying every way I can find to get it to load, is adding jQuery via webpack in this project. Is it easy for you to explain?

rename .env file

First of all, thank you for your outstanding contribution to rails + docker.

I'm trying to use dotenv to add some environment variables, and kamal to deploy to production, which will use yaml-formatted .env. Given that the .env used by docker-rails-example is just a bash file, would it be possible to rename it to something like .env_bash, to avoid conflicts with dotenv?

Thank you.

Importmaps missing

Rails 7 introduces import maps and I am wondering if it would make sense providing the option.

Failed to open TCP connection on 9090 port with motor-admin-rails gem

Hi @nickjj !

Thanks for all your work! I already use your repository for some of my personal projects. Recently, I wanted to create a project to use the motor-admin-rails gem.

I followed their doc and yours to install the gem:

  1. add to Gemfile
  2. ./run rails g motor:install
  3. ./run rails db:setup

On startup I get this log from the web service which confirms the installation of the gem:

web-1 | ⚡ Motor::Admin is starting under /motor_admin (the gem has been installed)

But when I want to access the page linked to the gem, I get this error:

web-1 | I, [2024-05-29T15:56:05.269178 #15] INFO -- : Started GET “/motor_admin/assets/main-3b866105d1b5846018e0.css” for 192.168.65.1 at 2024-05-29 15:56:05 +0000
web-1 | E, [2024-05-29T15:56:05.285530 #15] ERROR -- :   
web-1 | Errno::EADDRNOTAVAIL (Failed to open TCP connection to localhost:9090 (Cannot assign requested address - connect(2) for “localhost” port 9090)):

I've already tested these modifications but nothing changes:
Dockerfile:78 EXPOSE 9090
docker-compose.yml:89 - "9090:9090"

Do you know how to allow a connection to port 9090 (for the motor-admin-rails gem) while keeping the connection to port 8000 for the standard rails application?

binding.pry

I'm having difficulty using binding.pry with docker, can anyone use it?

Note: I'm using WSL too, I don't know to what extent it can influence it, but it's worth considering ^^

I'm using the translator

att

MySQL Example

Is it possible to have a MySQL example too as well as Postgres?

App insists on trying to connect to `ws://localhost:8000/cable` when using Hotwire

Following a screencast on how to use Hotwire in Rails and using this project as a starting point, after creating a basic Tweet scaffold and hooking it up using turbo_stream_from and turbo_frame_tag elements, etc., I noticed that the page insists on trying to connect to ws://localhost:8000/cable in spite of the configuration in application.rb.

I tried to identify the cause of the issue and have thus far been unsuccessful. Maybe you will have some idea what's going on?

Enable YJIT by default

Debian Slim now has YJIT available thanks to docker-library/ruby@6db728e.

That means it's available to use, which you can confirm with:

$ docker container run --rm ruby:3.2.0-slim-bullseye ruby --yjit -v
ruby 3.2.0 (2022-12-25 revision a528908271) +YJIT [x86_64-linux]

But it's not enabled by default. One of the easiest ways to enable it is by setting this environment variable RUBYOPT=--yjit. Technically this project is already equipped to use it. You can set that in your .env and you're done.

You can confirm it's "really" enabled and working by running:

$ docker compose up

$ ./run rails console
irb(main):001:0> RubyVM::YJIT.enabled?
=> true

I'm opening this issue mainly as a form of documentation and perhaps in the near'ish future we can enable it by default.

One of the main reasons why I didn't enable it by default already is because memory usage is higher with it enabled and that could play a role in production on a single server or more generally smaller server deploys. Rails is already pretty memory hungry especially when you account for running Puma, Sidekiq and Action Cable. Each of those processes will use more memory. Anything that amplifies that per process could have an impact.

What could be helpful here is to benchmark a couple of use cases to see how much extra memory it uses.

Build on DigitalOcean Droplet fails

Great Work Nick!

All works fine in development, however, launching on a DigitalOcean Droplet does not work.

Here is the output

✔ Network unicorn_new_default Created 0.4s
✔ Volume "unicorn_new_redis" Created 0.0s
✔ Volume "unicorn_new_postgres" Created 0.0s
✔ Container unicorn_new-redis-1 Created 0.8s
✔ Container unicorn_new-js-1 Created 0.8s
✔ Container unicorn_new-css-1 Created 0.8s
✔ Container unicorn_new-postgres-1 Created 0.8s
✔ Container unicorn_new-cable-1 Created 0.2s
✔ Container unicorn_new-web-1 Created 0.2s
✔ Container unicorn_new-worker-1 Created 0.2s
Attaching to cable-1, css-1, js-1, postgres-1, redis-1, web-1, worker-1
redis-1 | 1:C 17 Jun 2024 14:00:11.612 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see jemalloc/jemalloc#1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis-1 | 1:C 17 Jun 2024 14:00:11.613 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis-1 | 1:C 17 Jun 2024 14:00:11.614 * Redis version=7.2.5, bits=64, commit=00000000, modified=0, pid=1, just started
redis-1 | 1:C 17 Jun 2024 14:00:11.614 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis-1 | 1:M 17 Jun 2024 14:00:11.614 * monotonic clock: POSIX clock_gettime
redis-1 | 1:M 17 Jun 2024 14:00:11.624 * Running mode=standalone, port=6379.
redis-1 | 1:M 17 Jun 2024 14:00:11.628 * Server initialized
redis-1 | 1:M 17 Jun 2024 14:00:11.637 * Ready to accept connections tcp
postgres-1 | The files belonging to this database system will be owned by user "postgres".
postgres-1 | This user must also own the server process.
postgres-1 |
postgres-1 | The database cluster will be initialized with locale "en_US.utf8".
postgres-1 | The default database encoding has accordingly been set to "UTF8".
postgres-1 | The default text search configuration will be set to "english".
postgres-1 |
postgres-1 | Data page checksums are disabled.
postgres-1 |
postgres-1 | fixing permissions on existing directory /var/lib/postgresql/data ... ok
postgres-1 | creating subdirectories ... ok
postgres-1 | selecting dynamic shared memory implementation ... posix
postgres-1 | selecting default max_connections ... 100
postgres-1 | selecting default shared_buffers ... 128MB
postgres-1 | selecting default time zone ... Etc/UTC
postgres-1 | creating configuration files ... ok
postgres-1 | running bootstrap script ... ok
yarn run v1.22.22
yarn run v1.22.22
$ ./run yarn:build
$ ./run yarn:build:css
js-1 | ✘ [ERROR] Failed to write to output file: open /app/app/assets/builds/application.js: permission denied
js-1 |
js-1 | 1 error
js-1 |
js-1 | app/assets/builds/application.js 143.4kb
js-1 |
web-1 | cp: cannot create regular file '/app/public/502.html': Permission denied
web-1 | cp: cannot create regular file '/app/public/android-chrome-192x192.png': Permission denied
web-1 | cp: cannot create regular file '/app/public/android-chrome-512x512.png': Permission denied
web-1 | cp: cannot create regular file '/app/public/apple-touch-icon.png': Permission denied
web-1 | cp: cannot create directory '/app/public/assets': Permission denied
web-1 | cp: cannot create regular file '/app/public/browserconfig.xml': Permission denied
web-1 | cp: cannot create regular file '/app/public/favicon-16x16.png': Permission denied
web-1 | cp: cannot create regular file '/app/public/favicon-32x32.png': Permission denied
web-1 | cp: cannot create regular file '/app/public/favicon.ico': Permission denied
web-1 | cp: cannot create regular file '/app/public/maintenance.html': Permission denied
web-1 | cp: cannot create regular file '/app/public/mstile-150x150.png': Permission denied
web-1 | cp: cannot create regular file '/app/public/robots.txt': Permission denied
web-1 | cp: cannot create regular file '/app/public/safari-pinned-tab.svg': Permission denied
web-1 | cp: cannot create regular file '/app/public/site.webmanifest': Permission denied
js-1 | node:child_process:929
js-1 | throw err;
js-1 | ^
js-1 |
js-1 | Error: Command failed: /node_modules/@esbuild/linux-x64/bin/esbuild app/javascript/application.js --outdir=app/assets/builds --bundle --minify
js-1 | at genericNodeError (node:internal/errors:984:15)
js-1 | at wrappedFn (node:internal/errors:538:14)
js-1 | at checkExecSyncError (node:child_process:890:11)
js-1 | at Object.execFileSync (node:child_process:926:15)
js-1 | at Object. (/node_modules/esbuild/bin/esbuild:219:28)
js-1 | at Module._compile (node:internal/modules/cjs/loader:1358:14)
js-1 | at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
js-1 | at Module.load (node:internal/modules/cjs/loader:1208:32)
js-1 | at Module._load (node:internal/modules/cjs/loader:1024:12)
js-1 | at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:174:12) {
js-1 | status: 1,
js-1 | signal: null,
js-1 | output: [ null, null, null ],
js-1 | pid: 26,
js-1 | stdout: null,
js-1 | stderr: null
js-1 | }
js-1 |
js-1 | Node.js v20.14.0
js-1 |
js-1 | Task completed in 0m1.845s
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
js-1 exited with code 1
web-1 exited with code 1

cable-1 | [1] Puma starting in cluster mode...
cable-1 | [1] * Puma version: 6.4.2 (ruby 3.3.2-p78) ("The Eagle of Durango")
cable-1 | [1] * Min threads: 1
cable-1 | [1] * Max threads: 1
cable-1 | [1] * Environment: production
cable-1 | [1] * Master PID: 1
cable-1 | [1] * Workers: 1
cable-1 | [1] * Restarts: (✔) hot (✖) phased
cable-1 | [1] * Preloading application
postgres-1 | performing post-bootstrap initialization ... ok
postgres-1 | syncing data to disk ... ok
postgres-1 |
postgres-1 | initdb: warning: enabling "trust" authentication for local connections
postgres-1 | initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.
postgres-1 |
postgres-1 | Success. You can now start the database server using:
postgres-1 |
postgres-1 | pg_ctl -D /var/lib/postgresql/data -l logfile start
postgres-1 |
postgres-1 | waiting for server to start....2024-06-17 14:00:21.385 UTC [47] LOG: starting PostgreSQL 16.3 (Debian 16.3-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
postgres-1 | 2024-06-17 14:00:21.390 UTC [47] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres-1 | 2024-06-17 14:00:21.423 UTC [50] LOG: database system was shut down at 2024-06-17 14:00:20 UTC
postgres-1 | 2024-06-17 14:00:21.460 UTC [47] LOG: database system is ready to accept connections
postgres-1 | done
postgres-1 | server started
postgres-1 | CREATE DATABASE
postgres-1 |
postgres-1 |
postgres-1 | /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
postgres-1 |
postgres-1 | 2024-06-17 14:00:22.713 UTC [47] LOG: received fast shutdown request
postgres-1 | waiting for server to shut down....2024-06-17 14:00:22.728 UTC [47] LOG: aborting any active transactions
postgres-1 | 2024-06-17 14:00:22.779 UTC [47] LOG: background worker "logical replication launcher" (PID 53) exited with exit code 1
postgres-1 | 2024-06-17 14:00:22.810 UTC [48] LOG: shutting down
postgres-1 | 2024-06-17 14:00:22.817 UTC [48] LOG: checkpoint starting: shutdown immediate
postgres-1 | 2024-06-17 14:00:23.003 UTC [48] LOG: checkpoint complete: wrote 922 buffers (5.6%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.097 s, sync=0.065 s, total=0.192 s; sync files=301, longest=0.014 s, average=0.001 s; distance=4255 kB, estimate=4255 kB; lsn=0/1912048, redo lsn=0/1912048
postgres-1 | 2024-06-17 14:00:23.060 UTC [47] LOG: database system is shut down
postgres-1 | done
postgres-1 | server stopped
postgres-1 |
postgres-1 | PostgreSQL init process complete; ready for start up.
postgres-1 |
postgres-1 | 2024-06-17 14:00:23.315 UTC [1] LOG: starting PostgreSQL 16.3 (Debian 16.3-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
postgres-1 | 2024-06-17 14:00:23.316 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres-1 | 2024-06-17 14:00:23.318 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres-1 | 2024-06-17 14:00:23.327 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres-1 | 2024-06-17 14:00:23.347 UTC [63] LOG: database system was shut down at 2024-06-17 14:00:22 UTC
postgres-1 | 2024-06-17 14:00:23.403 UTC [1] LOG: database system is ready to accept connections
css-1 |
css-1 | Rebuilding...
css-1 | Error: EACCES: permission denied, open './app/assets/builds/application.css'
css-1 | at async open (node:internal/fs/promises:636:25)
css-1 | at async Object.writeFile (node:internal/fs/promises:1216:14)
css-1 | at async outputFile (/node_modules/tailwindcss/lib/cli/build/utils.js:87:5)
css-1 | at async Promise.all (index 0)
css-1 | at async build (/node_modules/tailwindcss/lib/cli/build/index.js:49:9) {
css-1 | errno: -13,
css-1 | code: 'EACCES',
css-1 | syscall: 'open',
css-1 | path: './app/assets/builds/application.css'
css-1 | }
css-1 |
css-1 | Task completed in 0m13.928s
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
css-1 exited with code 1

worker-1 | 2024-06-17T14:00:38.916Z pid=1 tid=2u9 INFO: Booted Rails 7.1.3.4 application in production environment
worker-1 | 2024-06-17T14:00:38.937Z pid=1 tid=2u9 INFO: Running in ruby 3.3.2 (2024-05-30 revision e5a195edf6) +YJIT [x86_64-linux]
worker-1 | 2024-06-17T14:00:38.937Z pid=1 tid=2u9 INFO: See LICENSE and the LGPL-3.0 for licensing details.
worker-1 | 2024-06-17T14:00:38.937Z pid=1 tid=2u9 INFO: Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org
worker-1 | 2024-06-17T14:00:38.938Z pid=1 tid=2u9 INFO: Sidekiq 7.2.4 connecting to Redis with options {:size=>10, :pool_name=>"internal", :url=>"redis://redis:6379/1"}
cable-1 | [1] * Listening on http://0.0.0.0:28080
worker-1 | 2024-06-17T14:00:39.027Z pid=1 tid=2u9 INFO: Sidekiq 7.2.4 connecting to Redis with options {:size=>1, :pool_name=>"default", :url=>"redis://redis:6379/1"}
cable-1 | [1] Use Ctrl-C to stop
cable-1 | [1] ! WARNING: Detected running cluster mode with 1 worker.
cable-1 | [1] ! Running Puma in cluster mode with a single worker is often a misconfiguration.
cable-1 | [1] ! Consider running Puma in single-mode (workers = 0) in order to reduce memory overhead.
cable-1 | [1] ! Set the silence_single_worker_warning option to silence this warning message.
cable-1 | [1] - Worker 0 (PID: 10) booted in 0.05s, phase: 0
redis-1 | 1:M 17 Jun 2024 14:05:12.005 * 100 changes in 300 seconds. Saving...
redis-1 | 1:M 17 Jun 2024 14:05:12.007 * Background saving started by pid 18
redis-1 | 18:C 17 Jun 2024 14:05:12.020 * DB saved on disk
redis-1 | 18:C 17 Jun 2024 14:05:12.021 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB
redis-1 | 1:M 17 Jun 2024 14:05:12.109 * Background saving terminated with success
postgres-1 | 2024-06-17 14:05:23.406 UTC [61] LOG: checkpoint starting: time
postgres-1 | 2024-06-17 14:05:26.161 UTC [61] LOG: checkpoint complete: wrote 30 buffers (0.2%); 0 WAL file(s) added, 0 removed, 0 recycled; write=2.723 s, sync=0.007 s, total=2.755 s; sync files=11, longest=0.004 s, average=0.001 s; distance=132 kB, estimate=132 kB; lsn=0/19330F0, redo lsn=0/19330B8
redis-1 | 1:M 17 Jun 2024 14:10:13.011 * 100 changes in 300 seconds. Saving...
redis-1 | 1:M 17 Jun 2024 14:10:13.012 * Background saving started by pid 19
redis-1 | 19:C 17 Jun 2024 14:10:13.023 * DB saved on disk
redis-1 | 19:C 17 Jun 2024 14:10:13.024 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB
redis-1 | 1:M 17 Jun 2024 14:10:13.112 * Background saving terminated with success

Cannot connect to postgres without mapping port

Howdy, I'm a novice Docker user kludging my way through learning. Was very excited to discover this repo that features a clean implementation of Rails + Docker w/ best practices; thank you!

One issue I encountered what that I could not access/connect to my running Postgres container using the standard config in your docker-compose.yml file. However, once I manually mapped the port, everything worked fine.

Specifically, I had to add the following under the postgres service in docker-compose.yml:

ports:
  - 5432:5432

I assume your implementation works great for you out of the box yet not on my workstation (2021 M1 MacBook Pro). Any thoughts as to why I had to manually map the port in the config?

Yarn EROFS when adding modules

When attempting to add a module, I'm encountering a file permission error.

I can reproduce the error in a new app by cloning and composing:

git clone https://github.com/nickjj/docker-rails-example test_docker_yarn cd test_docker_yarn cp .env.example .env cp docker-compose.override.yml.example docker-compose.orverride.yml docker-compose up --build

Followed by:
yarn add any_module_here

Process halts with the following error:

error An unexpected error occurred: "EROFS: read-only file system, mkdir '/node_modules'".
yarn-error.log

I'm not sure if this is just my machine or something in the way Docker is composing the project?

use `run` instead of `exec` as `DC` for rails in run script?

I ran into a problem running rails generators with the run script via e.g. ./run rails g model MyModel my_attr. There was no output from the command and no changes were made.

Adding DC=run inside the rails function fixes it for me - it seems docker-compose exec won't work with the generators while docker-compose run does.

I'm not sure if this should be a default or not but thought I'd mention it in case anyone else runs into the problem.

Production sample?

This looks pretty cool, there are a lot of nuances which you seem to have considered and factored in which the typical "rails-quickstart" project ignores.

(1) Do you know has anyone used this setup in a production app, deployed on Heroku via good old git push (eg, not deployed via a docker container)? I ask because there seem to be a lot of online tales of woe around Heroku + deployment + Rails 6.1. (We consider Docker invaluable for local development, but not as suitable for production deployment on Heroku.)

(2) with your tech stack does rails scaffolding generate views that use the CSS framework you chose (Tailwind)? If not, do you know if that is possible and what steps would be needed to add that?

(3) have you considered a demo app - perhaps even hosted on Heroku - built on this stack with a model or two - that might "show off" (eg show working) some of the somewhat bleeding-edge incorporated elements (hotwire, actioncable, Stimulus) - which BTW might also make for an awesome video that might help drive some adoption of this carefully curated stack?

Add Redis password

This is not an issue, but it would be nice to get people thinking about security by adding authentication to the Redis container. This can be done easily through the compose/.env files and minimal changes to the application, Redis, and Sidekiq configs.

.env.example:
#export REDIS_URL=redis://redis:6379/1 #export REDIS_PASSWORD=password

docker-compose.yml:
services: redis: command: > --requirepass ${REDIS_PASSWORD:-password}

application.rb:
config.cache_store = :redis_cache_store, { url: ENV.fetch("REDIS_URL") { "redis://redis:6379/1" }, namespace: "cache", password: ENV.fetch("REDIS_PASSWORD") { "password" } }

redis.rb:
@redis ||= Redis.new(url: ENV.fetch("REDIS_URL") { "redis://redis:6379/1" }, password: ENV.fetch("REDIS_PASSWORD") { "password" })

sidekiq.rb:
sidekiq_config = { url: ENV.fetch("REDIS_URL") { "redis://redis:6379/1" }, password: ENV.fetch("REDIS_PASSWORD") { "password" } }

cable.yml:
default: &default password: "<%= ENV.fetch("REDIS_PASSWORD") { "password"} %>"

Even though ACLs are the preferred method for authentication in Redis 6+, best practice should probably be to use some form of authentication, even in development.

WARN: Unresolved or ambiguous specs during Gem::Specification.reset:

Could anyone help us to fix this warning? No idea on how to do it.

worker_1     | WARN: Unresolved or ambiguous specs during Gem::Specification.reset:
worker_1     |       minitest (>= 5.1)
worker_1     |       Available/installed versions of this gem:
worker_1     |       - 5.14.3
worker_1     |       - 5.13.0
worker_1     |       racc (~> 1.4)
worker_1     |       Available/installed versions of this gem:
worker_1     |       - 1.5.2
worker_1     |       - 1.4.16
worker_1     |       rake (>= 0.8.7)
worker_1     |       Available/installed versions of this gem:
worker_1     |       - 13.0.3
worker_1     |       - 13.0.1
worker_1     | WARN: Clearing out unresolved specs. Try 'gem cleanup <gem>'
worker_1     | Please report a bug if this causes problems.

How to sync a clone of this repo after changing the name and adding more code.

I have tried to add this repo as an upstream to my clone of it and merge the main branch, but after changing the name for the project and adding some code it's becoming hard to solve all the conflicts there.
Has anyone lived this pain?
Is there any way to make this possible without having too many conflicts?
Is there any other way to keep in sync?

Thanks.

Permission Denied @dir_s_mkdir - /app/...

First things first, great project!

I tried to run it on an digital ocean vm with ubuntu 20.04 and docker 19.03.12 and I got this error when running the web service:

 => Booting Puma
web_1       | => Rails 6.1.3.2 application starting in development 
web_1       | => Run `bin/rails server --help` for more startup options
web_1       | Exiting
web_1       | /usr/local/lib/ruby/3.0.0/fileutils.rb:253:in `mkdir': Permission denied @ dir_s_mkdir - /app/tmp/cache (Errno::EACCES)

I tried to add a chmod to the Dockerfile:

...
RUN mkdir /app
RUN chmod 777 /app
...

among other things, but without success. Do you guys know what could be happening? Everything works normally on my local machine (ubuntu 20.04 and Docker 20.10.7). I tried to use the same version on the digital ocean vm, but without success too.

Anyway, great project! Thanks

Add Postgres port forwarding

Add Postgres port forwarding to be able to connect to the development db using a GUI.

eg:

.env

export POSTGRES_PORT_FORWARD=54320

docker-compose.yml

services:
  postgres:
    ...
    ports:
      - "${POSTGRES_PORT_FORWARD:-54320}:${POSTGRES_PORT:-5432}"

How to run system tests

Hi, nice work that you have done, but I think you have not set an example for running system tests

Cable - Operation not permitted - bs_fetch:atomic_write_cache_file:chmod (Errno::EPERM)

Hi Nick, first of all, thank you so much for sharing this excellent piece of code.

I am testing it, a fresh install, and during the build I'am getting an error in the Cable part of the docker-compose.

"Operation not permitted - bs_fetch:atomic_write_cache_file:chmod (Errno::EPERM)"

Captura de pantalla 2021-01-09 a las 4 52 51

Any idea on what is going on? I believe Cable is looking for a temporary directory but cannot find exactly which is and why can't be used.

Set env variables via ./run

I can't really see a way to do do something as:

./run cmd SOME_ENV_TO_SET=Y bin/rails db:seed

Where SOME_ENV_TO_SET is something for deciding when to do one or the other for a given environment. db:seed is just an example for what im working on right now for seeding development machines once in a blue moon.

I dont wish to add them to .env file as it is really one time operation for most machines.

I have considered adding to ./run and call "_dc -e ..." is that the preferred way to add such a feature?

Unable to establish DB connection from web server

I'm trying to fire up the base example from the readme. All the containers build and seemingly start correctly. However the web server returns ConnectionNotEstablished when trying to connect to postgres and it looks like the workers can't connect to redis (I haven't looked in to that as postgres really blocks anything.)

I can ping and telnet to the postgres server pg port from the host machine. It looks like ping isn't installed on any of the containers so I can't test directly from the webserver.

Any ideas or pointers would be GREATLY appreciated. I'd love to move a bunch of my rails apps over to docker!

Incoming pile of version & environment data - please let me know if anything else would be helpful

app is top of main from yesterday
host is ubuntu 20
I have a few other dockers running with networking but nothing seems to collide with the hellorails_default

jchurch@ubuntu:~/hellorails$ docker network ls
NETWORK ID     NAME                      DRIVER    SCOPE
1565655ad8a9   bridge                    bridge    local
36869fcbef8f   hellorails_default        bridge    local
d16411050e7a   host                      host      local
1052fedf8e1e   myapp_default             bridge    local
dabb136ba7eb   none                      null      local
689c8988682a   psychic-pancake_default   bridge    local
jchurch@ubuntu:~/hellorails$ docker ps
CONTAINER ID   IMAGE                                   COMMAND                  CREATED          STATUS                    PORTS                                                     NAMES
b4bd28991a21   hellorails-js                           "yarn build"             46 minutes ago   Up 46 minutes                                                                       hellorails-js-1
e607f3b1f559   hellorails-cable                        "puma -p 28080 cable…"   46 minutes ago   Up 46 minutes             8000/tcp, 0.0.0.0:28080->28080/tcp, :::28080->28080/tcp   hellorails-cable-1
ddb52e2655f6   hellorails-web                          "/app/bin/docker-ent…"   46 minutes ago   Up 46 minutes (healthy)   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp                 hellorails-web-1
f9bb4938ab11   hellorails-css                          "yarn build:css"         46 minutes ago   Up 46 minutes                                                                       hellorails-css-1
28a2282b0a54   postgres:15.4-bookworm                  "docker-entrypoint.s…"   15 hours ago     Up 46 minutes             5432/tcp                                                  hellorails-postgres-1
38517dca762e   redis:7.0.12-bookworm                   "docker-entrypoint.s…"   15 hours ago     Up 46 minutes             6379/tcp                                                  hellorails-redis-1
092da6e0dbea   ghcr.io/beeper/linkedin:latest          "/opt/linkedin-matri…"   7 days ago       Up 46 minutes             0.0.0.0:29329->29329/tcp, :::29329->29329/tcp             modest_moser
46ac294cb409   dock.mau.dev/mautrix/whatsapp:latest    "/docker-run.sh"         7 weeks ago      Up 46 minutes             0.0.0.0:29318->29318/tcp, :::29318->29318/tcp             fervent_yalow


jchurch@ubuntu:~/hellorails$ docker compose version
Docker Compose version v2.20.2-desktop.1
jchurch@ubuntu:~/hellorails$ docker network inspect hellorails_default
[
    {
        "Name": "hellorails_default",
        "Id": "36869fcbef8fb291c6a99063f612ddae8ae48f2f2e756de0ab7360e189a89d09",
        "Created": "2023-09-12T20:30:44.800489461-04:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.20.0.0/16",
                    "Gateway": "172.20.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "28a2282b0a544a213285da101e09f0888f852fb52ede1852007f232b7556b70b": {
                "Name": "hellorails-postgres-1",
                "EndpointID": "fe05c4ad329531fea86ddda820e79b9d4eb6498631deb34b95a8905864b74684",
                "MacAddress": "02:42:ac:14:00:04",
                "IPv4Address": "172.20.0.4/16",
                "IPv6Address": ""
            },
            "38517dca762ea5ffdfea7c7b69cae7306a25bb88b619d4ba1d9e0a58ebb97667": {
                "Name": "hellorails-redis-1",
                "EndpointID": "ec6ac6039498873453ce45ee2e7ee012949ccdd7a2707c1ac3fb619502a163e3",
                "MacAddress": "02:42:ac:14:00:03",
                "IPv4Address": "172.20.0.3/16",
                "IPv6Address": ""
            },
            "b4bd28991a21652b934ad85e67f32d314b95133a57d30e132b825743504c65ad": {
                "Name": "hellorails-js-1",
                "EndpointID": "d30e5252656e8d5ae9a3b00082f1c12b451c0da801c0d24edb4156902390c34a",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            },
            "ddb52e2655f6c402fb921460cca3b893d6d8e77b131a2cb8abdd32ca507588b8": {
                "Name": "hellorails-web-1",
                "EndpointID": "939bab609d4ee25d3874750fab8191cf78e5dbdee7ffaa49611c78ee8d7aebb2",
                "MacAddress": "02:42:ac:14:00:06",
                "IPv4Address": "172.20.0.6/16",
                "IPv6Address": ""
            },
            "e607f3b1f55997d58fb4942f99415901172f26149c9cbcf8e6a1e5539ba72a06": {
                "Name": "hellorails-cable-1",
                "EndpointID": "879ca6c02f4a204cdc58ec9eb2a0fd9626e5ea72382ee0932d562c93029f1282",
                "MacAddress": "02:42:ac:14:00:07",
                "IPv4Address": "172.20.0.7/16",
                "IPv6Address": ""
            },
            "f9bb4938ab11986028861fc22de542910936e57132bc3ef59a6d0e2b5290f729": {
                "Name": "hellorails-css-1",
                "EndpointID": "dde1d71cfda6bb40361b50cdcc690bf892b5464b566b7f2c1d68c6452ee76775",
                "MacAddress": "02:42:ac:14:00:05",
                "IPv4Address": "172.20.0.5/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "default",
            "com.docker.compose.project": "hellorails",
            "com.docker.compose.version": "2.20.2"
        }
    }
]
jchurch@ubuntu:~/hellorails$ telnet 172.20.0.4 5432
Trying 172.20.0.4...
Connected to 172.20.0.4.
Escape character is '^]'.
^CConnection closed by foreign host.

app build/start output

jchurch@ubuntu:~$ cd hellorails/
direnv: export +COMPOSE_PROFILES +COMPOSE_PROJECT_NAME +DOCKER_BUILDKIT +DOCKER_CABLE_PORT_FORWARD +DOCKER_RESTART_POLICY +DOCKER_WEB_HEALTHCHECK_TEST +DOCKER_WEB_PORT_FORWARD +DOCKER_WEB_VOLUME +NODE_ENV +POSTGRES_PASSWORD +POSTGRES_USER +RAILS_ENV +RAILS_MAX_THREADS +SECRET_KEY_BASE +WEB_CONCURRENCY
jchurch@ubuntu:~/hellorails$ docker compose up --build
[+] Building 1.3s (38/67)                                                                                                                                                      docker:default
 => [worker internal] load build definition from Dockerfile                                                                                                                              0.0s
 => => transferring dockerfile: 32B                                                                                                                                                      0.0s
 => [web internal] load build definition from Dockerfile                                                                                                                                 0.0s
 => => transferring dockerfile: 32B                                                                                                                                                      0.0s
 => [js internal] load build definition from Dockerfile                                                                                                                                  0.0s
 => => transferring dockerfile: 32B                                                                                                                                                      0.0s
 => [css internal] load build definition from Dockerfile                                                                                                                                 0.0s
 => => transferring dockerfile: 32B                                                                                                                                                      0.0s
 => [worker internal] load .dockerignore                                                                                                                                                 0.0s
 => => transferring context: 35B                                                                                                                                                         0.0s
 => [cable internal] load build definition from Dockerfile                                                                                                                               0.0s
 => => transferring dockerfile: 32B                                                                                                                                                      0.0s
 => [web internal] load .dockerignore                                                                                                                                                    0.0s
 => => transferring context: 35B                                                                                                                                                         0.0s
 => [js internal] load .dockerignore                                                                                                                                                     0.0s
 => => transferring context: 35B                                                                                                                                                         0.0s
 => [css internal] load .dockerignore                                                                                                                                                    0.0s
 => => transferring context: 35B                                                                                                                                                         0.0s
 => [web internal] load metadata for docker.io/library/ruby:3.2.2-slim-bookworm                                                                                                          1.0s
 => [cable internal] load .dockerignore                                                                                                                                                  0.0s
 => => transferring context: 35B                                                                                                                                                         0.0s
 => [worker auth] library/ruby:pull token for registry-1.docker.io                                                                                                                       0.0s
 => [cable assets 1/9] FROM docker.io/library/ruby:3.2.2-slim-bookworm@sha256:b86f08332ea5f9b73c427018f28af83628c139567cc72823270cac6ab056c4dc                                           0.0s
 => [web internal] load build context                                                                                                                                                    0.1s
 => => transferring context: 65.29kB                                                                                                                                                     0.0s
 => [css internal] load build context                                                                                                                                                    0.0s
 => => transferring context: 65.29kB                                                                                                                                                     0.0s
 => [js internal] load build context                                                                                                                                                     0.0s
 => => transferring context: 65.29kB                                                                                                                                                     0.0s
 => [cable internal] load build context                                                                                                                                                  0.1s
 => => transferring context: 65.29kB                                                                                                                                                     0.0s
 => [worker internal] load build context                                                                                                                                                 0.1s
 => => transferring context: 65.29kB                                                                                                                                                     0.0s
 => CACHED [web assets 2/9] WORKDIR /app                                                                                                                                                 0.0s
 => CACHED [web assets 3/9] RUN bash -c "set -o pipefail && apt-get update   && apt-get install -y --no-install-recommends build-essential curl git libpq-dev   && curl -fsSL https://d  0.0s
 => CACHED [js assets 4/9] COPY --chown=ruby:ruby Gemfile* ./                                                                                                                            0.0s
 => CACHED [js assets 5/9] RUN bundle install                                                                                                                                            0.0s
 => CACHED [js assets 6/9] COPY --chown=ruby:ruby package.json *yarn* ./                                                                                                                 0.0s
 => CACHED [js assets 7/9] RUN yarn install                                                                                                                                              0.0s
 => CACHED [js assets 8/9] COPY --chown=ruby:ruby . .                                                                                                                                    0.0s
 => CACHED [js assets 9/9] RUN if [ "development" != "development" ]; then   SECRET_KEY_BASE=dummyvalue rails assets:precompile; fi                                                      0.0s
 => [css] exporting to image                                                                                                                                                             0.1s
 => => exporting layers                                                                                                                                                                  0.0s
 => => writing image sha256:1c048854f8388e92eaf65eef14095e6d0c752bb8620b230a52e00d4d7f63bbad                                                                                             0.0s
 => => naming to docker.io/library/hellorails-js                                                                                                                                         0.0s
 => => writing image sha256:c9569cd0330a46c310034f2da1bc24343e685a4b442ef0fc14da8a68534b5284                                                                                             0.0s
 => => naming to docker.io/library/hellorails-web                                                                                                                                        0.0s
 => => writing image sha256:50c83f892ac842aab7f8f8eaa5d4e84b4153c0b7e301fc4d5eb70d0dc69a6c4d                                                                                             0.0s
 => => naming to docker.io/library/hellorails-worker                                                                                                                                     0.0s
 => => writing image sha256:2207df3fa1bce63f81b545fb54b9ea3526fe24ca7ccbeab4b6c24af879e5909f                                                                                             0.0s
 => => naming to docker.io/library/hellorails-cable                                                                                                                                      0.0s
 => => writing image sha256:1e6359cab03064720efa15e9d91711f0f7c81a5b9fb3ebcc67967256bd400a12                                                                                             0.0s
 => => naming to docker.io/library/hellorails-css                                                                                                                                        0.0s
 => CACHED [web app 3/8] RUN apt-get update   && apt-get install -y --no-install-recommends build-essential curl libpq-dev   && rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/m  0.0s
 => CACHED [web app 4/8] COPY --chown=ruby:ruby bin/ ./bin                                                                                                                               0.0s
 => CACHED [web app 5/8] RUN chmod 0755 bin/*                                                                                                                                            0.0s
 => CACHED [web assets 4/9] COPY --chown=ruby:ruby Gemfile* ./                                                                                                                           0.0s
 => CACHED [web assets 5/9] RUN bundle install                                                                                                                                           0.0s
 => CACHED [web assets 6/9] COPY --chown=ruby:ruby package.json *yarn* ./                                                                                                                0.0s
 => CACHED [web assets 7/9] RUN yarn install                                                                                                                                             0.0s
 => CACHED [web assets 8/9] COPY --chown=ruby:ruby . .                                                                                                                                   0.0s
 => CACHED [web assets 9/9] RUN if [ "development" != "development" ]; then   SECRET_KEY_BASE=dummyvalue rails assets:precompile; fi                                                     0.0s
 => CACHED [web app 6/8] COPY --chown=ruby:ruby --from=assets /usr/local/bundle /usr/local/bundle                                                                                        0.0s
 => CACHED [web app 7/8] COPY --chown=ruby:ruby --from=assets /app/public /public                                                                                                        0.0s
 => CACHED [web app 8/8] COPY --chown=ruby:ruby . .                                                                                                                                      0.0s
[+] Running 7/7
 ✔ Container hellorails-redis-1     Created                                                                                                                                              0.0s 
 ✔ Container hellorails-css-1       Recreated                                                                                                                                            0.1s 
 ✔ Container hellorails-js-1        Recreated                                                                                                                                            0.1s 
 ✔ Container hellorails-postgres-1  Created                                                                                                                                              0.0s 
 ✔ Container hellorails-cable-1     Recreated                                                                                                                                            0.1s 
 ✔ Container hellorails-web-1       Recreated                                                                                                                                            0.1s 
 ✔ Container hellorails-worker-1    Recreated                                                                                                                                            0.1s 
Attaching to hellorails-cable-1, hellorails-css-1, hellorails-js-1, hellorails-postgres-1, hellorails-redis-1, hellorails-web-1, hellorails-worker-1
hellorails-redis-1     | 1:C 13 Sep 2023 15:02:32.310 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
hellorails-redis-1     | 1:C 13 Sep 2023 15:02:32.310 # Redis version=7.0.12, bits=64, commit=00000000, modified=0, pid=1, just started
hellorails-redis-1     | 1:C 13 Sep 2023 15:02:32.310 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
hellorails-redis-1     | 1:M 13 Sep 2023 15:02:32.310 * Increased maximum number of open files to 10032 (it was originally set to 1024).
hellorails-redis-1     | 1:M 13 Sep 2023 15:02:32.310 * monotonic clock: POSIX clock_gettime
hellorails-redis-1     | 1:M 13 Sep 2023 15:02:32.311 * Running mode=standalone, port=6379.
hellorails-redis-1     | 1:M 13 Sep 2023 15:02:32.311 # Server initialized
hellorails-redis-1     | 1:M 13 Sep 2023 15:02:32.311 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
hellorails-redis-1     | 1:M 13 Sep 2023 15:02:32.312 * Loading RDB produced by version 7.0.12
hellorails-redis-1     | 1:M 13 Sep 2023 15:02:32.312 * RDB age 45 seconds
hellorails-redis-1     | 1:M 13 Sep 2023 15:02:32.312 * RDB memory usage when created 0.82 Mb
hellorails-redis-1     | 1:M 13 Sep 2023 15:02:32.312 * Done loading RDB, keys loaded: 0, keys expired: 0.
hellorails-redis-1     | 1:M 13 Sep 2023 15:02:32.312 * DB loaded from disk: 0.000 seconds
hellorails-redis-1     | 1:M 13 Sep 2023 15:02:32.312 * Ready to accept connections
hellorails-postgres-1  | 
hellorails-postgres-1  | PostgreSQL Database directory appears to contain a database; Skipping initialization
hellorails-postgres-1  | 
hellorails-postgres-1  | 
hellorails-postgres-1  | 2023-09-13 15:02:32.561 UTC [1] LOG:  starting PostgreSQL 15.4 (Debian 15.4-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
hellorails-postgres-1  | 2023-09-13 15:02:32.990 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
hellorails-postgres-1  | 2023-09-13 15:02:32.990 UTC [1] LOG:  listening on IPv6 address "::", port 5432

yarn run v1.22.19      | 
hellorails-postgres-1  | 2023-09-13 15:02:32.993 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
hellorails-postgres-1  | 2023-09-13 15:02:32.997 UTC [28] LOG:  database system was shut down at 2023-09-13 15:01:47 UTC
yarn run v1.22.19
hellorails-postgres-1  | 2023-09-13 15:02:33.030 UTC [1] LOG:  database system is ready to accept connections

hellorails-js-1        | 
hellorails-js-1        | $ ./run yarn:build
hellorails-js-1        | 
$ ./run yarn:build:css
hellorails-js-1        | [watch] build finished, watching for changes...
hellorails-js-1        | 
hellorails-css-1       | 
hellorails-css-1       | Rebuilding...
hellorails-cable-1     | [1] Puma starting in cluster mode...
hellorails-cable-1     | [1] * Puma version: 6.3.1 (ruby 3.2.2-p53) ("Mugi No Toki Itaru")
hellorails-cable-1     | [1] *  Min threads: 1
hellorails-cable-1     | [1] *  Max threads: 1
hellorails-cable-1     | [1] *  Environment: development
hellorails-cable-1     | [1] *   Master PID: 1
hellorails-cable-1     | [1] *      Workers: 1
hellorails-cable-1     | [1] *     Restarts: (✔) hot (✖) phased
hellorails-cable-1     | [1] * Preloading application
hellorails-css-1       | 
hellorails-css-1       | Done in 407ms.
hellorails-web-1       | => Booting Puma
hellorails-web-1       | => Rails 7.0.7.2 application starting in development 
hellorails-web-1       | => Run `bin/rails server --help` for more startup options
hellorails-web-1       | [1] Puma starting in cluster mode...
hellorails-web-1       | 
hellorails-web-1       | [1] * Puma version: 6.3.1 (ruby 3.2.2-p53) ("Mugi No Toki Itaru")
hellorails-web-1       | [1] *  Min threads: 1
hellorails-web-1       | [1] *  Max threads: 1
hellorails-web-1       | [1] *  Environment: development
hellorails-web-1       | [1] *   Master PID: 1
hellorails-web-1       | [1] *      Workers: 1
hellorails-web-1       | [1] *     Restarts: (✔) hot (✖) phased
hellorails-web-1       | [1] * Preloading application
hellorails-web-1       | [1] * Listening on http://0.0.0.0:8000
hellorails-web-1       | [1] Use Ctrl-C to stop
hellorails-web-1       | [1] ! WARNING: Detected running cluster mode with 1 worker.
hellorails-web-1       | [1] ! Running Puma in cluster mode with a single worker is often a misconfiguration.
hellorails-web-1       | [1] ! Consider running Puma in single-mode (workers = 0) in order to reduce memory overhead.
hellorails-web-1       | [1] ! Set the `silence_single_worker_warning` option to silence this warning message.
hellorails-web-1       | [1] - Worker 0 (PID: 10) booted in 0.0s, phase: 0
hellorails-worker-1    | 
hellorails-worker-1    | 
hellorails-worker-1    |                m,
hellorails-worker-1    |                `$b
hellorails-worker-1    |           .ss,  $$:         .,d$
hellorails-worker-1    |           `$$P,d$P'    .,md$P"'
hellorails-worker-1    |            ,$$$$$b/md$$$P^'
hellorails-worker-1    |          .d$$$$$$/$$$P'
hellorails-worker-1    |          $$^' `"/$$$'       ____  _     _      _    _
hellorails-worker-1    |          $:    ',$$:       / ___|(_) __| | ___| | _(_) __ _
hellorails-worker-1    |          `b     :$$        \___ \| |/ _` |/ _ \ |/ / |/ _` |
hellorails-worker-1    |                 $$:         ___) | | (_| |  __/   <| | (_| |
hellorails-worker-1    |                 $$         |____/|_|\__,_|\___|_|\_\_|\__, |
hellorails-worker-1    |               .d$$                                       |_|
hellorails-worker-1    |       
hellorails-worker-1    | 
hellorails-worker-1    | 2023-09-13T15:02:34.930Z pid=1 tid=2pt INFO: Booted Rails 7.0.7.2 application in development environment
hellorails-worker-1    | 2023-09-13T15:02:34.931Z pid=1 tid=2pt INFO: Running in ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]
hellorails-worker-1    | 2023-09-13T15:02:34.931Z pid=1 tid=2pt INFO: See LICENSE and the LGPL-3.0 for licensing details.
hellorails-worker-1    | 2023-09-13T15:02:34.931Z pid=1 tid=2pt INFO: Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org
hellorails-worker-1    | 2023-09-13T15:02:34.931Z pid=1 tid=2pt INFO: Sidekiq 7.1.2 connecting to Redis with options {:size=>10, :pool_name=>"internal", :url=>"redis://redis:6379/1"}
hellorails-cable-1     | [1] * Listening on http://0.0.0.0:28080
hellorails-cable-1     | [1] ! WARNING: Detected 2 Thread(s) started in app boot:
hellorails-cable-1     | [1] ! #<Thread:0x00007f0df71ef558@DEBUGGER__::SESSION@server /usr/local/bundle/gems/debug-1.8.0/lib/debug/session.rb:179 sleep_forever> - <internal:thread_sync>:18:in `pop'
hellorails-cable-1     | [1] ! #<Rack::MiniProfiler::FileStore::CacheCleanupThread:0x00007f0df6324230 /usr/local/bundle/gems/rack-mini-profiler-3.1.1/lib/mini_profiler/storage/file_store.rb:67 sleep> - /usr/local/bundle/gems/rack-mini-profiler-3.1.1/lib/mini_profiler/storage/file_store.rb:85:in `sleep'
hellorails-cable-1     | [1] Use Ctrl-C to stop
hellorails-cable-1     | [1] ! WARNING: Detected running cluster mode with 1 worker.
hellorails-cable-1     | [1] ! Running Puma in cluster mode with a single worker is often a misconfiguration.
hellorails-cable-1     | [1] ! Consider running Puma in single-mode (workers = 0) in order to reduce memory overhead.
hellorails-cable-1     | [1] ! Set the `silence_single_worker_warning` option to silence this warning message.
hellorails-cable-1     | [1] - Worker 0 (PID: 11) booted in 0.0s, phase: 0
hellorails-worker-1    | Connection timed out - user specified timeout
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/socket.rb:65:in `connect_internal'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/socket.rb:141:in `connect'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/socket.rb:645:in `block in tcp'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/socket.rb:231:in `each'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/socket.rb:231:in `foreach'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/socket.rb:635:in `tcp'
hellorails-worker-1    | /usr/local/bundle/gems/redis-client-0.16.0/lib/redis_client/ruby_connection.rb:117:in `connect'
hellorails-worker-1    | /usr/local/bundle/gems/redis-client-0.16.0/lib/redis_client/ruby_connection.rb:49:in `initialize'
hellorails-worker-1    | /usr/local/bundle/gems/redis-client-0.16.0/lib/redis_client.rb:684:in `new'
hellorails-worker-1    | /usr/local/bundle/gems/redis-client-0.16.0/lib/redis_client.rb:684:in `block in connect'
hellorails-worker-1    | /usr/local/bundle/gems/redis-client-0.16.0/lib/redis_client/middlewares.rb:12:in `connect'
hellorails-worker-1    | /usr/local/bundle/gems/redis-client-0.16.0/lib/redis_client.rb:683:in `connect'
hellorails-worker-1    | /usr/local/bundle/gems/redis-client-0.16.0/lib/redis_client.rb:670:in `raw_connection'
hellorails-worker-1    | /usr/local/bundle/gems/redis-client-0.16.0/lib/redis_client.rb:637:in `ensure_connected'
hellorails-worker-1    | /usr/local/bundle/gems/redis-client-0.16.0/lib/redis_client.rb:218:in `call'
hellorails-worker-1    | /usr/local/bundle/gems/redis-client-0.16.0/lib/redis_client/decorator.rb:26:in `call'
hellorails-worker-1    | /usr/local/bundle/gems/sidekiq-7.1.2/lib/sidekiq/config.rb:145:in `block in redis_info'
hellorails-worker-1    | /usr/local/bundle/gems/sidekiq-7.1.2/lib/sidekiq/config.rb:164:in `block in redis'
hellorails-worker-1    | /usr/local/bundle/gems/connection_pool-2.4.1/lib/connection_pool.rb:110:in `block (2 levels) in with'
hellorails-worker-1    | /usr/local/bundle/gems/connection_pool-2.4.1/lib/connection_pool.rb:109:in `handle_interrupt'
hellorails-worker-1    | /usr/local/bundle/gems/connection_pool-2.4.1/lib/connection_pool.rb:109:in `block in with'
hellorails-worker-1    | /usr/local/bundle/gems/connection_pool-2.4.1/lib/connection_pool.rb:106:in `handle_interrupt'
hellorails-worker-1    | /usr/local/bundle/gems/connection_pool-2.4.1/lib/connection_pool.rb:106:in `with'
hellorails-worker-1    | /usr/local/bundle/gems/sidekiq-7.1.2/lib/sidekiq/config.rb:161:in `redis'
hellorails-worker-1    | /usr/local/bundle/gems/sidekiq-7.1.2/lib/sidekiq/config.rb:144:in `redis_info'
hellorails-worker-1    | /usr/local/bundle/gems/sidekiq-7.1.2/lib/sidekiq/cli.rb:75:in `run'
hellorails-worker-1    | /usr/local/bundle/gems/sidekiq-7.1.2/bin/sidekiq:31:in `<top (required)>'
hellorails-worker-1    | /usr/local/bundle/bin/sidekiq:25:in `load'
hellorails-worker-1    | /usr/local/bundle/bin/sidekiq:25:in `<top (required)>'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/bundler/cli/exec.rb:58:in `load'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/bundler/cli/exec.rb:58:in `kernel_load'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/bundler/cli/exec.rb:23:in `run'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/bundler/cli.rb:492:in `exec'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/bundler/cli.rb:34:in `dispatch'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/bundler/cli.rb:28:in `start'
hellorails-worker-1    | /usr/local/lib/ruby/gems/3.2.0/gems/bundler-2.4.10/libexec/bundle:45:in `block in <top (required)>'
hellorails-worker-1    | /usr/local/lib/ruby/3.2.0/bundler/friendly_errors.rb:117:in `with_friendly_errors'
hellorails-worker-1    | /usr/local/lib/ruby/gems/3.2.0/gems/bundler-2.4.10/libexec/bundle:33:in `<top (required)>'
hellorails-worker-1    | /usr/local/bin/bundle:25:in `load'
hellorails-worker-1    | /usr/local/bin/bundle:25:in `<main>'
hellorails-worker-1 exited with code 1
hellorails-web-1       | Started GET "/" for 172.20.0.1 at 2023-09-13 15:02:45 +0000
hellorails-web-1       |   
hellorails-web-1       | ActiveRecord::ConnectionNotEstablished (connection to server at "172.20.0.4", port 5432 failed: Connection timed out
hellorails-web-1       | 	Is the server running on that host and accepting TCP/IP connections?
hellorails-web-1       | ):

esbuild not re-building css

Hi Nick,
Really great setup you have here. I've followed through your readme. In fact, I simply cloned and set up a sample project using your starter kit.
All the services are up and running as expected. The only issue is 'css' esbuild doesn't re-build when I make an update in the views folder or appplication.css file, as expected.

The 'js' watcher works as expected.
I'm sure it might be an issue with my setup.

I'm using a Mac Book Pro M1, with docker; Docker version 20.10.17, build 100c701

This may have nothing to do with your starter kit, and may be an issue with my setup, so I will appreciate any pointers on what to look at.
I did a fresh install using rails new myapp -j esbuild -c tailwind and run it without docker, and both watchers worked as expected, so I'm thinking this could be something related to Docker.

Anyway, thanks and hope you have some ideas

Unable to load application: RuntimeError: invalid bytecode

Great work on providing this dockerized rails template repo.

After running bin/rename-project myapp MyApp, then running docker-compose up --build, I got the following:

cable_1      | [1] ! Unable to load application: RuntimeError: invalid bytecode
cable_1      | /usr/local/bundle/gems/bootsnap-1.7.5/lib/bootsnap/compile_cache/iseq.rb:19:in `load_from_binary': invalid bytecode (RuntimeError)

Similarly, for "web", I'm seeing

web_1        | [WARNING] Could not load command "rails/commands/server/server_command". Error: invalid bytecode.
web_1        | /usr/local/bundle/gems/bootsnap-1.7.5/lib/bootsnap/compile_cache/iseq.rb:19:in `load_from_binary'

Does not build after utilizing rename command.

Changed the name to customize for project start and ran into the following errors when running docker compose up --build. I did test with the stock repo version of this project without changing anything and it fired right up. The following output is displayed when I try to run the initial command after running the rename script.

At first I thought maybe it was the short 4 character name I chose but even after trying with a longer name it still failed.

You can find the repo here.

track_my_job_apps-cable-1     | [1] * Puma version: 6.2.2 (ruby 3.2.2-p53) ("Speaking of Now")
track_my_job_apps-cable-1     | [1] *  Min threads: 1
track_my_job_apps-cable-1     | [1] *  Max threads: 1
track_my_job_apps-cable-1     | [1] *  Environment: development
track_my_job_apps-cable-1     | [1] *   Master PID: 1
track_my_job_apps-cable-1     | [1] *      Workers: 1
track_my_job_apps-cable-1     | [1] *     Restarts: (✔) hot (✖) phased
track_my_job_apps-cable-1     | [1] * Preloading application
track_my_job_apps-cable-1     | [1] ! Unable to load application: SyntaxError: /app/config/application.rb:9: class/module name must be CONSTANT
track_my_job_apps-cable-1     |   class Application < Rails::Application
track_my_job_apps-cable-1     |        ^~~~~~~~~~~~~~~~~
track_my_job_apps-cable-1     | 
track_my_job_apps-cable-1     | /app/config/environment.rb:2:in `require_relative': /app/config/application.rb:9: class/module name must be CONSTANT (SyntaxError)
track_my_job_apps-cable-1     |   class Application < Rails::Application
track_my_job_apps-cable-1     |        ^~~~~~~~~~~~~~~~~
track_my_job_apps-cable-1     | 
track_my_job_apps-cable-1     |         from /app/config/environment.rb:2:in `<top (required)>'
track_my_job_apps-cable-1     |         from cable/config.ru:3:in `require_relative'
track_my_job_apps-cable-1     |         from cable/config.ru:3:in `block in <main>'
track_my_job_apps-cable-1     |         from /usr/local/bundle/gems/rack-2.2.7/lib/rack/builder.rb:116:in `eval'
track_my_job_apps-cable-1     |         from /usr/local/bundle/gems/rack-2.2.7/lib/rack/builder.rb:116:in `new_from_string'
track_my_job_apps-cable-1     |         from /usr/local/bundle/gems/rack-2.2.7/lib/rack/builder.rb:105:in `load_file'
track_my_job_apps-cable-1     |         from /usr/local/bundle/gems/rack-2.2.7/lib/rack/builder.rb:66:in `parse_file'
track_my_job_apps-cable-1     |         from /usr/local/bundle/gems/puma-6.2.2/lib/puma/configuration.rb:366:in `load_rackup'
track_my_job_apps-cable-1     |         from /usr/local/bundle/gems/puma-6.2.2/lib/puma/configuration.rb:288:in `app'
track_my_job_apps-cable-1     |         from /usr/local/bundle/gems/puma-6.2.2/lib/puma/runner.rb:158:in `load_and_bind'
track_my_job_apps-cable-1     |         from /usr/local/bundle/gems/puma-6.2.2/lib/puma/cluster.rb:359:in `run'
track_my_job_apps-cable-1     |         from /usr/local/bundle/gems/puma-6.2.2/lib/puma/launcher.rb:194:in `run'
track_my_job_apps-cable-1     |         from /usr/local/bundle/gems/puma-6.2.2/lib/puma/cli.rb:75:in `run'
track_my_job_apps-cable-1     |         from /usr/local/bundle/gems/puma-6.2.2/bin/puma:10:in `<top (required)>'
track_my_job_apps-cable-1     |         from /usr/local/bundle/bin/puma:25:in `load'
track_my_job_apps-cable-1     |         from /usr/local/bundle/bin/puma:25:in `<main>'
track_my_job_apps-cable-1 exited with code 1
track_my_job_apps-worker-1    | bundler: failed to load command: sidekiq (/usr/local/bundle/bin/sidekiq)
track_my_job_apps-worker-1    | /app/config/environment.rb:2:in `require_relative': /app/config/application.rb:9: class/module name must be CONSTANT (SyntaxError)
track_my_job_apps-worker-1    |   class Application < Rails::Application
track_my_job_apps-worker-1    |        ^~~~~~~~~~~~~~~~~
track_my_job_apps-worker-1    | 
track_my_job_apps-worker-1    |         from /app/config/environment.rb:2:in `<top (required)>'
track_my_job_apps-worker-1    |         from <internal:/usr/local/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
track_my_job_apps-worker-1    |         from <internal:/usr/local/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
track_my_job_apps-worker-1    |         from /usr/local/bundle/gems/sidekiq-7.1.0/lib/sidekiq/cli.rb:302:in `boot_application'
track_my_job_apps-worker-1    |         from /usr/local/bundle/gems/sidekiq-7.1.0/lib/sidekiq/cli.rb:42:in `run'
track_my_job_apps-worker-1    |         from /usr/local/bundle/gems/sidekiq-7.1.0/bin/sidekiq:31:in `<top (required)>'
track_my_job_apps-worker-1    |         from /usr/local/bundle/bin/sidekiq:25:in `load'
track_my_job_apps-worker-1    |         from /usr/local/bundle/bin/sidekiq:25:in `<top (required)>'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/3.2.0/bundler/cli/exec.rb:58:in `load'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/3.2.0/bundler/cli/exec.rb:58:in `kernel_load'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/3.2.0/bundler/cli/exec.rb:23:in `run'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/3.2.0/bundler/cli.rb:492:in `exec'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/3.2.0/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/3.2.0/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/3.2.0/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/3.2.0/bundler/cli.rb:34:in `dispatch'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/3.2.0/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/3.2.0/bundler/cli.rb:28:in `start'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/gems/3.2.0/gems/bundler-2.4.10/libexec/bundle:45:in `block in <top (required)>'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/3.2.0/bundler/friendly_errors.rb:117:in `with_friendly_errors'
track_my_job_apps-worker-1    |         from /usr/local/lib/ruby/gems/3.2.0/gems/bundler-2.4.10/libexec/bundle:33:in `<top (required)>'
track_my_job_apps-worker-1    |         from /usr/local/bin/bundle:25:in `load'
track_my_job_apps-worker-1    |         from /usr/local/bin/bundle:25:in `<main>'
track_my_job_apps-worker-1 exited with code 1
track_my_job_apps-web-1       | <internal:/usr/local/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require': /app/config/application.rb:9: class/module name must be CONSTANT (SyntaxError)
track_my_job_apps-web-1       |   class Application < Rails::Application
track_my_job_apps-web-1       |        ^~~~~~~~~~~~~~~~~
track_my_job_apps-web-1       | 
track_my_job_apps-web-1       |         from <internal:/usr/local/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
track_my_job_apps-web-1       |         from /usr/local/bundle/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
track_my_job_apps-web-1       |         from /usr/local/bundle/gems/railties-7.0.4.3/lib/rails/commands/server/server_command.rb:137:in `block in perform'
track_my_job_apps-web-1       |         from <internal:kernel>:90:in `tap'
track_my_job_apps-web-1       |         from /usr/local/bundle/gems/railties-7.0.4.3/lib/rails/commands/server/server_command.rb:134:in `perform'
track_my_job_apps-web-1       |         from /usr/local/bundle/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
track_my_job_apps-web-1       |         from /usr/local/bundle/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
track_my_job_apps-web-1       |         from /usr/local/bundle/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
track_my_job_apps-web-1       |         from /usr/local/bundle/gems/railties-7.0.4.3/lib/rails/command/base.rb:87:in `perform'
track_my_job_apps-web-1       |         from /usr/local/bundle/gems/railties-7.0.4.3/lib/rails/command.rb:48:in `invoke'
track_my_job_apps-web-1       |         from /usr/local/bundle/gems/railties-7.0.4.3/lib/rails/commands.rb:18:in `<main>'
track_my_job_apps-web-1       |         from <internal:/usr/local/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
track_my_job_apps-web-1       |         from <internal:/usr/local/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
track_my_job_apps-web-1       |         from /usr/local/bundle/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
track_my_job_apps-web-1       |         from bin/rails:4:in `<main>'
track_my_job_apps-web-1 exited with code 1```

Fix bundle install running twice when you change your Gemfile

This stems from having to generate webpacker packs for our test environment which means our webpacker image needs the complete Rails app available since the tests themselves end up running in the webpacker container. That's why it runs twice. Once for that and then again for the regular web image.

I know this kind of stinks because running bundle install takes a long time with Docker since if you change 1 dependency all dependencies need to be re-installed since that's how Docker layers work, and with this current set up we get dinged twice.

If we don't use a multi-stage build then our final Docker image is going to be over double in size since it'll include the entire Node runtime + all of the package.json libraries which isn't good.

Also we would still get hit with other delays, because if everything is in 1 image we have to individually run yarn install and bundle install, which means if you did yarn first it would then invalidate Docker's cache for bundle which means every time we change our package.json file our gems would get re-installed too. So moving to 1 image isn't ideal either.

I'm open for ideas on how to solve this.

Sidekiq fails to start when RAILS_ENV=production is set after upgrading to Rails 7 and using turbo-rails-1.0.0

Edit: The scope of this issue has changed to affect every Active Job running through Sidekiq and it also affects all environments. The first reply to this issue has more details. I left the original issue here for extra context which is still worth reading.

Sidekiq starts successfully with RAILS_ENV=development, but fails to start with RAILS_ENV=production.

Here's the stack trace:

worker_1    | 2021-12-18T15:43:09.829Z pid=1 tid=2ut INFO: Booting Sidekiq 6.3.1 with redis options {:url=>"redis://redis:6379/1"}
worker_1    | /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/loader/helpers.rb:95:in `require': cannot load such file -- /usr/local/bundle/gems/turbo-rails-1.0.0/app/channels/turbo/streams (LoadError)
worker_1    |   from /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/loader/helpers.rb:95:in `const_get'
worker_1    |   from /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/loader/helpers.rb:95:in `cget'
worker_1    |   from /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/loader.rb:239:in `block (2 levels) in eager_load'
worker_1    |   from /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/loader/helpers.rb:26:in `block in ls'
worker_1    |   from /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/loader/helpers.rb:18:in `each_child'
worker_1    |   from /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/loader/helpers.rb:18:in `ls'
worker_1    |   from /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/loader.rb:227:in `block in eager_load'
worker_1    |   from /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/loader.rb:212:in `synchronize'
worker_1    |   from /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/loader.rb:212:in `eager_load'
worker_1    |   from /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/loader.rb:312:in `each'
worker_1    |   from /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/loader.rb:312:in `eager_load_all'
worker_1    |   from /usr/local/bundle/gems/railties-7.0.0/lib/rails/application/finisher.rb:79:in `block in <module:Finisher>'
worker_1    |   from /usr/local/bundle/gems/railties-7.0.0/lib/rails/initializable.rb:32:in `instance_exec'
worker_1    |   from /usr/local/bundle/gems/railties-7.0.0/lib/rails/initializable.rb:32:in `run'
worker_1    |   from /usr/local/bundle/gems/railties-7.0.0/lib/rails/initializable.rb:61:in `block in run_initializers'
worker_1    |   from /usr/local/lib/ruby/3.0.0/tsort.rb:228:in `block in tsort_each'
worker_1    |   from /usr/local/lib/ruby/3.0.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
worker_1    |   from /usr/local/lib/ruby/3.0.0/tsort.rb:431:in `each_strongly_connected_component_from'
worker_1    |   from /usr/local/lib/ruby/3.0.0/tsort.rb:349:in `block in each_strongly_connected_component'
worker_1    |   from /usr/local/lib/ruby/3.0.0/tsort.rb:347:in `each'
worker_1    |   from /usr/local/lib/ruby/3.0.0/tsort.rb:347:in `call'
worker_1    |   from /usr/local/lib/ruby/3.0.0/tsort.rb:347:in `each_strongly_connected_component'
worker_1    |   from /usr/local/lib/ruby/3.0.0/tsort.rb:226:in `tsort_each'
worker_1    |   from /usr/local/lib/ruby/3.0.0/tsort.rb:205:in `tsort_each'
worker_1    |   from /usr/local/bundle/gems/railties-7.0.0/lib/rails/initializable.rb:60:in `run_initializers'
worker_1    |   from /usr/local/bundle/gems/railties-7.0.0/lib/rails/application.rb:369:in `initialize!'
worker_1    |   from /app/config/environment.rb:5:in `<top (required)>'
worker_1    |   from <internal:/usr/local/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:148:in `require'
worker_1    |   from <internal:/usr/local/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:148:in `require'
worker_1    |   from /usr/local/bundle/gems/zeitwerk-2.5.1/lib/zeitwerk/kernel.rb:35:in `require'
worker_1    |   from /usr/local/bundle/gems/sidekiq-6.3.1/lib/sidekiq/cli.rb:273:in `boot_application'
worker_1    |   from /usr/local/bundle/gems/sidekiq-6.3.1/lib/sidekiq/cli.rb:37:in `run'
worker_1    |   from /usr/local/bundle/gems/sidekiq-6.3.1/bin/sidekiq:31:in `<top (required)>'
worker_1    |   from /usr/local/bundle/bin/sidekiq:25:in `load'
worker_1    |   from /usr/local/bundle/bin/sidekiq:25:in `<main>'
hellorails_worker_1 exited with code 1

If I exec into the worker container I'm able to stat /usr/local/bundle/gems/turbo-rails-1.0.0/app/channels/turbo/streams which returns back that the directory does exist as seen below:

ruby@97b98bc1dd6b:/app$ stat /usr/local/bundle/gems/turbo-rails-1.0.0/app/channels/turbo/streams
  File: /usr/local/bundle/gems/turbo-rails-1.0.0/app/channels/turbo/streams
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: bdh/189d        Inode: 290588      Links: 2
Access: (0755/drwxr-xr-x)  Uid: ( 1000/    ruby)   Gid: ( 1000/    ruby)
Access: 2021-12-18 15:26:58.040000000 +0000
Modify: 2021-12-18 15:26:29.950000000 +0000
Change: 2021-12-18 15:26:55.900000000 +0000
 Birth: 2021-12-18 15:26:55.900000000 +0000

What's weird is the error mentions cannot load such file but that path it not a file, it's a directory on disk.

What's also interesting is the web, worker and cable containers that run all use an identical Dockerfile and the only difference is the command that gets run (such as puma or sidekiq). Both the web and cable containers come up fine. It's only worker that fails.

Running the same stat command in the web and cable containers produce the same output.

Move away from Webpacker to jsbundling-rails and cssbundling-rails

DHH has been on a mission recently to offer many viable alternatives to writing modern web applications without depending on a ton of Javascript, Webpacker or even a Node environment in some cases.

He has written about a few upcoming front-end choices that will be available in Rails 7 and he also published a few YouTube videos going over how to implement some of these solutions.

He also released 2 new gems which are jsbundling-rails and cssbundling-rails which will be in Rails 7 by default but they can be used today with Rails 6. This is the direction I see this example repo moving to.

It'll let us continue bundling our JS and CSS while still being able to use a custom Tailwind config file. I'm very much leaning towards using esbuild too. One fantastic thing about jsbundling-rails is even if you decide to use Webpack instead of esbuild you can easily swap it out and unlike Webpacker it will use a raw webpack config file. That was a great decision because I imagine the folks who want to go all-in with Webpack will want to use their existing configs.

But for this repo, I can see it using esbuild. It's lightning fast and has enough features to build a "Rails way" style of application that uses Hotwire Turbo and Stimulus. Since both bundling libraries are brand new and are changing fairly quick I may hold off on using them right away but I can see them being integrated here before Rails 7 launches. Also if someone is already using them successfully, I'm certainly open for a PR even if it's only a proof of concept.

Exciting times! Thank you for all of your efforts in this @dhh.

Steps to Integrate with existing app

I have an existing app. Is there some sort of checklist on what you have to do to integrate this into an existing app? I tried several times to integrate it with my app but haven't had success in getting it working.

The web container fails, saying that an existing server already exists. I have tried adding in a line in the entrypoint script to remove the /app/tmp/pids/server.pid file. Any suggestions on this?

Finally are there any other concerns I need to worry about running this on a M1 Mac? Do I need docker_sync to make it run better?

Thanks!

permission issue

ERROR

hellorails-web-1 | /usr/local/bundle/gems/rack-2.2.5/lib/rack/server.rb:433:in `initialize': Permission denied @ rb_sysopen - /app/tmp/pids/server.pid (Errno::EACCES)

I am almost sure that this is a local issue with my development environment.

I followed the steps in the README file and made sure that my UID and GUID are 1000.

➜ hellorails git:(main) ✗ id
uid=1000(arvindcj) gid=1000(arvindcj)

➜ hellorails git:(main) ✗ cat .env |grep 1000
If you're running native Linux and your uid:gid isn't 1000:1000 you can set
export UID=1000
export GID=1000

The ran> docker compose up --build

To get the error on the first line and the docker container does not start.

However, when am able to start the container from the image:
doceker run -it <image_id>

I see that the container starts:
docker run -it 61b8bc6d195e
=> Booting Puma
=> Rails 7.0.4 application starting in development
=> Run bin/rails server --help for more startup options
Puma starting in single mode...

  • Puma version: 6.0.1 (ruby 3.2.0-p0) ("Sunflower")
  • Min threads: 5
  • Max threads: 5
  • Environment: development
  • PID: 1
  • Listening on http://0.0.0.0:8000
    Use Ctrl-C to stop

But unable to reach port 8000 from the base machine.

"web", "cable", and "worker" containers do not display any logging

... unless you remove the "tty=true" from docker-compose.yml.

As the repo is, the only containers which show logging output when running "docker compose up" are the postgres and redis containers, which are second to least-important.

Reproduced on MacOS Monterey with docker 4.6.0.

I'm a Tailwind n00b...

...and I'm trying to get the most minimal Tailwind styling working, but I'm stuck.

In this branch on a fork, I attempted to strip out all custom chrome from the application.html.erb layout and replaced the content in app/views/pages/home.html.erb with minimally-Tailwind-styled default content. The styling does not get applied to the home page, but the default content + Tailwind classes are being rendered.

I have essentially the same layout + content in a vanilla Rails app, and see the Tailwind styles as expected.

  • In the logs, I see evidence that the CSS is being rebuilt:
    hellorails-css-1       |
    hellorails-css-1       | Rebuilding...
    hellorails-css-1       |
    hellorails-css-1       | Done in 74ms.
    
    but the elements in the DOM aren't getting the styling.
  • I've stopped and started the server, no difference.
  • I've forced a rebuild (docker compose up --build), no difference.

What am I missing?

Yarn build fails

When I build the project, my js compile fails with the following error:

$ ./run yarn:build js_1 | ./run: line 111: /app/node_modules/.bin/esbuild: cannot execute binary file: Exec format error js_1 | js_1 | Task completed in 0m0.024s error Command failed with exit code 126. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Manually reverting package.json to call "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds" successfully compiles.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.