האם Discourse יכול לשדרג תמונות Docker תדירות שאינן צריכות להיות מבוססות מראש?

I believe the launcher was built before docker compose was a thing:

לייק 1

ל-Docker compose אין את הפונקציונליות הנדרשת. מבנה יצירת התבניות של קבצי ה-docker של Discourse מאפשר תוצאות docker גמישות. עם compose, כל מה שיש לך הוא סט אפשרי של Dockerfiles קבועים שיכולים להוביל להרבה קונטיינרים.

בהגדרת ה-Discourse שלי, אני משתמש בקונטיינר יחיד עם Discourse ו-nginx המשתמשים ב-UNIX socket. PostgreSQL ו-Redis הם שירותים על המארח (host). זהו סטייה די משמעותית מההגדרה ברירת המחדל, אבל זה אפשרי ‘out of the box’.

זה אפשרי חלקית עם compose, אולי על ידי שימוש בתכונת הפרופילים (profile) שתוכננה בצורה לא מוצלחת. אבל גם אז זה די מבולגן. או שתצטרך לספק קבצי compose שונים עבור כל וריאציה.

אתה פשוט מעביר את הבעיה.

הגדרה נקייה של compose עבור Discourse תהיה השירותים הבאים בקונטיינרים נפרדים:

  • Discourse
  • nginx
  • PostgreSQL
  • Redis

Discourse ו-nginx צריכים לשתף volume, זה לא ביג דיל.

PostgreSQL ו-Redis… אלו דברים שאולי תרצה לארח במקום אחר, ולא שיהיה להם קונטיינר ספציפי ל-Discourse. ועכשיו docker compose הופך לבעיה: docker compose up -d יפעיל את ה-PostgreSQL הלא רצוי שלך. אוקיי, אז אנחנו מגדירים את זה כ-docker compose --profile postgresql up -d כדי להפעיל את הגדרת ה-discourse הבסיסית, וקונטיינר postgresql. docker compose --profile postgresql --profile redis up -d עבור הגדרת קונטיינר ה-Discourse העצמאית ה"מלאה". עדיף שלא תשכח ארגומנט --profile ..., כי אז יהיו לך יותר בעיות.

אז לחוויית משתמש (UX) טובה יותר, אתה יוצר launcher שידאג ליצירת פקודת ה-docker compose הרצויה. עכשיו אנחנו בעצם חוזרים לאותה נקודה. למעט העובדה ששינויים בקונטיינר ה-nginx עדיין אינם אפשריים. אז אני צריך קונטיינר nginx-http וקונטיינר nginx-unix שצריכים להיות הדדיים (mutually exclusive)? …

בטח שניהול הפלאגינים (plugin management) יכול להיות טוב יותר, אבל לעשות את זה עם docker compose, זה יהיה גיהינום.

לייק 1

So, to sum it up. There won’t be proper docker image.

As for the unbelievable amount of incorrect knowledge about what docker is and how it operates: What is Docker? | Docker Docs

You can share containers while you work, and be sure that everyone you share with gets the same container that works in the same way.

Also - with the beloved “launcher” - how can I run discourse on k8s cluster given there is no docker image I can consume and deploy it there?

Riiight…

This script must be run as root. Please sudo or log in as root first.

No, thank you. I don’t like running random scripts from internet. I only want to have nice Docker image that I can safely run in isolation :slight_smile:

I’ve successfully deployed Discourse to Production using Docker Compose with the published image as have clients.

However, yes, it’s messy and a reasonable amount of bespoke work is involved.

It is much easier to stick with the standard install with the CDCK launcher unless you really must use a different method because you have an opionated view, specific architecture or otherwise special requirements.

לייק 1

Using non-wizard-take-my-by-the-hand approach is not “opinionated, specific or special” :roll_eyes:

At any rate - the clue is having original docker image from discourse. As simple as that.

I tried using the official guide and “launcher” just to toy with the setup - with no luck (save for quite silly check if the user is root, which is just asking for problems).

I then turned to bitnami image (and their suggested compose file) from https://hub.docker.com/r/bitnami/discourse and one docker compose up later (and a bunch of SQL error [which doesn’t bode well] as well as warning from ruby [same caveat] I got running instance of discourse:

Pure convoluted and “non-standard magic”…

So again - why there is no regular image?

Digging through sources and repositories I found that base image is used (https://hub.docker.com/r/discourse/base/) though it’s verioning/tagging surprised me (https://hub.docker.com/r/discourse/base/tags)… There are no sane versions I wondered? And indeed, looking at the main repo there didn’t seem to be any releases but hey - at least there are properly tagged versions (Tags · discourse/discourse · GitHub).

Now one wonder - why there are not matching images in the main docker hub?

So yeah - having a look at how things are organized I concur:

:smiley:


On the other hand (or rather: “how things should be”), example project (smaller in scope, but the reasoning stands): GitHub - miniflux/v2: Minimalist and opinionated feed reader.

It has sane releases: Releases · miniflux/v2 · GitHub

Which have corresponding images correctly tagged: https://hub.docker.com/r/miniflux/miniflux/tags

And then upgrading is just switching version from x to y (or using latest tag so simple stop/pull/start will give updated version (which would run all required migrations automatically)

(oh, and the image is like 70x smaller but that’s yet another story)

Good job!

Just two questions… what are SQL errors and ruby warnings? I’m not familiar with those. But perhaps it is because I’ve used docker and stuff totally wrong way :thinking:

You do something like this:

./launcher bootstrap myimage
# the command that pushes that image to your preferred place to launch images
./launcher start-cmd

and that gives you the ENV variables you need to set to launch your image.

It’s really not that hard. You can even get it integrated into a github action so that it will build your image and push it to your docker-repo thingy. Looking at the commits to docker_compose, it looks like there are moves afoot to produce an image that doesn’t need to be bootstrapped, or at least make it easier to have it do some of the required stuff (migrate the database, precompile assets and push to s3 and so on). I’ve done this for clients who wanted to use k8s or AWS image-launcher-thingy (I can’t remember its name).

A few times I’ve considered offering such pre-built images as a service, but never found anyone who wanted to pay for such.

But there are a bunch of little pieces. Best I can tell CDCK uses launcher to build images, but they launch and manage them with other tools, just like you want to. And when they started, docker-compose wasn’t yet a decent way to do that and by the time it was, they had already made launcher work, so finding a way to migrate everyone from launcher to something else wasn’t really an option.

If the bitnami images work for you, then use them, but if they don’t, you’ll need to get help from someone who uses them, which is mostly nobody here.

2 לייקים

Eh… I already deleted the file and whole setup as I found NodeBB which feels less user hostile when it comes to deployment (guide: Docker - NodeBB Documentation; simple docker-compose file with 3 services: nodebb, postgres and redis: NodeBB/docker-compose-pgsql.yml at master · NodeBB/NodeBB · GitHub; and nicely tagged images: Package nodebb · GitHub)

However, I got the image and here are the relevant errors:

  1. seems like sql schema issue:
postgresql-1  | 2025-07-06 17:15:40.518 GMT [155] ERROR:  relation "translation_overrides" does not exist at character 523
postgresql-1  | 2025-07-06 17:15:40.518 GMT [155] STATEMENT:  SELECT a.attname, format_type(a.atttypid, a.atttypmod),
postgresql-1  | 	       pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
postgresql-1  | 	       c.collname, col_description(a.attrelid, a.attnum) AS comment,
postgresql-1  | 	       attidentity AS identity,
postgresql-1  | 	       attgenerated as attgenerated
postgresql-1  | 	  FROM pg_attribute a
postgresql-1  | 	  LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
postgresql-1  | 	  LEFT JOIN pg_type t ON a.atttypid = t.oid
postgresql-1  | 	  LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
postgresql-1  | 	 WHERE a.attrelid = '"translation_overrides"'::regclass
postgresql-1  | 	   AND a.attnum > 0 AND NOT a.attisdropped
postgresql-1  | 	 ORDER BY a.attnum
postgresql-1  |
postgresql-1  | 2025-07-06 17:15:40.616 GMT [156] ERROR:  relation "translation_overrides" does not exist at character 523
postgresql-1  | 2025-07-06 17:15:40.616 GMT [156] STATEMENT:  SELECT a.attname, format_type(a.atttypid, a.atttypmod),
postgresql-1  | 	       pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
postgresql-1  | 	       c.collname, col_description(a.attrelid, a.attnum) AS comment,
postgresql-1  | 	       attidentity AS identity,
postgresql-1  | 	       attgenerated as attgenerated
postgresql-1  | 	  FROM pg_attribute a
postgresql-1  | 	  LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
postgresql-1  | 	  LEFT JOIN pg_type t ON a.atttypid = t.oid
postgresql-1  | 	  LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
postgresql-1  | 	 WHERE a.attrelid = '"translation_overrides"'::regclass
postgresql-1  | 	   AND a.attnum > 0 AND NOT a.attisdropped
postgresql-1  | 	 ORDER BY a.attnum
  1. ruby warnings (both in discourse as well as sidekiq containers, which kinda makes sense as they use same image :D):
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:5: warning: already initialized constant DiscourseAutomation::Scripts::ADD_USER_TO_GROUP_THROUGH_CUSTOM_FIELD
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:5: warning: previous definition of ADD_USER_TO_GROUP_THROUGH_CUSTOM_FIELD was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:6: warning: already initialized constant DiscourseAutomation::Scripts::APPEND_LAST_CHECKED_BY
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:6: warning: previous definition of APPEND_LAST_CHECKED_BY was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:7: warning: already initialized constant DiscourseAutomation::Scripts::APPEND_LAST_EDITED_BY
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:7: warning: previous definition of APPEND_LAST_EDITED_BY was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:8: warning: already initialized constant DiscourseAutomation::Scripts::AUTO_RESPONDER
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:8: warning: previous definition of AUTO_RESPONDER was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:9: warning: already initialized constant DiscourseAutomation::Scripts::AUTO_TAG_TOPIC
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:9: warning: previous definition of AUTO_TAG_TOPIC was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:10: warning: already initialized constant DiscourseAutomation::Scripts::BANNER_TOPIC
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:10: warning: previous definition of BANNER_TOPIC was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:11: warning: already initialized constant DiscourseAutomation::Scripts::CLOSE_TOPIC
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:11: warning: previous definition of CLOSE_TOPIC was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:12: warning: already initialized constant DiscourseAutomation::Scripts::FLAG_POST_ON_WORDS
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:12: warning: previous definition of FLAG_POST_ON_WORDS was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:13: warning: already initialized constant DiscourseAutomation::Scripts::GIFT_EXCHANGE
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:13: warning: previous definition of GIFT_EXCHANGE was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:14: warning: already initialized constant DiscourseAutomation::Scripts::GROUP_CATEGORY_NOTIFICATION_DEFAULT
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:14: warning: previous definition of GROUP_CATEGORY_NOTIFICATION_DEFAULT was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:15: warning: already initialized constant DiscourseAutomation::Scripts::PIN_TOPIC
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:15: warning: previous definition of PIN_TOPIC was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:16: warning: already initialized constant DiscourseAutomation::Scripts::POST
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:16: warning: previous definition of POST was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:17: warning: already initialized constant DiscourseAutomation::Scripts::SEND_PMS
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:17: warning: previous definition of SEND_PMS was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:18: warning: already initialized constant DiscourseAutomation::Scripts::SUSPEND_USER_BY_EMAIL
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:18: warning: previous definition of SUSPEND_USER_BY_EMAIL was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:19: warning: already initialized constant DiscourseAutomation::Scripts::TOPIC
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:19: warning: previous definition of TOPIC was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:20: warning: already initialized constant DiscourseAutomation::Scripts::TOPIC_REQUIRED_WORDS
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:20: warning: previous definition of TOPIC_REQUIRED_WORDS was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:21: warning: already initialized constant DiscourseAutomation::Scripts::USER_GLOBAL_NOTICE
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:21: warning: previous definition of USER_GLOBAL_NOTICE was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:22: warning: already initialized constant DiscourseAutomation::Scripts::USER_GROUP_MEMBERSHIP_THROUGH_BADGE
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:22: warning: previous definition of USER_GROUP_MEMBERSHIP_THROUGH_BADGE was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:23: warning: already initialized constant DiscourseAutomation::Scripts::ZAPIER_WEBHOOK
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/scripts.rb:23: warning: previous definition of ZAPIER_WEBHOOK was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:5: warning: already initialized constant DiscourseAutomation::Triggers::AFTER_POST_COOK
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:5: warning: previous definition of AFTER_POST_COOK was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:6: warning: already initialized constant DiscourseAutomation::Triggers::API_CALL
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:6: warning: previous definition of API_CALL was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:7: warning: already initialized constant DiscourseAutomation::Triggers::CATEGORY_CREATED_EDITED
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:7: warning: previous definition of CATEGORY_CREATED_EDITED was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:8: warning: already initialized constant DiscourseAutomation::Triggers::PM_CREATED
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:8: warning: previous definition of PM_CREATED was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:9: warning: already initialized constant DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:9: warning: previous definition of TOPIC_TAGS_CHANGED was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:10: warning: already initialized constant DiscourseAutomation::Triggers::POINT_IN_TIME
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:10: warning: previous definition of POINT_IN_TIME was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:11: warning: already initialized constant DiscourseAutomation::Triggers::POST_CREATED_EDITED
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:11: warning: previous definition of POST_CREATED_EDITED was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:12: warning: already initialized constant DiscourseAutomation::Triggers::RECURRING
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:12: warning: previous definition of RECURRING was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:13: warning: already initialized constant DiscourseAutomation::Triggers::STALLED_TOPIC
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:13: warning: previous definition of STALLED_TOPIC was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:14: warning: already initialized constant DiscourseAutomation::Triggers::STALLED_WIKI
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:14: warning: previous definition of STALLED_WIKI was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:15: warning: already initialized constant DiscourseAutomation::Triggers::TOPIC
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:15: warning: previous definition of TOPIC was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:16: warning: already initialized constant DiscourseAutomation::Triggers::USER_ADDED_TO_GROUP
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:16: warning: previous definition of USER_ADDED_TO_GROUP was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:17: warning: already initialized constant DiscourseAutomation::Triggers::USER_BADGE_GRANTED
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:17: warning: previous definition of USER_BADGE_GRANTED was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:18: warning: already initialized constant DiscourseAutomation::Triggers::USER_FIRST_LOGGED_IN
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:18: warning: previous definition of USER_FIRST_LOGGED_IN was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:19: warning: already initialized constant DiscourseAutomation::Triggers::USER_PROMOTED
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:19: warning: previous definition of USER_PROMOTED was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:20: warning: already initialized constant DiscourseAutomation::Triggers::USER_REMOVED_FROM_GROUP
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:20: warning: previous definition of USER_REMOVED_FROM_GROUP was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:21: warning: already initialized constant DiscourseAutomation::Triggers::USER_UPDATED
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers.rb:21: warning: previous definition of USER_UPDATED was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers/recurring.rb:6: warning: already initialized constant DiscourseAutomation::Triggers::Recurring::RECURRENCE_CHOICES
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers/recurring.rb:6: warning: previous definition of RECURRENCE_CHOICES was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers/stalled_wiki.rb:6: warning: already initialized constant DiscourseAutomation::Triggers::StalledWiki::DURATION_CHOICES
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers/stalled_wiki.rb:6: warning: previous definition of DURATION_CHOICES was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb:7: warning: already initialized constant DiscourseAutomation::Triggers::TopicTagsChanged::TriggerOn::TAGS_ADDED_OR_REMOVED
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb:7: warning: previous definition of TAGS_ADDED_OR_REMOVED was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb:8: warning: already initialized constant DiscourseAutomation::Triggers::TopicTagsChanged::TriggerOn::TAGS_ADDED
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb:8: warning: previous definition of TAGS_ADDED was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb:9: warning: already initialized constant DiscourseAutomation::Triggers::TopicTagsChanged::TriggerOn::TAGS_REMOVED
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb:9: warning: previous definition of TAGS_REMOVED was here
sidekiq-1     | /opt/bitnami/discourse/plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb:11: warning: already initialized constant DiscourseAutomation::Triggers::TopicTagsChanged::TriggerOn::MODES
sidekiq-1     | /bitnami/discourse/plugins/automation/lib/discourse_automation/triggers/topic_tags_changed.rb:11: warning: previous definition of MODES was here
sidekiq-1     | 2025-07-06T17:15:52.699Z pid=1 tid=4ox INFO: Booted Rails 7.2.2.1 application in production environment

That’s an excellent point. There isn’t really a good reason why this script cannot run as non-root.

The setup script is the only one which really needs root, for the scary part where it suggest to execute the docker install script from the internet. So even that can be changed to execute as non-root.

The launcher script doesn’t need root, it just needs write access to /var/discourse and the permission to manage docker containers.

לייק 1

Eh… :slight_smile:

The script doesn’t even need access to /var/discourse (why it does?!).

The whole problem stems from a couple of things:

  1. huge misunderstanding what docker it, how it works and what it enables
  2. glueing together the notion that docker = docker-compsose (it’s not!)

You can have completely contained setup that virtually doesn’t touch the host environment…

After doing quite a lot of digging in it seems that the whole “setup” script was created to make installation as simple-as-possible for the very-non-technical-person. It checks, guides the user and setups everything. That may be a nice thing, but it breaks completely in anything that tries to stray even the tiniest inch from the envisioned path.

In the most basic setup, you may not even need to access to any host directories - everything will be contained within limited environment (image will be used to create the container and all the required storage would be handle via docker volumes [it has issues where you want to migrate somewhere else or access the files but we are talking about basics]).

It also tries to make sure that DNS is correct, tries to setup certs, reverse proxy, SMTP and whatnot - again, completely fine to provide this easy setup.

BUT!

The issue is NOT about throwing that away but IN ADDITION providing plain docker image (it’s already there, it’s used by the scripts and templates used by the script! discourse_docker/templates/postgres.template.yml at main · discourse/discourse_docker · GitHub & discourse_docker/launcher at main · discourse/discourse_docker · GitHub) with

  1. proper versioning: you tag the image with the released discourse version (3.4.5 or whatnot)
  2. sane, simple documentation of the expected environment variables (driving database/redis/etc connectivity) and possible paths/volumes that can be mounted to host.

Just that…

Take a look at aforementioned miniflux guide: Miniflux Installation with Docker - it gives you details about the image (and which repositories serves them) and possible environment variables to configure it.
Or MySQL docker image: https://hub.docker.com/_/mysql - same thing - guide that expains what is possbile to configure (see especially section: " Environment Variables").

Noone says: “you have to use mysql launcher to build mysql image so you can use it”, or redis for that matter - in this case you simply use existing images and this is the clue and gist of using docker. Yet in case of discourse suddently this is “bad” solution and everyone shouts: “you have to build your own image!” – why!?

No. Because of plugins.

לייק 1

Uhm… had to do a bit of digging regarding plugins and again I have to say/quote:

:smiley:

So what I’ve done - went to plugins section, clicked on first plugin looking for instructions and installation guide (Plugin directory | Discourse - Civilized DiscussionSign in with Apple | Discourse - Civilized DiscussionDiscourse Apple AuthenticationInstall plugins on a self-hosted site) and… dear lord - what a convoluted “mess”.

Why on earth you would need new image just to have plugins? With docker you can just specify mount directory for plugins and then place it there…

I’m not a Ruby guy so the things may be weirder here, but for example in the Java world you just drop a jar with the plugin so it would be loaded and voila - you have it running. And you are using the same image as everyone else…

(Not saying it’s not messy, just explaining why things are as they are)

Because of the Ember asset pipeline.

Which would be a mess as well, because you don’t want to have those deps externally.

2 לייקים

This one: GitHub - ember-engines/ember-asset-loader: Asset loading support for Ember applications?

Why not though?

ניתן לעבד תוספים תוך כדי תנועה, וזה נעשה גם בעת שדרוג של תוסף.
עם קצת קסם, ניתן גם להוסיף תוסף חדש למופע פועל מבלי לבנות מחדש את הקונטיינר. לכן, טעינת נפח תוסף לקונטיינר אמורה להיות אפשרית (עם כמה שינויים).

הבעיה העיקרית שאני רואה היא עם שדרוג Discourse. ניתן לעשות זאת כעת עם מופע פועל. שדרוג בעצם בונה מחדש את ה-Discourse. אם ה-Discourse הגיע למעשה מתמונה שנבנתה מראש, אינך יכול לשנות את הקבצים הללו. לכן, שדרוג עם אפס/מעט זמן השבתה כנראה ידרוש לא מעט עבודה.

This is something I don’t grasp (probably missing context in terms of Ruby…).

In general with docker/containers/orchestration you can have blue-green/red-black deployments where you prepare new container with new version and switch the trafic once it’s ready. However, in general for smaller deployments that shouldn’t be an issue as most of the time service (container) startup should be mere seconds so the downtime from switching versions should be minimal (the biggest problem is having to run schema upgrades, but this applies regardless if you re-build the image or not)

כן, אבל זה לא איך שזה עובד כרגע, אז זה החלק שדורש עבודה. איך אתה הולך לעשות את זה מתוך ממשק הניהול של Discourse. איך אתה הולך להקטין את הקונטיינר הכחול תוך כדי הפעלת הקונטיינר הירוק (למערכות אין משאבים אינסופיים, אז לפני שמתחילים להפעיל את הכחול רוצים להפחית את עובדי ה-unicorn בירוק). או שאתה יכול פשוט ללכת על מצב שהירוק למטה, ועכשיו הכחול עולה.

יש הרבה דברים שצריך להבין ולפתור. גם מפרספקטיבה טכנית וגם מפרספקטיבה של מנהל מערכת. השדרוג בלחיצה אחת מתוך ממשק הניהול הוא תכונה חשובה.

לייק 1

Plugins and custom images still need to be built, but for vanilla building for compose is becoming within reach these days - I’ve made a little proof of concept experiment here for anyone curious.

Obviously, since these are all my repos (not Discourse’s™) this is not anything Official, so YMMV, and definitely do not expect official support :dragon: I’m casting this here, since it’s been mentioned folks are already running bitnami and other non-sanctioned ways of running.

The off the shelf postgres (or pgvector) images do not work for Discourse - Discourse needs to change the default config, does not connect via a superuser, support locales, and needs to support postgres upgrades without a Discourse admin needing to dump/restore.

4 לייקים

Eh… this is I think the crucial difference and this “update from the admin interface” is somewhat of a reminder of old times, when you only had “web hosting” with php interpreter so everything was build around that notion. And I think this carried over to how Discourse work and is expected to be managed.

Well, that’s another thing I noticed - discourse is quite heavy (the container started consuming resources during startup at a scary level) so yeah - it may be a problem.

How those are “build” in the context of Ruby (which is mostly interpreted and not compiled language)?

Wouldn’t it be better to try to use off-the-shelf solutions? Even for postgres config can be easily changed by simply providing/mouting custom postgresql.conf file, no need for completely custom image with baked in config… and even still - if that’s required, discourse could provide such pre-build image that would only be pulled instead of re-build every time…

This “admin upgrade interface” is a plugin (called “docker manager”). You don’t need to include it if you have another way of doing online updates.