Definieren von DISCOURSE_S3_CDN_URL-Links zu Assets in der S3-CDN-URL

I had this problem before and decided that I was crazy, confused, or the database on the site was suspect, but this is on a brand new site. Also, I was on Digital Ocean spaces, so I thought it might be a problem somehow.

I’m trying again to figure out how to keep images on AWS S3 like I think the Big Boys do.

Here’s what I have in the env section:

  DISCOURSE_S3_ACCESS_KEY_ID: 'key'
  DISCOURSE_S3_SECRET_ACCESS_KEY: 'lock'
  DISCOURSE_BACKUP_LOCATION: 's3'
  DISCOURSE_S3_BUCKET: 'lc-xyz'
  DISCOURSE_S3_BUCKET_NAME: 'lc-xyz'
  DISCOURSE_S3_BACKUP_BUCKET: 'lc-xyz/backups'
  DISCOURSE_S3_UPLOAD_BUCKET: 'lc-xyz/uploads'
  DISCOURSE_S3_CDN_URL: 'https://lc-rbx.s3.amazonaws.com'

When I include the s3 cdn url the site breaks because all of the links to the assets are on S3 like https://lc-xyz.s3.amazonaws.com/assets/plugin-third-party-01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b.br.js.

Because if you define s3 cdn url Discourse looks for the assets on the s3_cdn_url.

I did a rebuild, but the assets are still missing. I can do a

rake s3:upload_assets

Is there an after_bundling_assets stanza that I could add that to? (I know about after_db_migrate and after_bundle_exec, but don’t know if those would work.)

Do assets get produced some other time? (It would seem like when themes get modified assets would change.)

If I also had a “push CDN like normal”, would that keep this from happening?

Is there some best practice that I’m missing?

You can use after_assets_precompile as the hook for that rake task.

Aha! Thanks very much for that. Where does the list of those things live?

I’m still confused why this is necessary, especially since you seemed confused before. (Or maybe I should be happy that I can push all this stuff to S3, now that I know how to do it–And I think that it was you who said that one could use CloudFlare’s free CDN to front an AWS bucket.)

I’m trying this again. I’ve got uploads going to s3. That works.

I configured cloudflare to CDN the site. If I enter https://lc-XXX.literatehosting.com/uploads in the s3_cdn_url site setting, new uploads go to the S3 bucket and the image is linked to the CDN url and it works.

BUT if I try to set the s3_cdn_url with an ENV in app.yml (or edit config/discourse.conf by hand and sv restart unicorn, all of the assets are loaded from S3 (where they aren’t). That might be OK, but if I try to rake s3:upload_assets, it complains that S3 isn’t configured.

I happened across this while figuring out some clashing settings names.

I think (and hope, because it means I understand this and didn’t write absolute nonsense in the thread linked above) that if you remove these two lines:

DISCOURSE_S3_BUCKET: 'lc-xyz'
DISCOURSE_S3_BUCKET_NAME: 'lc-xyz'

Then you can set DISCOURSE_S3_CDN_URL, and it will only be used for uploads, not assets.

I think that you do understand, and, thanks to you, I’m at least closer to understanding myself! Thanks very much!

Running into this and still very confused after reading this thread…

I’m trying to server s3 uploads (not compiled assets) from CDN (Cloudfront).

If I configure “s3 cdn url” via the settings screen, it works as expected (well…except for System upload not using s3 cdn url)

However, if I configure via DISCOURSE_S3_CDN_URL and rebuild, the frontend is broken because its trying to load compiled assets from my s3 cdn url.

Seems DISCOURSE_S3_CDN_URL / s3_cdn_url should only affect uploads, and DISCOURSE_CDN_URL should only affect assets.

That is my experience too. I ended up making a plugin to set the S3_CDN_URL.

@pfaffman seems like this should be filed as a bug then, yes?

Perhaps. It’s not a feature likely to be used by normal self hosters,so it’s going to be a low priority. Also, I think that there is soon to be a change in how global settings and shadowed by global work, so it’ll likely get worked out then.

Es scheint, dass das gleiche Problem hier auch bei mir auftritt.
@pfaffman, ich brauche deine Hilfe.
Verwendest du Cloudfront, um die benutzerdefinierte Domain-CDN-URL zu erreichen, oder nutzt du einfach den öffentlichen Präfix der Bucket-Objekte in der CDN-URL?

Ich bin gerade darauf gestoßen. @pfaffman, hast du das Problem jemals gelöst?

Ich habe Uploads zum Laufen gebracht, indem ich s3_cdn_url manuell in den Site-Einstellungen gesetzt habe, aber idealerweise müsste ich die ENV-Variable beim Deployen global setzen können. Wenn ich das tue, tritt das gleiche Problem auf: Discourse versucht, Assets unter der s3_cdn_url zu suchen. Das scheint mir ein Fehler in discourse/lib/content_security_policy/default.rb at main · discourse/discourse · GitHub zu sein.

Ich glaube, ich habe den Wert einfach in der Datenbank gesetzt.

Meine Vermutung ist, dass die Lösung darin besteht, den Rake-Auftrag zu finden, der die Assets nach S3 hochlädt.

Ich wollte mich erkundigen, ob jemand vom @team bestätigen kann, ob dieses Verhalten erwartet ist, dass man eine S3-CDN (global eingestellt) für Uploads nicht verwenden kann, ohne dass Discourse auch nach Assets dort sucht. Es scheint ein unerwartetes Verhalten zu sein, es sei denn, ich habe etwas missverstanden.

Ja, das ist das erwartete Verhalten.

Die Einrichtung eines S3-CDN bewirkt, dass es für alle statischen Dateien verwendet wird, egal ob es sich um Uploads oder JS-Assets handelt.

Hier sind einige Informationen dazu, ich habe mich letzten Monat damit beschäftigt.

Ich habe es behoben, indem ich beide Variablen (DISCOURSE_S3_CDN_URL und DISCOURSE_CDN_URL) gesetzt und zwei CloudFront-Distributionen erstellt habe: eine für die Uploads mit dem S3-Bucket als Ursprung und eine für die Assets mit dem Server als Ursprung.

Hier ist der Code, den wir dafür verwenden:

Hier ist unsere app.yml (wir haben sie web.yml genannt), wobei wir die Variablen zur Build-Zeit ersetzen: infra/modules/services/discourse/web.yml at master · debtcollective/infra · GitHub

Fantastisch. Vielen Dank. Es scheint kaum Dokumentation dazu zu geben, und die Einstellungen legen nahe, dass S3 nur für Uploads verwendet werden kann, was uns vermutlich alle verwirrt.

Es steht auf meiner Liste, dazu ein howto zu schreiben. Ich hoffe, das bis zum Wochenende zu schaffen.

Ja, sobald man verstanden hat, dass man zwei CloudFront-Distributionen benötigt, ergibt das mehr Sinn. Vergessen Sie auch nicht, nach jedem Rebuild die Assets auf S3 hochzuladen. Es gibt ein Problem bei Upgrades von Docker Manager, bei dem Sie bundle exec rake s3:upload_assets manuell innerhalb des Docker-Containers ausführen müssen. Wenn Sie stattdessen einen Rebuild durchführen, sollte es funktionieren, wenn Sie diese Zeilen zu Ihrer app.yml hinzufügen:

hooks:
  after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - 'bundle exec rake s3:upload_assets'

Diese Aufgabe meldet, dass S3 nicht konfiguriert ist. Ich habe das Problem auf diese Methode in global_setting.rb eingegrenzt:

def self.use_s3?
    (@use_s3 ||=
      begin
        s3_bucket &&
        s3_region && (
          s3_use_iam_profile || (s3_access_key_id && s3_secret_access_key)
        ) ? :true : :false
      end) == :true
  end

Wo wird GlobalSetting.s3_bucket erwartet? Mir scheint, wir müssen die Umgebungsvariablen DISCOURSE_S3_UPLOAD_BUCKET und DISCOURSE_S3_BUCKET setzen. Was ist der Unterschied zwischen den beiden?