paketo-buildpacks / rails-assets

Cloud Native Buildpack for precompiling rails assets for Ruby applications.
Apache License 2.0
7 stars 4 forks source link

Missing secret_key_base #144

Open collimarco opened 2 years ago

collimarco commented 2 years ago

Building a Rails app (v6.1.4) with pack fails:

Paketo Rails Assets Buildpack 0.2.4
  Executing build process
    Running 'bundle exec rails assets:precompile assets:clean'
failed to execute bundle exec output:
rails aborted!
ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `bin/rails credentials:edit`
/workspace/config/environment.rb:5:in `<main>'
Tasks: TOP => environment

Related: https://github.com/rails/rails/issues/32947

The point is that you don't need that key during the assets compile task, so a random key should be passed instead, so that the task doesn't fail.

Can you fix that?

Or can you suggest any other solution?

collimarco commented 2 years ago

Note that the Heroku buildpack works properly with the same application, so this is a bug in this buildpack.

sophiewigmore commented 2 years ago

Hey @collimarco, thanks for letting us know.

Yes, we've run into this before, which seems like buggy Rails 6 behaviour. Our rails 6 test app currently gets around this issue by setting config.secret_key_base = ENV['SECRET_KEY_BASE'] in the production.rb. This gets things passing in the build phase. Then, when running the built image with docker run, we pass the dummy vale--env SECRET_KEY_BASE=something to make rails happy.

sophiewigmore commented 2 years ago

Your suggestion of setting the dummy value in the buildpack is a good idea. I would be open to it if we could check through the app config files to make sure we aren't overriding a user-set value, in a nice, straightforward way.

kingdonb commented 2 years ago

The linked thread from rails/rails looks... unresolved

I tried setting config.secret_key_base = ENV['SECRET_KEY_BASE'] in production.rb but doesn't this still require a SECRET_KEY_BASE to be injected into the environment when you want to precompile assets?

I'm testing on Rails 7 and Ruby 3.1.2, and it's looking like a no-go. I did manage to get this far, it was a bit harder than it should be, but basically just had to ensure I was using the full builder (not base) and that I was not loading any other buildpacks besides ruby first, since it seemingly invokes all the buildpacks that it needs including this one.

I'm trying to get rails assets:precompile to work running locally with no master.key and no SECRET_KEY_BASE injected, I would settle for injecting a dummy variable but AFAICT it's not supported through kpack:

So, is there a solution that works with kpack? 😄

kingdonb commented 2 years ago

This is what I wound up doing for today:

diff --git a/config/environments/production.rb b/config/environments/production.rb
index 8eea956..5d9946e 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -78,5 +78,5 @@ Rails.application.configure do
   config.active_record.dump_schema_after_migration = false

   # https://github.com/paketo-buildpacks/rails-assets/issues/144#issuecomment-975613426
-  config.secret_key_base = ENV['SECRET_KEY_BASE']
+  config.secret_key_base = ENV['SECRET_KEY_BASE'] || `rails secret`

I'd like to add a guard clause to guarantee that I'm not really using a random secret in production where I guess it would cause peoples cookies to be invalidated every time the server starts up, or maybe alternatively if there's a variable set by paketo ruby/rails buildpack that I can use to detect I'm doing assets precompile/build and it's OK to use a random secret... otherwise balk and quit?

This seemed to work! I have an image now, gonna go test it out...

kingdonb commented 2 years ago

A little further poking around the documentation, I found that issue I linked is misleading:

apiVersion: kpack.io/v1alpha2
kind: Image
metadata:
  name: planet-image
  namespace: planet-store
spec:
  tag: img.hephy.pro/planetstore/web
  imageTaggingStrategy: BuildNumber
  serviceAccountName: store-pusher
  builder:
    name: planet-builder
    kind: Builder
  source:
    git:
      url: git@github.com:yebyen/planet-store.git
      revision: production
      #revision: c090ccca4a41096cc1155d20e05ddf9999211754
  build:
    env:
      - name: SECRET_KEY_BASE
        value: asdf1234

You can of course set environment variables at build time, in the Image definition, that wasn't clear to me until I read the doc (not sure how you can solve that one unfortunately, I'll try to read all the docs...)

Edit: Sunday afternoon, IDK if I have read all the docs, but I do have everything working! I'll never write another Dockerfile again... 🎉

robdimsdale commented 2 years ago

@kingdonb glad you found a way to achieve the behavior you wanted.

It sounds like this is mostly a kpack documentation issue. Is there anything you'd expect to see in the documentation for this buildpack in addition?

sophiewigmore commented 2 years ago

@kingdonb @robdimsdale I think at a minimum we should make it known that the SECRET_KEY_BASE should be set, in the README and then link out to the way to set that in pack/kpack to make it easier.

Alternatively, I'm open to a PR for @collimarco's workaround suggestion to set a dummy value if not provided, since a fair number of folks have run into this

kingdonb commented 2 years ago

I'd love to see a walkthrough of what is needed to boot a stripped-down rails new with for example --skip-keeps and maybe any other options that can potentially cause problems – you need to be sure there is a tmp directory and a log directory, there were a few other "easy ones" like this.

I will go back through my experience and make some notes about what else I tripped over. In general this experience, once I understood how to construct my Image, builder, and Clusterstack, was great! Getting to that point was a bit harder than I expected. I didn't really understand that the "ruby" buildpack was the only one I needed to include in my source and it will go out and fetch the others as needed, like this one.

I think there were an equal or fewer number of things to trip over compared to what my experience has been like with Heroku buildpacks. So, stellar review from me! I was really skeptical walking in too, because I've been using Heroku buildpacks or struggling to write a comparably good Dockerfile for years, I am pretty used to being disappointed with how it turns out.

sophiewigmore commented 2 years ago

@kingdonb thank you for providing this feedback, it's really helpful and appreciated.

Definitely interested to hear an enumeration of pitfalls you ran into in your experience, and also maybe what documentation you referenced? Our Rails Asset Pipeline reference documentation as well as how to documentation is very barebones so I filed https://github.com/paketo-buildpacks/paketo-website/issues/498 to add some details there. That issue might be a good place to add some of the issues you had so we can make them better documented.