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 „Gefällt mir“

Hallo,

Kein Admin-Konto erstellt

Wenn ich den Docker-Container von außen über die Skripte in d/ verwende (z. B. d/boot_dev --init, wie in Install Discourse for development using Docker beschrieben), werde ich aufgefordert, im Rahmen des Prozesses ein Admin-Konto einzurichten.

Wenn ich ihn jedoch als Dev Container verwende und die Build-Schritte ausführe (Strg/Cmd + Umschalt + B), wird KEIN Admin erstellt.

Beim Überfliegen der Anweisungen hatte ich zunächst den Eindruck, dass die Erstellung eines Admins ziemlich mühsam ist; aber dann erkannte ich, dass alles, was es braucht, dieser Befehl ist, und hinterlasse ihn hier für diejenigen, die auf das gleiche Problem stoßen:

rake admin:create

(oder, wenn er sich über eine andere erforderliche Rake-Version beschwert: bundle exec rake admin:create)

7 „Gefällt mir“

Unter Windows 11, wenn Sie Probleme mit Zeilenenden vermeiden möchten, wie zum Beispiel:

[23963 ms] Start: Run in container: /bin/sh -c ./.devcontainer/scripts/start.rb
/usr/bin/env: ‘ruby\r’: No such file or directory
/usr/bin/env: use -[v]S to pass options in shebang lines

Stellen Sie sicher, dass Sie In Volume klonen

6 „Gefällt mir“

Es gibt vielleicht einen besseren Weg, aber um an Plugins zu arbeiten, habe ich einen Geschwisterordner namens discourse-plugins neben meinem Haupt-Discourse-Repository-Ordner. Dieser wird nach /workspace/plugins gemountet, sodass ich dann Symlinks innerhalb des Containers erstellen kann.

Das habe ich zu mounts in devcontainer.json hinzugefügt:
"source=${localWorkspaceFolder}/../${localWorkspaceFolderBasename}-plugins,target=/workspace/plugins,type=bind"

2 „Gefällt mir“

Das ist wirklich hilfreich, danke.

1 „Gefällt mir“

… Oder einfach git reset --hard
Hat bei mir funktioniert
Dann Dev Container: Rebuild Container und Ctrl-Shift-B

Wenn Sie OrbStack (nicht verbunden) in Ihrer lokalen macOS-Umgebung verwenden und Discourse über HTTPS mit einer benutzerdefinierten Domain ausführen möchten, aktualisieren Sie Ihre devcontainer.json mit den folgenden Ergänzungen:

  1. Geben Sie dem Container einen Namen.
  2. Fügen Sie die Wildcard-Domain .orb.local zur Umgebungsvariablen RAILS_DEVELOPMENT_HOSTS hinzu (Hostnamen müssen durch ein Komma getrennt sein).
--- 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", // Schritt 2
     "PGUSER": "discourse",
     "SELENIUM_FORWARD_DEVTOOLS_TO_PORT": "9229",
   },
+  "runArgs": ["--name","discourse"], // Schritt 1
   "mounts": [
     "source=${localWorkspaceFolderBasename}-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume",
     "source=${localWorkspaceFolderBasename}-pg,target=/shared/postgres_data,type=volume",

p.s. Bitte lassen Sie mich wissen, wenn Sie wissen, wie ich den Hostnamen *.orb.local und den Containernamen dynamisch festlegen kann, wie es für GitHub Codespaces definiert ist. Das Festlegen des Werts als .app.github.dev,.orb.local hat bei mir nicht funktioniert.

Update: Irgendwie fehlte ein Eintrag in meiner /etc/hosts-Datei. Nachdem ich diese Zeile hinzugefügt hatte, konnte ich die Wildcard-Domain .orb.local in Schritt 2 verwenden.

Mit diesen Änderungen in der devcontainer.json-Datei kann ich jetzt meine lokale Discourse-Instanz unter https://discourse.orb.local/ ausführen.

/etc/hosts

Fügen Sie diese Zeile zu Ihrer /etc/hosts-Datei hinzu, falls sie noch nicht vorhanden ist.

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

Bonus-Tipp 1
Wenn Ihre Netzwerkeinstellungen, Ihr Firmen-VPN oder ähnliches mit den IP-Bereichen von OrbStack-Containern in Konflikt geraten, aktualisieren Sie OrbStack mit einem anderen Bereich.

Bonus-Tipp 2
Wenn Sie Schritt 1 weglassen, erstellt OrbStack einen Container mit zufälligem Namen, aber Sie können HTTPS trotzdem ohne Angabe einer Portnummer verwenden. Der Nachteil ist der Containername, und damit wird der Domainname jedes Mal aktualisiert, wenn Sie den Container neu erstellen.

1 „Gefällt mir“

Es scheint, dass Orbstack Docker-Images ausführen kann. Wenn Sie versuchen, in Produktion zu gehen, möchten Sie vielleicht Folgendes verwenden:

Wenn es für die Entwicklung ist, denke ich, dass Discourse das Image discourse/discourse_dev - Docker Image verwendet. Aber Sie müssen wahrscheinlich Ihr eigenes Setup durchführen.

Zu Ihrer Information, ich glaube, der Docker

Befehlscode befindet sich in discourse/bin/docker/boot_dev at main · discourse/discourse · GitHub.

1 „Gefällt mir“

Für diejenigen, die nicht an VS Code gebunden sind, ist dies der Prozess, um DevContainers ausschließlich mit der devcontainers-CLI zu nutzen.

Unter der Annahme, dass devcontainers bereits installiert ist:

Container erstellen

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

Sobald Sie sich im Container befinden, müssen Sie die Abhängigkeiten erstellen:

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 &
  • Ändern Sie /dev/null in eine andere Datei, wenn Sie Protokolle sehen möchten.
  • Wenn Sie den Prozess weiterlaufen lassen möchten, während Sie keine Verbindung zur Shell haben, führen Sie disown aus.

Auf Discourse zugreifen

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

Dies zeigt die dem Container zugewiesene IP-Adresse an.
Öffnen Sie in Ihrem Browser http://<ipaddress>:4200.

Bereinigen

Um Ihren DevContainer zu löschen (die Optionen down/delete sind noch nicht implementiert):

Rufen Sie den Namen des Containers ab:
docker ps

Stoppen und löschen Sie den Container:
docker stop <name> && docker rm <name>

Löschen Sie die Volumes:
docker volume rm discourse-node_modules discourse-pg discourse-redis

4 „Gefällt mir“

Die Anweisungen für Nicht-VS-Code haben bei mir unter macOS gerade nicht funktioniert. Ich empfehle macOS-Benutzern, die außerhalb von VS Code mit dem Discourse-Docker-Image interagieren möchten, stattdessen das herkömmliche Docker-Skript boot_dev zu verwenden.

Mit docker ps habe ich den Namen meines Containers gefunden (ein zufällig generierter alberner Name, wie peaceful_lumiere). Ich habe docker inspect peaceful_lumiere | jq '.[0].NetworkSettings.Networks.bridge.IPAddress' ausgeführt, und es wurde eine IP-Adresse ausgegeben. In meinem Browser habe ich http://<ip>:4200 aufgerufen, und es drehte sich ewig.

Ich glaube, das liegt daran, dass der ember-cli-Entwicklungsserver nicht auf allen Schnittstellen lauscht; er hört nur auf http://127.0.0.1:4200 innerhalb des Containers.

Letztendlich habe ich es zum Laufen gebracht, indem ich einen runArgs-Abschnitt zu .devcontainer/devcontainer.json hinzugefügt habe, so wie hier:

     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",

… aber wenn du das tust, wird es nicht in VS Code funktionieren (weil sowohl VS Code als auch der Dev-Container versuchen, Ports weiterzuleiten). Ich habe eine separate devcontainer-cli.json erstellt und devcontainer --override-config .devcontainer/devcontainer-cli.json verwendet, und das hat funktioniert.

Dann wurde mir klar: Ich habe all diese Umwege genommen, bin aber nicht besser dran als mit dem bestehenden herkömmlichen boot_dev-Skript. Die dort dokumentierten Schritte zu befolgen ist schneller und einfacher, als zu versuchen, devcontainer über die CLI dazu zu bringen, das Richtige zu tun.

Dev-Container sind primär für die Verwendung in VS Code oder etwas gedacht, das die Portweiterleitung automatisch für dich verwaltet; die devcontainer-CLI macht das nicht. Wenn du also VS Code nicht verwenden möchtest, lass vielleicht besser die Finger von Dev-Containern.

Ich sollte erwähnen, dass meine Anweisungen für Linux galten (in meinem Fall speziell NixOS), aber es gibt keinen Grund, warum sie nicht auf anderen Linux-basierten Systemen funktionieren sollten.

@dfabulich Ich habe deinen Beitrag gelesen und glaube, das Problem zu verstehen. Port-Weiterleitung sollte nicht erforderlich sein. Du benötigst die IP-Adresse des Containers. 127.0.0.1 ist localhost (dein lokales System, nicht der Container).

Der jq-Befehl sollte eine lokale LAN-Subnetz-IP ausgegeben haben, auf die du ohne Port-Weiterleitung zugreifen kannst.

Nein, das habe ich gemacht. jq hat "172.17.0.2" ausgegeben und http://172.17.0.2:4200 blieb einfach endlos im Ladezustand.

Im Container hört ember-cli nicht auf 0.0.0.0:4200; es hört auf 127.0.0.1:4200. Wenn Sie also auf 172.17.0.2:4200 zugreifen (oder auf Ihre tatsächliche IP-Adresse), erreicht die Anfrage Ember nicht – zumindest unter macOS.

Beachten Sie, dass Docker Desktop unter macOS nur eine virtuelle Maschine ausführt. Es gibt unter macOS keine „leichtgewichtigen Docker-Container auf Prozessebene".

Ich weiß nicht genug über macOS, um zu sagen, ob Docker Kernel-Namensräume wie unter Linux verwendet. Ich habe es gerade noch einmal getestet (Hinweis: Der Dienst braucht etwas Zeit zum Starten):


Das tut es nicht. Docker Desktop für macOS läuft buchstäblich über QEMU. (Oder zumindest war das bis vor kurzem so; jetzt nutzen sie etwas Neues, das im Grunde wie QEMU ist, nur mit einem lustigen Hut und Schnurrbart. Auf jeden Fall läuft immer noch eine vollständige VM als Implementierung.)

Also, ich bin mir sicher, dass es auf deinem Rechner funktioniert, aber auf meinem macOS-Rechner nicht, und ich denke, das ist der wahrscheinlichste Grund dafür.

1 „Gefällt mir“