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 Ctrl + Shift + B (Cmd + Shift + B on mac).

    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. Visit http://localhost:4200 in your browser to see your new Discourse instance

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

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 Mi Piace

Ciao,

Nessun account amministratore creato

Quando si utilizza il container Docker dall’esterno tramite gli script in d/ (ad esempio, d/boot_dev --init come specificato in Install Discourse for development using Docker , mi viene chiesto di creare un account amministratore come parte del processo.

Tuttavia, quando lo si utilizza come Dev Container ed eseguendo i passaggi di compilazione (ctrl/cmd + shift + b), NON crea un amministratore.

Dando una rapida occhiata alle istruzioni, ho avuto inizialmente l’impressione che la creazione di un amministratore fosse piuttosto ardua; ma poi mi sono reso conto che tutto ciò che serve è questo comando, lo lascio qui per coloro che incontrano lo stesso problema:

rake admin:create

(o, se si lamenta di una versione di rake diversa richiesta: bundle exec rake admin:create)

7 Mi Piace

Su Windows 11, se non si desidera incorrere in problemi di terminazione di riga, come ad esempio:

[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

.. assicurati di Clonare nel volume

6 Mi Piace

Forse c’è un modo migliore, ma per lavorare sui plugin ho una cartella sorella discourse-plugins accanto alla mia cartella principale del repository discourse. Questa viene montata in /workspace/plugins in modo da poter creare collegamenti simbolici all’interno del container.

Questo è ciò che ho aggiunto a mounts in devcontainer.json:
"source=${localWorkspaceFolder}/../${localWorkspaceFolderBasename}-plugins,target=/workspace/plugins,type=bind"

2 Mi Piace

È davvero utile, grazie.

1 Mi Piace

… O semplicemente git reset --hard
Ha funzionato per me
Poi Dev Container: Rebuild Container e Ctrl-Shift-B

Se stai usando OrbStack (non affiliato) sul tuo ambiente macOS locale e vuoi eseguire Discourse su HTTPS con un dominio personalizzato, aggiorna il tuo devcontainer.json con le seguenti aggiunte:

  1. Assegna un nome al container.
  2. Aggiungi il dominio wildcard .orb.local alla variabile d’ambiente RAILS_DEVELOPMENT_HOSTS (gli hostname devono essere separati da una virgola).
--- 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", // Step 2
     "PGUSER": "discourse",
     "SELENIUM_FORWARD_DEVTOOLS_TO_PORT": "9229",
   },
+  "runArgs": ["--name","discourse"], // Step 1
   "mounts": [
     "source=${localWorkspaceFolderBasename}-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume",
     "source=${localWorkspaceFolderBasename}-pg,target=/shared/postgres_data,type=volume",

p.s. per favore fammi sapere se sai come impostare l’hostname *.orb.local e il nome del container dinamicamente, come è definito per GitHub Codespaces. Impostare il valore come .app.github.dev,.orb.local non ha funzionato per me.

Aggiornamento: In qualche modo, mi mancava una voce nel mio file /etc/hosts. Dopo aver aggiunto questa riga, sono stato in grado di utilizzare il dominio wildcard .orb.local nel passaggio 2.

Con queste modifiche nel file devcontainer.json, ora posso eseguire la mia istanza locale di Discourse su \u003chttps://discourse.orb.local/\u003e

/etc/hosts

Aggiungi questa riga al tuo file /etc/hosts se non l’hai già fatto.

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

Suggerimento bonus 1
Se in qualche modo le tue impostazioni di rete, o la rete VPN della tua azienda, ecc. entrano in conflitto con gli intervalli IP dei container di OrbStack, aggiorna OrbStack con un intervallo diverso.

Suggerimento bonus 2
Se ometti il passaggio 1, OrbStack creerà un container con un nome casuale, ma sarai comunque in grado di utilizzare HTTPS senza aggiungere alcun numero di porta. Lo svantaggio è il nome del container, quindi il nome del dominio verrà aggiornato ogni volta che ricostruisci il container.

1 Mi Piace

Sembra che Orbstack sia destinato all’esecuzione di immagini Docker. Se stai cercando di eseguire in produzione, potresti voler usare:

Se è per lo sviluppo, penso che Discourse utilizzi l’immagine discourse/discourse_dev - Docker Image. Ma probabilmente dovrai fare la tua configurazione.

Per tua informazione, credo che il comando Docker

il cui codice si trova in discourse/bin/docker/boot_dev at main · discourse/discourse · GitHub.

1 Mi Piace

Per chi non è legato a VSCode, ecco il processo per utilizzare i devcontainer solo con il CLI dei devcontainer.
Supponendo che i devcontainer siano già installati:

Build del container

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

Una volta all’interno del container, è necessario costruire le dipendenze:

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 con un file diverso se desideri visualizzare i log
  • Se vuoi mantenere il processo in esecuzione anche dopo la disconnessione dalla shell, esegui disown

Accesso a Discourse

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

Questo mostrerà l’indirizzo IP assegnato al container.
Nel tuo browser, apri http://<indirizzo_ip>:4200

Pulizia

Per eliminare il tuo devcontainer (le opzioni down/delete non sono ancora implementate)
Recupera il nome del container:
docker ps
Arresta ed elimina il container:
docker stop <nome> && docker rm <nome>
Elimina i volumi:
docker volume rm discourse-node_modules discourse-pg discourse-redis

4 Mi Piace

Quelle istruzioni non relative a VS Code non hanno funzionato per me in questo momento su macOS. Consiglio agli utenti macOS che desiderano interagire con l’immagine Docker di Discourse al di fuori di VS Code di utilizzare invece lo script Docker legacy boot_dev.

Con docker ps ho trovato il nome del mio container (un nome casuale e bizzarro, come peaceful_lumiere). Ho eseguito docker inspect peaceful_lumiere | jq '.[0].NetworkSettings.Networks.bridge.IPAddress' e mi ha restituito un indirizzo IP. Sono andato su http://<ip>:4200 nel mio browser, ma è rimasto bloccato a girare all’infinito.

Penso che ciò sia dovuto al fatto che il server di sviluppo ember-cli non ascolta su tutte le interfacce; ascolta solo su http://127.0.0.1:4200 all’interno del container.

Alla fine sono riuscito a farlo funzionare aggiungendo una sezione runArgs a .devcontainer/devcontainer.json, come in questo esempio.

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

… ma se lo fai, non funzionerà in VS Code (perché sia VS Code che il devcontainer proveranno a inoltrare le porte). Ho creato un file devcontainer-cli.json separato e ho usato devcontainer --override-config .devcontainer/devcontainer-cli.json, e così ha funzionato.

Ma poi mi è venuto in mente: ho fatto tutti questi sforzi, ma non sono in una situazione migliore rispetto all’utilizzo dello script legacy esistente boot_dev. Seguire i passaggi documentati è più rapido e semplice che cercare di convincere devcontainer a fare la cosa giusta da CLI.

I Dev Container sono principalmente pensati per l’uso in VS Code, o in qualcosa che gestisca automaticamente l’inoltro delle porte per te; la CLI devcontainer non lo fa. Quindi, se non vuoi usare VS Code, forse è meglio non preoccuparsi dei Dev Container.

Dovrei precisare che le mie istruzioni erano per Linux (nel mio caso, NixOS), ma non c’è motivo per cui non dovrebbero funzionare anche su altri sistemi basati su Linux.

@dfabulich Ho letto il tuo post e credo di aver capito il problema. L’inoltro delle porte non dovrebbe essere necessario. Hai bisogno dell’IP del contenitore. 127.0.0.1 è localhost (il tuo sistema locale, non il contenitore).

Il comando jq avrebbe dovuto restituire un IP della subnet LAN locale a cui è possibile accedere senza inoltro delle porte.

No, l’ho fatto io. jq ha stampato "172.17.0.2" e http://172.17.0.2:4200 è rimasto lì a girare all’infinito.

All’interno del container, ember-cli non ascolta su 0.0.0.0:4200; ascolta su 127.0.0.1:4200. Quindi, se lo accedi tramite 172.17.0.2:4200 (o l’indirizzo IP effettivo), la richiesta non raggiunge mai Ember, almeno su macOS.

Tieni presente che su macOS Docker Desktop esegue semplicemente una macchina virtuale. Non esiste una cosa come un “container Docker leggero a livello di processo” su macOS.

Non conosco abbastanza macOS per sapere se Docker utilizzi i namespace del kernel come su Linux. Ho appena effettuato un nuovo test (Nota: il servizio richiede un po’ di tempo per avviarsi):


Non lo fa. Docker Desktop per macOS esegue letteralmente QEMU. (O, fino a poco tempo fa; ora usano una nuova soluzione che è essenzialmente come QEMU con un cappello buffo e un baffo; in ogni caso, esegue comunque una VM completa come sua implementazione.)

Quindi, sono sicuro che funzioni sulla tua macchina, ma non funziona sulla mia macchina macOS, e penso che questa sia la ragione più probabile.

1 Mi Piace