nickjj / docker-rails-example

A production ready example Rails app that's using Docker and Docker Compose.
MIT License
974 stars 197 forks source link

Production sample? #13

Closed jpwynn closed 11 months ago

jpwynn commented 3 years ago

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?

nickjj commented 3 years ago

Hi,

(1) If you don't use Docker you'd likely want to create a Procfile and set up the services to run there. I haven't done this personally but I don't think there's anything unique about this app that would make it different than running any other Rails app on Heroku that uses a web + worker + action cable services. Did you run into a specific issue?

(2) I haven't created custom generators for TailwindCSS. In most projects I don't really find this to be useful. I mean, I really like using the generators but I never keep my end game pages looking the same as what the generator provides. Instead I usually design one of my generated resources how I like and then use that as a reference for future resources in the same project.

(3) I haven't yet, mainly because the screenshot shows the application in its current state. If such a demo app existed now it would involve maintaining 2 repos, which I don't necessarily mind, it just hasn't came up yet. But with everything set up in this project you can start following any Turbo / Stimulus / AC tutorials or examples. Maybe I could do something like this in the future.

jpwynn commented 3 years ago

(1) Oh yes we use Docker exclusively - for development - but not to push to production where we rely on the code running on Heroku's carefully curated dynos. Yes for our Rails 5 app we have a Procfile for production, use docker-compose for spinning everything up locally.

(2) Agreed, the generators are in no way critical, but if done right then out of the box they can give a nice "intro" to using a CSS framework.

(3) Just a thought. Problem with tutorials "out there" is they all make their own assumptions, and so many are terribly out of date. A unified "sample" might really highlight your curated stack.

We'll be taking it for a test-drive shortly!

nickjj commented 3 years ago

(2) I think it might be better suited towards creating a separate Tailwind generator gem and if such a thing existed and was shown to be well maintained I would add it as a dependency here. If you want to create that gem let me know.

danjebs commented 3 years ago

@jpwynn did you have any luck setting up a deploy to Heroku?

I'm getting a permissions error and I wonder if it's one of the common 6.1 issues that you were mentioning...

error An unexpected error occurred: "EROFS: read-only file system, mkdir '/node_modules'".
jpwynn commented 3 years ago

I did not try to install it to Heroku, sorry, @danjebs I actually ended up trying Jumpstart https://github.com/excid3/jumpstart which installed easily.

nickjj commented 3 years ago

That's a big difference since Jumpstart isn't using Docker.

@danjebs are you using Docker within Heroku?

jpwynn commented 3 years ago

I could not find a Heroku-production-tested Rails 6 template with that also used Docker for development. Heroku was a must-have; Docker was a very strong development preference, but still a #2 consideration. (ignore the link I'm sick of github's boneheaded lack of documented escaping for number sign)

danjebs commented 3 years ago

@jpwynn I see - I get a bit miffed with Docker occasionally because it's so slow on Mac but Docker solves enough problems that I am actually considering switching to Linux rather than ditching Docker. So Jumpstart doesn't sound like it would work for me.

@nickjj actually I hadn't tried Docker within Heroku - thus far I have not yet been using Redis or ActionCale or Sidekiq so I was hoping Heroku would work it's automagic at least for a barebones Rails setup.

Since you mention it, I guess the starting point would be to setup a heroku.yml file and deploy with that? A la the instructions here https://devcenter.heroku.com/articles/build-docker-images-heroku-yml#heroku-yml-overview

I could probably stumble to a working solution but there's a lot of features and if you're considering building the heroku.yml file then I would prefer to work with you on that. Otherwise I am happy to share whatever bumbled solution I come up with as a PR 😅

danjebs commented 3 years ago

It might actually be stupidly simple to deploy with Heroku if you take a few seconds to Google it first 🤦

Following https://devcenter.heroku.com/articles/container-registry-and-runtime:

heroku container:login
heroku container:push web
heroku container:release web
heroku open

Then set up your SECRET_KEY_BASE and provision/migrate your DB. If you are like me, loading the page and working through the Heroku logs will get you places.

I'm getting 404s on accessing JS and CSS asset packs though, that part isn't so trivial. And I have a feeling that there is more to it than what I outlined above (I mean, it can't be that simple!).

nickjj commented 3 years ago

Did you run through those steps and what's where you're at now?

The 404s are likely because Rails isn't configured to serve assets in production mode based on https://github.com/nickjj/docker-rails-example/blob/00b1acadbd5484ff563889b9d674991cf0f5e5b4/config/environments/production.rb#L25

If you set RAILS_SERVE_STATIC_FILES=1 as an env variable they might load. Would be good for a test.

danjebs commented 3 years ago

Ka-ching! That did it, thanks @nickjj. I'm far from having the whole rig up and running (Redis, Sidekiq and ActionCable haven't been tested yet) but the basic app is up and running. Didn't even need a heroku.yml although I suppose having one to provision Postgres and Redis could be a nice addition to this repo. I'm just taking this stack for a spin with a play app but once I get more time I can send one over.

Once again, awesome work and thanks for sharing 👏

danjebs commented 3 years ago

Did you run through those steps and what's where you're at now?

Yes that's the steps I ran through and after setting the RAILS_SERVE_STATIC_FILES env variable, it's working fine.

nickjj commented 3 years ago

No problem.

If you get the whole stack up and running would you mind sharing your exact heroku.yml or Procfile and any possible steps you've taken to get it to work? Maybe we could add it to the docs, or even add a deploy to Heroku button.

danjebs commented 3 years ago

Absolutely. From what I understand, it'd be a heroku.yml as the Procfile is not used in Docker setups.

I should also add, I am making this as a side project to explore Stimulus and Turbo and the monolith world (as a simple alternative to the Rails/Next.js/GraphQL/NGINX setup that I usually run). I'm just doing bits and pieces between client projects and a six month old. So it won't be quick, but I certainly will share it.

nickjj commented 2 years ago

I use an AMD64 based CPU. What if you clone down this repo and run it?

Also, this issue isn't really the place for this type of conversation. It's unrelated to the issue and even this project. If cloning this repo works, then I would check out the Rails forum or post in the Ruby issue tracker about Ruby 3.1 not working with M1s while Ruby 3.0 does.

partydrone commented 2 years ago

Yes, you're right. My apologies. I deleted it to prevent further comments about it here. 🙂

ebrett commented 2 years ago

I was able to get this up and running on a M1 Mac mini only by first deleting Gemfile.lock - rebuilding made the following changes:

+++ b/Gemfile.lock
@@ -69,7 +69,7 @@ GEM
     addressable (2.8.0)
       public_suffix (>= 2.0.2, < 5.0)
     bindex (0.8.1)
-    bootsnap (1.10.2)
+    bootsnap (1.10.3)
       msgpack (~> 1.2)
     builder (3.2.4)
     capybara (3.36.0)
@@ -94,7 +94,7 @@ GEM
     erubi (1.10.0)
     globalid (1.0.0)
       activesupport (>= 5.0)
-    i18n (1.8.11)
+    i18n (1.9.1)
       concurrent-ruby (~> 1.0)
     io-console (0.5.11)
     io-wait (0.2.1)
@@ -132,11 +132,11 @@ GEM
       net-protocol
       timeout
     nio4r (2.5.8)
-    nokogiri (1.13.1-x86_64-linux)
+    nokogiri (1.13.1-aarch64-linux)
       racc (~> 1.4)
-    pg (1.2.3)
+    pg (1.3.1)
     public_suffix (4.0.6)
-    puma (5.5.2)
+    puma (5.6.1)
       nio4r (~> 2.0)
     racc (1.6.0)
     rack (2.2.3)
@@ -171,7 +171,7 @@ GEM
       thor (~> 1.0)
       zeitwerk (~> 2.5)
     rake (13.0.6)
-    redis (4.5.1)
+    redis (4.6.0)
     regexp_parser (2.2.0)
     reline (0.3.1)
       io-console (~> 0.5)
@@ -216,10 +216,10 @@ GEM
     websocket-extensions (0.1.5)
     xpath (3.2.0)
       nokogiri (~> 1.8)
-    zeitwerk (2.5.3)
+    zeitwerk (2.5.4)

 PLATFORMS
-  x86_64-linux
+  aarch64-linux

 DEPENDENCIES
   bootsnap
zacwillis commented 2 years ago

I am having the same issue with the assets returning 404 errors. I have the RAILS_SERVE_STATIC_FILES=1 set in my env file. I have successfully deployed to heroku container registry but the js and css are not working in production. Any idea what would be causing this problem?

Here is my github repo: https://github.com/zacwillis/bcb

Any help would be GREATLY appreciated!

nickjj commented 2 years ago

Hi,

Your link is 404ing, is it a private repo?

zacwillis commented 2 years ago

Sorry, just made it public.

nickjj commented 2 years ago

Does Heroku let you connect to the container to see the file system? It would be curious to see if the assets exist in the correct spot. Also does Heroku throw any errors during the deploy process? Did you build and deploy an image with both RAILS_ENV and NODE_ENV set to production?

nickjj commented 2 years ago

Also, I don't want to be a stickler of policy but you removed the LICENSE file which violates the MIT license.

zacwillis commented 2 years ago

I wasn't aware of that, I will add it back.

I am not getting any errors during the deploy process. I have the RAILS_ENV and NODE_ENV set to production on the heroku side of things. I have attached an image of my production logs.

Screen Shot 2022-05-25 at 4 11 28 PM
nickjj commented 2 years ago

Does Heroku build a new image based on those env vars? The image needs to be both built and run with them set to production.

zacwillis commented 2 years ago

I have built a new image after changing the env vars to production in my .env file but it didn't resolve the issue. I have attached a screenshot of my .env variables and my heroku env variables.

Screen Shot 2022-05-31 at 2 01 56 PM Screen Shot 2022-05-31 at 2 01 48 PM
nickjj commented 2 years ago

From what I know those environment variables are set at runtime, not build time or does Heroku containers build images using those env vars too?

It's hard to say without knowing more details about your set up, plus I haven't run Heroku myself.

Also:

I don't want to be a stickler of policy but you removed the LICENSE file which violates the MIT license.

JBerendes commented 1 year ago

Environment vars set in the Heroku's config will be used first. This can be tested by setting a few unused vars and logging them.

I often find it easier to diagnose env issues by separating docker and env files based on proposed environments.
For production I may have- production:

Dockerfile.production
docker-compose.production.yml
.env.production

dev:

Dockerfile.development
docker-compose.development.yml
.env.development

I might even have a .env file that would allow me to run without docker .env.darwin or .env.local

I've been burned plenty by trying to craft a silver bullet. I'm finding in practice that the one size fits all approach rarely works even if it is desirable for devs. I can delight my employer and clients when I spend more time delivering on features. Go ahead and try this if you are getting stuck with environments not working how you might expect.

nickjj commented 11 months ago

Based on this discussion https://github.com/nickjj/docker-rails-example/discussions/70#discussioncomment-7252423 nothing had to change within this project to make it work on Heroku.

I'm going to resolve this issue because there is an easy path forward with this project if you want to use Heroku.

I'd rather not include specific config files for various deployment services like Heroku, Render and others because there's too many of them and the person doing the deployment will likely only ever use 1 of these at a time. Also out of the box this project will work with a VPS style deployment using Docker Compose.