Creo que el lanzador se creó antes de que existiera docker compose:
Docker Compose no incluye la funcionalidad requerida. La construcción de plantillas de archivos de Docker de Discourse permite resultados de Docker flexibles. Con Compose, todo lo que tienes es un conjunto posible de Dockerfiles fijos que pueden resultar en un montón de contenedores.
En mi configuración de Discourse, uso un solo contenedor con Discourse y nginx usando un socket UNIX. PostgreSQL y Redis son un servicio en el host. Eso es una desviación bastante grande de la configuración predeterminada, pero es posible de fábrica.
Es parcialmente posible con Compose, quizás usando la característica de perfil bastante mal diseñada. Pero incluso entonces es bastante desordenado. O necesitarías entregar diferentes archivos de Compose para cada variación.
Simplemente estás trasladando el problema.
Una configuración limpia de Compose para Discourse sería los siguientes servicios en contenedores separados:
- Discourse
- nginx
- PostgreSQL
- Redis
Discourse y nginx necesitan compartir un volumen, no es gran cosa.
PostgreSQL y Redis… esas son cosas que podrías querer alojar en otro lugar, y no tener un contenedor específico de Discourse para ello. Y ahora Docker Compose se convierte en un problema: docker compose up -d lanzará tu PostgreSQL no deseado. Ok, entonces lo hacemos docker compose --profile postgresql up -d para lanzar la configuración básica de Discourse y un contenedor de PostgreSQL. docker compose --profile postgresql --profile redis up -d para la configuración de contenedor de Discourse “completa” autocontenida. Será mejor que no olvides un argumento --profile ..., porque entonces tendrás más problemas.
Así que para una mejor experiencia de usuario (UX), creas un lanzador para encargarte de crear el comando Docker Compose deseado. Ahora estamos más o menos de vuelta donde estábamos. Excepto que las modificaciones en el contenedor de nginx aún no son posibles. ¿Así que necesito un contenedor nginx-http y un contenedor nginx-unix que deberían ser mutuamente excluyentes? …
Claro, la gestión de plugins podría ser mejor, pero hacer esto con Docker Compose, eso será un infierno.
Entonces, para resumir. No habrá una imagen de Docker adecuada.
En cuanto a la increíble cantidad de conocimiento incorrecto sobre qué es Docker y cómo funciona: What is Docker? | Docker Docs
Puedes compartir contenedores mientras trabajas y estar seguro de que todos los que compartes obtienen el mismo contenedor que funciona de la misma manera.
Además, con el querido “lanzador”, ¿cómo puedo ejecutar Discourse en un clúster de k8s dado que no hay una imagen de Docker que pueda consumir y desplegar allí?
Claro…
Este script debe ejecutarse como root. Por favor, usa sudo o inicia sesión como root primero.
No, gracias. No me gusta ejecutar scripts aleatorios de Internet. Solo quiero tener una buena imagen de Docker que pueda ejecutar de forma segura en aislamiento ![]()
He desplegado Discourse con éxito en producción usando Docker Compose con la imagen publicada, al igual que lo han hecho clientes.
Sin embargo, sí, es un lío y requiere una cantidad razonable de trabajo a medida.
Es mucho más fácil ceñirse a la instalación estándar con el lanzador de CDCK a menos que realmente debas usar un método diferente porque tienes una opinión particular, una arquitectura específica u otros requisitos especiales.
Usar un enfoque que no sea de asistente que me tome de la mano no es “opinado, específico o especial” ![]()
En cualquier caso, la pista es tener la imagen original de Docker de Discourse. Tan simple como eso.
Intenté usar la guía oficial y el “lanzador” solo para jugar con la configuración, sin éxito (salvo una comprobación bastante tonta de si el usuario es root, lo que solo pide problemas).
Luego recurrí a la imagen de Bitnami (y a su archivo compose sugerido) de https://hub.docker.com/r/bitnami/discourse y, después de un docker compose up (y un montón de errores de SQL [lo que no augura nada bueno], así como advertencias de Ruby [la misma advertencia]), obtuve una instancia en funcionamiento de Discourse:
Puro y complicado “magia no estándar”…
Entonces, de nuevo, ¿por qué no hay una imagen normal?
Investigando en las fuentes y repositorios, encontré que se utiliza la imagen base (https://hub.docker.com/r/discourse/base/), aunque su versionado/etiquetado me sorprendió (https://hub.docker.com/r/discourse/base/tags)… ¿No hay versiones sensatas? Y, de hecho, mirando el repositorio principal, no parecía haber ningún lanzamiento, pero bueno, al menos hay versiones correctamente etiquetadas (Tags · discourse/discourse · GitHub).
Ahora uno se pregunta: ¿por qué no hay imágenes que coincidan en el hub principal de Docker?
Así que sí, echando un vistazo a cómo están organizadas las cosas, estoy de acuerdo:
![]()
Por otro lado (o más bien: “cómo deberían ser las cosas”), proyecto de ejemplo (de menor alcance, pero el razonamiento se mantiene): GitHub - miniflux/v2: Minimalist and opinionated feed reader.
Tiene lanzamientos sensatos: Releases · miniflux/v2 · GitHub
Que tienen imágenes correspondientes correctamente etiquetadas: https://hub.docker.com/r/miniflux/miniflux/tags
Y luego actualizar es simplemente cambiar la versión de x a y (o usar la etiqueta latest, por lo que un simple stop/pull/start dará la versión actualizada (que ejecutará todas las migraciones necesarias automáticamente).
(oh, y la imagen es como 70 veces más pequeña, pero esa es otra historia)
¡Buen trabajo!
Solo dos preguntas… ¿qué son los errores SQL y las advertencias de Ruby? No estoy familiarizado con ellos. Pero quizás sea porque he usado Docker y esas cosas de forma totalmente incorrecta ![]()
Haces algo como esto:
./launcher bootstrap myimage
# el comando que envía esa imagen a tu lugar preferido para lanzar imágenes
./launcher start-cmd
y eso te da las variables de entorno que necesitas configurar para lanzar tu imagen.
Realmente no es tan difícil. Incluso puedes integrarlo en una acción de github para que construya tu imagen y la envíe a tu repositorio de docker. Si observas los commits de docker_compose, parece que hay movimientos en marcha para producir una imagen que no necesite ser iniciada, o al menos facilitar que haga algunas de las tareas requeridas (migrar la base de datos, precompilar activos y enviarlos a s3, etc.). He hecho esto para clientes que querían usar k8s o el “lanzador de imágenes” de AWS (no recuerdo su nombre).
Un par de veces he considerado ofrecer tales imágenes preconstruidas como un servicio, pero nunca encontré a nadie que quisiera pagar por ello.
Pero hay un montón de pequeñas piezas. Lo mejor que puedo decir es que CDCK usa el lanzador para construir imágenes, pero las lanzan y las gestionan con otras herramientas, tal como tú quieres. Y cuando empezaron, docker-compose aún no era una forma decente de hacerlo y para cuando lo fue, ya habían hecho que el lanzador funcionara, por lo que encontrar una manera de migrar a todos del lanzador a otra cosa realmente no era una opción.
Si las imágenes de bitnami te funcionan, úsalas, pero si no, necesitarás ayuda de alguien que las use, que en su mayoría no está aquí.
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:
- 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
- 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
Ese es un excelente punto. Realmente no hay una buena razón por la que este script no pueda ejecutarse como no root.
El script de configuración es el único que realmente necesita ser root, por la parte aterradora donde sugiere ejecutar el script de instalación de Docker desde Internet. Así que incluso eso se puede cambiar para que se ejecute como no root.
El script del lanzador no necesita ser root, solo necesita acceso de escritura a /var/discourse y el permiso para administrar contenedores de Docker.
Eh… ![]()
El script ni siquiera necesita acceso a /var/discourse (¿por qué lo hace?).
Todo el problema se deriva de un par de cosas:
- Gran malentendido de lo que es docker, cómo funciona y qué permite.
- Unión de la noción de que docker = docker-compose (¡no lo es!)
Puedes tener una configuración completamente contenida que virtualmente no toca el entorno del host…
Después de investigar bastante, parece que todo el script de “configuración” se creó para que la instalación fuera lo más simple posible para la persona muy poco técnica. Comprueba, guía al usuario y configura todo. Eso puede ser algo bueno, pero falla por completo en cualquier cosa que intente desviarse incluso una pulgada del camino previsto.
En la configuración más básica, es posible que ni siquiera necesites acceso a ningún directorio del host: todo estará contenido dentro de un entorno limitado (se usará una imagen para crear el contenedor y todo el almacenamiento requerido se manejará a través de volúmenes de docker [tiene problemas cuando quieres migrar a otro lugar o acceder a los archivos, pero estamos hablando de lo básico]).
También intenta asegurarse de que el DNS sea correcto, intenta configurar certificados, proxy inverso, SMTP y lo que sea, nuevamente, está completamente bien proporcionar esta configuración fácil.
¡PERO!
El problema NO es desechar eso, sino ADEMÁS proporcionar una imagen de docker simple (ya existe, es utilizada por los scripts y las plantillas utilizadas por el script. discourse_docker/templates/postgres.template.yml at main · discourse/discourse_docker · GitHub y discourse_docker/launcher at main · discourse/discourse_docker · GitHub) con
- versionado adecuado: etiqueta la imagen con la versión de discourse lanzada (3.4.5 o lo que sea)
- documentación sensata y simple de las variables de entorno esperadas (que controlan la conectividad de la base de datos/redis/etc.) y las rutas/volúmenes posibles que se pueden montar en el host.
Solo eso…
Echa un vistazo a la guía de miniflux mencionada anteriormente: Miniflux Installation with Docker - te da detalles sobre la imagen (y qué repositorios las sirven) y las variables de entorno posibles para configurarla.
O la imagen de docker de MySQL: https://hub.docker.com/_/mysql - lo mismo - una guía que explica qué se puede configurar (ver especialmente la sección: “Variables de entorno”).
Nadie dice: “tienes que usar el lanzador de mysql para construir la imagen de mysql para poder usarla”, ni redis para el caso - en este caso simplemente usas las imágenes existentes y esta es la clave y la esencia de usar docker. Sin embargo, en el caso de discourse, de repente esta es una solución “mala” y todos gritan: “¡tienes que construir tu propia imagen!” – ¿por qué!?
No. Por los plugins.
Uhm… tuve que investigar un poco sobre los plugins y de nuevo tengo que decir/citar:
![]()
Así que lo que hice: fui a la sección de plugins, hice clic en el primer plugin buscando instrucciones y guía de instalación (Plugin directory | Discourse - Civilized Discussion → Sign in with Apple | Discourse - Civilized Discussion → Discourse Apple Authentication → Install plugins on a self-hosted site) y… por Dios - ¡qué “lío” tan enrevesado!
¿Por qué demonios necesitarías una nueva imagen solo para tener plugins? Con docker puedes simplemente especificar un directorio de montaje para los plugins y luego colocarlo allí…
No soy un experto en Ruby, así que las cosas pueden ser más extrañas aquí, pero, por ejemplo, en el mundo Java, simplemente sueltas un jar con el plugin para que se cargue y listo - lo tienes funcionando. Y usas la misma imagen que todos los demás…
(No digo que no sea un desorden, solo explico por qué las cosas son como son)
Debido al pipeline de assets de Ember.
Lo que también sería un desorden, porque no quieres tener esas dependencias externamente.
¿Este?: GitHub - ember-engines/ember-asset-loader: Asset loading support for Ember applications?
¿Por qué no, sin embargo?
Los plugins se pueden procesar sobre la marcha, esto también se hace al actualizar un plugin. Con un poco de magia, también puedes añadir un nuevo plugin a una instancia en ejecución sin reconstruir el contenedor. Por lo tanto, montar un volumen de plugin en un contenedor debería ser posible (con un montón de cambios).
El principal problema que veo es con la actualización de Discourse. Esto se puede hacer actualmente con una instancia en ejecución. La actualización básicamente reconstruye Discourse. Si Discourse proviniera de una imagen precompilada, no podrías cambiar esos archivos. Por lo tanto, actualizar con tiempo de inactividad cero/mínimo probablemente requerirá bastante trabajo.
Esto es algo que no entiendo (probablemente me falte contexto en términos de Ruby…).
En general, con docker/contenedores/orquestación, puedes tener despliegues blue-green/red-black donde preparas un nuevo contenedor con la nueva versión y cambias el tráfico una vez que está listo. Sin embargo, en general, para despliegues más pequeños, eso no debería ser un problema, ya que la mayor parte del tiempo el inicio del servicio (contenedor) debería ser de meros segundos, por lo que el tiempo de inactividad al cambiar versiones debería ser mínimo (el mayor problema es tener que ejecutar actualizaciones de esquema, pero esto se aplica independientemente de si reconstruyes la imagen o no).
Sí, pero así no es como funciona actualmente, así que esa es la parte que necesita trabajo. ¿Cómo vas a hacer esto desde la interfaz de administración de Discourse? ¿Cómo vas a reducir el contenedor azul mientras inicias el contenedor verde (los sistemas no tienen recursos infinitos, así que antes de iniciar el azul, quieres reducir los workers de unicornio en el verde)? O puedes simplemente optar por que el verde esté caído, y ahora que el azul suba.
Hay muchas cosas que necesitan ser resueltas y trabajadas. Tanto desde una perspectiva técnica como desde la perspectiva de un administrador. La actualización de un solo clic desde la interfaz de administración es una característica valiosa.
Los plugins y las imágenes personalizadas aún deben compilarse, pero para la compilación básica, compose está al alcance de la mano en estos días. He creado un pequeño experimento de prueba de concepto aquí para cualquier persona curiosa.
Obviamente, dado que todos estos son mis repositorios (no de Discourse™), esto no es nada oficial, por lo que su experiencia puede variar, y definitivamente no espere soporte oficial
Lo lanzo aquí, ya que se ha mencionado que la gente ya está ejecutando bitnami y otras formas no sancionadas de ejecución.
Las imágenes de postgres (o pgvector) listas para usar no funcionan para Discourse: Discourse necesita cambiar la configuración predeterminada, no se conecta a través de un superusuario, admite locales y necesita admitir actualizaciones de postgres sin que un administrador de Discourse necesite volcar/restaurar.
Eh… esta es, creo, la diferencia crucial y esta “actualización desde la interfaz de administración” es un recordatorio de los viejos tiempos, cuando solo tenías “alojamiento web” con intérprete php, por lo que todo se construía en torno a esa noción. Y creo que esto se ha trasladado a cómo funciona Discourse y se espera que se gestione.
Bueno, esa es otra cosa que noté: Discourse es bastante pesado (el contenedor comenzó a consumir recursos durante el inicio a un nivel aterrador), así que sí, puede ser un problema.
¿Cómo se “compilan” en el contexto de Ruby (que es en su mayoría un lenguaje interpretado y no compilado)?
¿No sería mejor intentar utilizar soluciones listas para usar? Incluso para la configuración de postgres se puede cambiar fácilmente simplemente proporcionando/montando un archivo postgresql.conf personalizado, no hay necesidad de una imagen completamente personalizada con la configuración integrada… e incluso así, si eso es necesario, Discourse podría proporcionar una imagen precompilada que solo se descargaría en lugar de recompilarse cada vez…
Esta “interfaz de actualización de administrador” es un plugin (llamado “docker manager”). No necesitas incluirlo si tienes otra forma de hacer actualizaciones en línea.
