Developing Discourse using a Dev Container

Dev Containers is an open standard for configuring a development environment inside a container. This almost entirely eliminates the need to install/configure Discourse-specific tools/dependencies on your local machine, and makes it very easy to keep up-to-date as Discourse evolves over time.

Dev Containers can be used in a number of different IDEs, or directly using their reference CLI. This guide will describe the setup process for VSCode.

Getting started

  1. Download and install VSCode

  2. Install the Dev Containers extension in VSCode

  3. Clone the Discourse repository onto your machine

    git clone https://github.com/discourse/discourse
    
  4. In VSCode, use FileOpen Folder, then choose the Discourse directory

  5. Open the folder in its Dev Container. This can be done via the popup prompt, or by opening the command palette (Cmd/Ctrl + Shift + P) and searching for “Open folder in container…”

  6. If this is your first time launching a container, you will be prompted to install and start Docker Desktop. Once complete, go back to VSCode re-run “Open folder in container…”

  7. Wait for the container to download and start. When it’s done, the README will appear, and you’ll see the Discourse filesystem in the sidebar.

  8. Run the default build task using Cmd/Ctrl + Shift + B.

    This will install dependencies, migrate the database, and start the server. It’ll take a few minutes, especially on the lower-end machines. You’ll see “Build successful” in the terminal when it’s done.

  9. Run the dev/admin/create task. Open the command palette and search for “Tasks: Run Tasks”. It will present a menu of tasks; select dev/admin/create off of that list. You’ll be prompted to enter an email address and a password for your admin user.

  10. Visit http://localhost:3000 in your browser to see your new Discourse instance

  11. All done! You can now make changes to Discourse’s source code and see them reflected in the preview.

Running tests

The first time you run tests, you’ll need to install testing dependencies, including Playwright and the discourse_test DB. You can run the deps/testing task to install those. Open the command palette, select “Tasks: Run Tasks”. It will present a menu of tasks; select deps/testing off of that list.

Once the test dependencies are installed, you can run bin/lint, bin/qunit, or the system specs

Applying config/container updates

Every so often, the devcontainer config and the associated container image will be updated. VSCode should prompt you to “rebuild” to apply the changes. Alternatively, you can run “Dev Containers: Rebuild Container” from the VSCode command palette. The working directory, and your Redis/Postgres data will be preserved across rebuilds.

If you’d like to start from scratch with fresh database, you’ll need to delete the discourse-pg and discourse-redis docker volumes. This can be done from the “Remote Explorer” tab of the VSCode sidebar.

Discourse’s sample vscode .vscode/settings.json and .vscode/tasks.json will be copied when you first boot the codespace. From that point forward, if you want to use the latest sample config, you’ll need to manually copy .vscode/settings.json.sample to .vscode/settings.json.

References


This document is version controlled - suggest changes on github.

13 Me gusta

Hola,

No se creó ninguna cuenta de administrador

Cuando se utiliza el contenedor de Docker desde el exterior a través de los scripts en d/ (por ejemplo, d/boot_dev --init, como se especifica en Install Discourse for development using Docker), me pide que configure una cuenta de administrador como parte del proceso.

Sin embargo, cuando se utiliza como Contenedor de Desarrollo y se ejecutan los pasos de compilación (Ctrl/Cmd + Shift + B), NO crea un administrador.

Al echar un vistazo a las instrucciones, primero tuve la impresión de que crear un administrador es bastante arduo; pero luego me di cuenta de que todo lo que se necesita es este comando, lo dejo aquí para aquellos que se encuentren con el mismo problema:

rake admin:create

(o, si se queja de que se requiere una versión diferente de rake: bundle exec rake admin:create)

7 Me gusta

En Windows 11, si no quieres encontrar problemas con los finales de línea, como:

[23963 ms] Inicio: Ejecutar en contenedor: /bin/sh -c ./.devcontainer/scripts/start.rb
/usr/bin/env: ‘ruby\r’: No existe el archivo o directorio
/usr/bin/env: usa -[v]S para pasar opciones en las líneas shebang

.. asegúrate de Clonar en Volumen

6 Me gusta

Quizás haya una mejor manera, pero para trabajar en plugins tengo una carpeta hermana discourse-plugins junto a mi carpeta principal del repositorio de discourse. Esto se monta en /workspace/plugins para que luego pueda crear enlaces simbólicos dentro del contenedor.

Esto es lo que agregué a mounts en devcontainer.json:
"source=${localWorkspaceFolder}/../${localWorkspaceFolderBasename}-plugins,target=/workspace/plugins,type=bind"

2 Me gusta

Esto es realmente útil, gracias.

1 me gusta

… O simplemente git reset --hard
Me funcionó
Luego Dev Container: Rebuild Container y Ctrl-Shift-B

Si estás usando OrbStack (no afiliado) en tu entorno macOS local y quieres ejecutar Discourse en HTTPS con un dominio personalizado, actualiza tu devcontainer.json con las siguientes adiciones:

  1. Dale un nombre al contenedor.
  2. Añade el dominio comodín .orb.local a la variable de entorno RAILS_DEVELOPMENT_HOSTS (los nombres de host deben estar separados por una coma).
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -13,10 +13,11 @@
   ],
   "remoteUser": "discourse",
   "remoteEnv": {
-    "RAILS_DEVELOPMENT_HOSTS": ".app.github.dev",
+    "RAILS_DEVELOPMENT_HOSTS": ".app.github.dev,.orb.local", // Paso 2
     "PGUSER": "discourse",
     "SELENIUM_FORWARD_DEVTOOLS_TO_PORT": "9229",
   },
+  "runArgs": ["--name","discourse"], // Paso 1
   "mounts": [
     "source=${localWorkspaceFolderBasename}-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume",
     "source=${localWorkspaceFolderBasename}-pg,target=/shared/postgres_data,type=volume",

p.d. por favor, házmelo saber si sabes cómo configurar el nombre de host *.orb.local y el nombre del contenedor dinámicamente, como se define para GitHub Codespaces. Establecer el valor como .app.github.dev,.orb.local no me funcionó.

Actualización: De alguna manera, me faltaba un registro en mi archivo /etc/hosts. Después de añadir esta línea, pude usar el dominio comodín .orb.local en el paso 2.

Con estos cambios en el archivo devcontainer.json, ahora puedo ejecutar mi instancia local de Discourse en https://discourse.orb.local/

/etc/hosts

Añade esta línea a tu archivo /etc/hosts si aún no la tienes.

##
# Docker y OrbStack
##
127.0.0.1 host.docker.internal

Consejo extra 1
Si por alguna razón la configuración de tu red, o la red VPN de tu empresa, etc., entra en conflicto con los rangos de IP de los contenedores de OrbStack, actualiza tu OrbStack con un rango diferente.

Consejo extra 2
Si omites el paso 1, OrbStack creará un contenedor con un nombre aleatorio, pero aún así podrás usar HTTPS sin añadir ningún número de puerto. La desventaja es el nombre del contenedor, por lo que el nombre de dominio se actualizará cada vez que reconstruyas el contenedor.

1 me gusta

Parece que Orbstack está diseñado para ejecutar imágenes de Docker. Si estás intentando ejecutar en producción, quizás te interese usar:

Si es para desarrollo, creo que Discourse utiliza la imagen discourse/discourse_dev - Docker Image. Pero probablemente tendrás que hacer tu propia configuración.

Para tu información, creo que el código del comando de Docker

está en discourse/bin/docker/boot_dev at main · discourse/discourse · GitHub.

1 me gusta

Para quienes no están casados con VSCode, este es el proceso para usar devcontainers solo con la CLI de devcontainers.
Suponiendo que ya tienes devcontainers instalado:

Construir contenedor

git clone https://github.com/discourse/discourse && cd discourse
devcontainer build
devcontainer up --workspace-folder .
devcontainer exec bash

Una vez dentro del contenedor, necesitas construir las dependencias:

pnpm install
bundle install
SKIP_MULTISITE=1 SKIP_TEST_DATABASE=1 bin/rake db:create db:migrate
DISCOURSE_DEV_ALLOW_ANON_TO_IMPERSONATE=1 bin/ember-cli -u > /dev/null 2>&1 &
  • Cambia /dev/null por un archivo diferente si quieres ver los registros.
  • Si quieres dejarlo ejecutándose mientras te desconectas de la shell, ejecuta disown.

Acceder a Discourse

docker inspect <nombre> | jq '.[0].NetworkSettings.Networks.bridge.IPAddress'

Esto mostrará la dirección IP asignada al contenedor.
En tu navegador, abre http://<direccion_ip>:4200.

Limpieza

Para eliminar tu devcontainer (las opciones down/delete aún no están desarrolladas):
Obtén el nombre del contenedor:
docker ps
Detén y elimina el contenedor:
docker stop <nombre> && docker rm <nombre>
Elimina los volúmenes:
docker volume rm discourse-node_modules discourse-pg discourse-redis

4 Me gusta

Esas instrucciones que no son para VS Code no me funcionaron hace un momento en macOS. Recomiendo que los usuarios de macOS que deseen interactuar con la imagen Docker de Discourse fuera de VS Code utilicen el script Docker heredado boot_dev en su lugar.

Con docker ps encontré el nombre de mi contenedor (un nombre aleatorio y gracioso, como peaceful_lumiere). Ejecuté docker inspect peaceful_lumiere | jq '.[0].NetworkSettings.Networks.bridge.IPAddress' y me devolvió una dirección IP. Fui a http://<ip>:4200 en mi navegador y simplemente se quedó girando para siempre.

Creo que eso se debe a que el servidor de desarrollo de ember-cli no está escuchando en todas las interfaces; solo está escuchando en http://127.0.0.1:4200 dentro del contenedor.

Finalmente logré que funcionara agregando una sección runArgs a .devcontainer/devcontainer.json, así:

     8025, // mailhog
     9229  // chrome remote debug
   ],
+  "runArgs": [
+    "-p",
+    "127.0.0.1:4200:4200",
+    "-p",
+    "127.0.0.1:3000:3000",
+    "-p",
+    "127.0.0.1:9292:9292",
+    "-p",
+    "127.0.0.1:8025:8025",
+    "-p",
+    "127.0.0.1:9229:9229"
+  ],
   "remoteUser": "discourse",
   "remoteEnv": {
     "RAILS_DEVELOPMENT_HOSTS": ".app.github.dev",

… pero si haces eso, no funcionará en VS Code (porque tanto VS Code como el devcontainer intentarán reenviar puertos). Creé un archivo devcontainer-cli.json separado y usé devcontainer --override-config .devcontainer/devcontainer-cli.json, y eso funcionó.

Pero luego me di cuenta: he pasado por todos estos obstáculos, pero no estoy mejor que usando el script heredado existente boot_dev. Seguir esos pasos documentados es más rápido y fácil que intentar obligar a devcontainer a hacer lo correcto desde la CLI.

Los Dev Containers están diseñados principalmente para usarse en VS Code, o en algo que gestione automáticamente el reenvío de puertos por ti; la CLI de devcontainer no hace eso. Así que, si no quieres VS Code, quizás sea mejor no molestarse con los Dev Containers.

Debo mencionar que mis instrucciones eran para Linux. (En mi caso, específicamente NixOS), pero no hay razón por la que no debería funcionar en otros sistemas basados en Linux.

@dfabulich Leí tu publicación y creo que entiendo el problema. El reenvío de puertos no debería ser necesario. Necesitas la IP del contenedor. 127.0.0.1 es localhost (tu sistema local, no el contenedor).

El comando jq debería haber mostrado una IP de la subred LAN local a la que puedes acceder sin reenvío de puertos.

No, yo hice eso. jq imprimió "172.17.0.2" y http://172.17.0.2:4200 simplemente se quedó girando para siempre.

Dentro del contenedor, ember-cli no está escuchando en 0.0.0.0:4200; está escuchando en 127.0.0.1:4200. Así que si accedes a él en 172.17.0.2:4200 (o la IP real que tengas), la solicitud nunca llega a ember, al menos en macOS.

Ten en cuenta que en macOS, Docker Desktop simplemente ejecuta una máquina virtual. No existe algo así como un «contenedor Docker ligero a nivel de proceso» en macOS.

No sé lo suficiente sobre macOS para saber si Docker utiliza espacios de nombres del núcleo como lo hace en Linux. Acabo de probarlo de nuevo (Nota: tarda un poco en iniciarse el servicio):


No lo hace. Docker Desktop para macOS literalmente ejecuta QEMU. (O, así era hasta hace poco; ahora utilizan algo nuevo que es básicamente como QEMU con un sombrero y bigote graciosos; de cualquier manera, sigue ejecutando una máquina virtual completa como su implementación.)

Así que, estoy seguro de que funciona en tu máquina, pero no funciona en mi máquina con macOS, y creo que esa es la razón más probable.

1 me gusta